2010-10-10 2 views
5

В C++ можно написать:Generic наследования в Java

#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 с использованием дженериков?

Спасибо.

Edit: Добавление больше информации о моих намерениях

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

+1

+1, я не знал, что C++ шаблоны могли это сделать! (Это можно использовать для достижения таких эффектов, как динамическая смесь в Scala :) – missingfaktor

+0

@missingfaktor: google для шаблона CRTP –

+0

@Armen: Это не пример шаблона CRTP. CRTP имеет общую структуру 'class A: B ', что не соответствует коду OP. – missingfaktor

ответ

5

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

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

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

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

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

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

+0

вычислительно и концептуально :) –

+0

Не 100% чистый imo, но я думаю, это сработает. Благодаря! – monoceres

0

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

+0

Я добавил дополнительную информацию :) – monoceres

+0

@monoceres Ну, образцы дизайна не моя сильная сторона, но кажется, что есть некоторые предложения уже (и, возможно, скоро к нам приедут более опытные люди, чем я). –

1

Увы, нет.

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

Поэтому спецификации языка Java Явно forbids указать тип в качестве суперкласса В параметре или реализованный интерфейс:

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

Супер: расширяет ClassType

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

Обходные

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