Можно ли смешивать композицию и наследование в Java? Во-первых, у меня есть несколько родовых классов - это отношения HAS-A (или HAS-MANY) (композиция).
Общие классы:
Структура, Тип A, Тип B, Тип C и т. Д., Где Структура находится в отношении HAS-A с Типом A, Типом B и Типом C.
Но тогда у меня также есть несколько наборов подклассов, которые наследуются от общих классов (Наследование) и находятся в одинаковых отношениях.
Наборы подклассов:
Набор 1:
Structure1, TypeA1, TypeB1, TypeC1 и т. Д., Где Structure1 находится в том же отношении HAS-A, что и TypeA1, TypeB1 и TypeC1, точно так же, как общие классы.
И: Structure1 расширяет Structure, TypeA1 расширяет TypeA, ..., TypeC1 расширяет TypeC и т. Д.
... до Задания X:
StructureX, TypeAX, TypeBX, TypeCX и т. Д.
Каждая специальная структура имеет ОДНО конкретный подтип A, Sub-TypeB и Sub-TypeC и т. Д. Общие классы определяют некоторый код (атрибуты и методы), который я хотел бы не использовать при работе со специальными структурами. Проблемы, с которыми я сталкиваюсь, лучше всего объясняются приведенным ниже кодом . (Я не знаю, можно ли это как-то решить с помощью «дженериков» Java, но я думаю, что нет.)
/***********************************************************************************************
/ 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;
}