Is it possible to mix composition and inheritance in Java? Fist I have some generic classes is a HAS-A (or HAS-MANY) relationship (Composition).
Structure, TypeA, TypeB, TypeC, etc., where Structure is in a HAS-A relationship with TypeA, TypeB and TypeC.
But then I also have several sets of subclasses which inherit from the generic classes (Inheritance) and are in the same relationship.
Structure1, TypeA1, TypeB1, TypeC1, etc., where Structure1 is in the same HAS-A relationship with TypeA1, TypeB1 and TypeC1, just like the generic classes.
And: Structure1 extends Structure, TypeA1 extends TypeA, ..., TypeC1 extends TypeC, etc.
StructureX, TypeAX, TypeBX, TypeCX, etc.
Each special structure has exactly ONE specific sub-TypeA, sub-TypeB and sub-TypeC, etc. The generic classes define some code (attributes and methods) which I would like ot reuse when dealing with special structures. The problems I am facing are best explained by the code below. (I do not know if this can somehow be solved by Java "generics" but I think not.)
/***********************************************************************************************
/ Generic Structure of Structure-Class with Instances of Generic other classes (Composition)
/***********************************************************************************************/
class Structure {
// Substructures
TypeA instanceA;
TypeB instanceB;
// Defining many methods using the instances of other generic classes like TypeA
void setGenericAttributeOfA(int value) {
instanceA.genericAttribute = value;
}
void setGenericAttributeOfB(int value) {
instanceB.genericAttribute = value;
}
}
class TypeA {
int genericAttribute;
}
class TypeB {
int genericAttribute;
}
/***********************************************************************************************
/ Specific implementation of a Structure-Class with specific implementation of the other classes (Inheritance)
/***********************************************************************************************/
// In the specific implementations I want to use the generic methods, because I do not want to
// rewrite the code for each and every specific implementation. But they should
class Structure1 extends Structure {
// This will create an additional attribute instanceA of specific TypeA1, so I will end up with two instances:
// (1) TypeA super.instanceA and (2) TypeA1 this.instanceA. But what I would like is to have only
// one instanceA of type TypeA1 that can also be used by the global methods of the generic Structure.
TypeA1 instanceA;
Structure1() {
// This creates an instance of type TypeA1, but it cannot be used in the generic methods
// because it is hold in a separate "local" variable that is not known to the generic Structure methods
instanceA = new TypeA1();
// This creates an instance of type TypeB1, but it cannot access the "local" specific attributes,
// because it is hold in a varable which is statically types as TypeB
instanceB = new TypeB1();
}
void specificMethod() {
setGenericAttributeOfA(42); // would fail, because instanceA of type generic TypeA is null
instanceA.specificAttribute = 13; // works only for "local" specific attributes
setGenericAttributeOfB(42); // works only for generic attributes
instanceB.specificAttribute = 13; // would fail, because instanceB is statically typed as generic TypeB which does not have this attribute
((TypeB1)instanceB).specificAttribute = 13; // works but is an ugly work-around and over-complicated if to be used many times
}
}
class TypeA1 extends TypeA {
int specificAttribute;
}
class TypeB1 extends TypeB {
int specificAttribute;
}
Maybe Generics can help?
Declare Structure
as generic:
class Structure<T1 extends TypeA, T2 extends TypeB, T3 extends TypeC> {
T1 instanceA;
T2 instanceB;
T3 instanceC;
}
And your specific structures will just inherit from the generic Structure
by specifying type arguments:
class Structure1 extends Structure<TypeA1, TypeB1, TypeC1> {
// here instanceA will be of type TypeA1, instanceB will be TypeB1 etc.
}