views:

145

answers:

4

In c++ we can write:

#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();
}

To get templated inheritance.

Can the same be done in java using generics?

Thanks.

Edit: Adding more info about my intentions

In my scenario I have two subclasses, Sprite and AnimatedSprite (which is a subclass of Sprite). The next step is a PhysicalSprite that adds physics to the sprites, but I want it to be able to inherit from both Sprite and AnimatedSprite.

+4  A: 

No. C++'s templates are much stronger than Java's generics. Generics in Java are only for ensuring proper typing during compile time and are not present in the generated bytecode - this is called type erasure.

In my scenario I have two subclasses, Sprite and AnimatedSprite (which is a subclass of Sprite). The next step is a PhysicalSprite that adds physics to the sprites, but I want it to be able to inherit from both Sprite and AnimatedSprite.

Inheritance is not the only form of code reuse. This use case can be handled with other patterns as well, such as simple decoration. Consider something akin to the following:

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

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

PhysicalSprite would in this case delegate the Sprite parts to some Sprite instance provided in the constructor. It would then be free to add its own handling for the Physics part.

Ezku
computationally and conceptually :)
Armen Tsirunyan
Not 100 % clean imo, but I guess it will work. Thanks!
monoceres
A: 

No, not in exact same way. But if you tell us what exactly you want to do, I'm pretty sure there'll be some elegant way to do that. I just don't see any need for templates/generics in your example.
In particular, it looks like Base1 and Base2 might benefit from common interfaces with method test.

Nikita Rybak
I added more info :)
monoceres
@monoceres Well, design patterns isn't my strong side, but it seems there're some suggestions already (and maybe soon some more experienced people than me will arrive to help).
Nikita Rybak
A: 

Hm.. Do you need decorator?

Stas
+1  A: 

Alas, no.

Unlike C++, which can be thought to emit a different class definition for every instantiation of a template, all instantiations of a generic type share the same runtime class in Java, and therefore have the same method definitions. Generics (in Java) are compile-time and not tracked at runtime.

Therefore, the Java Language Specification explictly forbids to specify a type paramater as superclass or implemented interface:

The optional extends clause in a normal class declaration specifies the direct superclass of the current class.

Super: extends ClassType

where ClassType is a qualified or unqualified class name (with optional type arguments)

Workarounds

  1. Use the decorator pattern if you don't need to override methods invoked by the super class.
  2. Generate a dedicated subclass for each instantiation of the template. You can do so at runtime using, for instance, Javassist, or using source code transformations at compile time.
meriton