Общее наследование в Java - PullRequest
       12

Общее наследование в Java

5 голосов
/ 10 октября 2010

В c ++ мы можем написать:

#include <iostream>

class Base1
{
public: void test() { std::cout << "Base 1" << std::endl; }
};

class Base2
{
    public: void test() { std::cout << "Base 2" << std::endl; }
};

template<class T>
class Derived: public T
{

};

int main()
{
    Derived<Base1> d1;
    Derived<Base2> d2;
    d1.test();
    d2.test();
}

Чтобы получить шаблонное наследование.

Можно ли сделать то же самое в Java с использованием обобщений?

Спасибо.

Редактировать: Добавление дополнительной информации о моих намерениях

В моем сценарии у меня есть два подкласса, Sprite и AnimatedSprite (который является подклассом Sprite).Следующим шагом является PhysicalSprite, который добавляет физику к спрайтам, но я хочу, чтобы он мог наследовать как от Sprite, так и от AnimatedSprite.

Ответы [ 4 ]

5 голосов
/ 10 октября 2010

Нет. Шаблоны C ++ намного сильнее , чем дженерики Java. Обобщения в Java предназначены только для обеспечения правильной типизации во время компиляции и отсутствуют в сгенерированном байт-коде - это называется стирание типа .

В моем сценарии у меня есть два подкласса, Sprite и AnimatedSprite (который является подклассом Sprite). Следующим шагом является PhysicalSprite, который добавляет физику к спрайтам, но я хочу, чтобы он мог наследовать как от Sprite, так и от AnimatedSprite.

Наследование - не единственная форма повторного использования кода. Этот вариант использования может быть обработан и с другими узорами, такими как простой украшение . Рассмотрим что-то похожее на следующее:

interface Sprite { ... }
class StaticSprite implements Sprite { ... }
class AnimatedSprite implements Sprite { ... }

class PhysicalSprite implements Sprite, Physics {
    PhysicalSprite(Sprite inner) { ... }
    ...
}

PhysicalSprite будет в этом случае делегировать части Sprite некоторому экземпляру Sprite, предоставленному в конструкторе. Тогда можно было бы свободно добавить свою собственную обработку для части Физики.

1 голос
/ 10 октября 2010

Увы, нет.

В отличие от C ++, который, как считается, может генерировать разные определения классов для каждого экземпляра шаблона, все экземпляры универсального типа совместно используют один и тот же класс времени выполнения в Java и, следовательно, имеют одинаковые определения методов. Обобщения (в Java) выполняются во время компиляции и не отслеживаются во время выполнения.

Следовательно, спецификация языка Java явно запрещает указывать параметр типа как суперкласс или реализованный интерфейс:

Необязательное условие extends в обычном объявлении класса определяет прямой суперкласс текущего класса.

Super : расширяет ClassType

, где ClassType - полное или неквалифицированное имя класса (с необязательными аргументами типа)

Обходные

  1. Используйте шаблон декоратора, если вам не нужно переопределять методы, вызываемые суперклассом.
  2. Создание выделенного подкласса для каждого экземпляра шаблона. Вы можете сделать это во время выполнения, используя, например, Javassist, или используя преобразования исходного кода во время компиляции.
0 голосов
/ 10 октября 2010

Хм .. Вам нужен декоратор ?

0 голосов
/ 10 октября 2010

Нет, не совсем так. Но если вы скажете нам, что именно вы хотите сделать, я почти уверен, что будет какой-то элегантный способ сделать это. Я просто не вижу необходимости в шаблонах / шаблонах в вашем примере.
В частности, похоже, что Base1 и Base2 могут выиграть от общих интерфейсов с методом test.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...