是否可以在Java中混合使用组合和继承?拳头我有一些泛型类是HAS-A(或HAS-MANY)关系(作文)。
结构,TypeA,TypeB,TypeC等,其中Structure与TypeA,TypeB和TypeC处于HAS-A关系。
但是后来我也有几组继承自泛型类(继承)的子类,它们处于相同的关系中。
Structure1,TypeA1,TypeB1,TypeC1等,其中Structure1与TypeA1,TypeB1和TypeC1处于相同的HAS-A关系,就像通用类一样。
并且:Structure1扩展了Structure,TypeA1扩展了TypeA,...,TypeC1扩展了TypeC等等。
StructureX,TypeAX,TypeBX,TypeCX等。
每个特殊结构都有一个特定的子类型A,子类型B和子类型C等。泛型类定义了一些代码(属性和方法),我想在处理特殊结构时不再使用它们。 我面临的问题最好用以下代码解释。 (我不知道这是否能以某种方式通过Java和#34; generics&#34来解决;但我认为不是。)
/***********************************************************************************************
/ 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;
}
答案 0 :(得分:0)
也许Generics可以提供帮助吗?
将Structure
声明为通用:
class Structure<T1 extends TypeA, T2 extends TypeB, T3 extends TypeC> {
T1 instanceA;
T2 instanceB;
T3 instanceC;
}
您的特定结构将通过指定类型参数继承通用Structure
:
class Structure1 extends Structure<TypeA1, TypeB1, TypeC1> {
// here instanceA will be of type TypeA1, instanceB will be TypeB1 etc.
}
答案 1 :(得分:0)
您的类型层次结构似乎不必要地复杂。实现数据继承通常具有挑战性,这种情况就是一个典型的例子。
您可以考虑重新设计类型的要点:
Type
和TypeB
相同,至少就帖子而言。除非每个类都有特定的行为,否则可以使它们合并:
// Replacement for TypeA and TypeB
class Type {
int genericAttribute;
}
如果他们有特定的行为,你可以使Type
成为一个界面,并考虑切换到getter和setter而不是字段(这是一个更好的主意)
在此之后,TypeA1
和TypeB1
可以扩展同一个父级Type
:
class TypeA1 extends Type {
int specificAttribute;
}
class TypeB1 extends Type {
int specificAttribute;
}
关于 Structure
类:您只需要此类,因为您希望实现&#34; generic&#34;与TypeA
和TypeB
相关的行为。不应再需要这种区别,因为这两者已经合并到Type
中,所以你可以省去这个类,留下数据来处理。数据可以移到Structure1
(这些字段不需要一个共同的,单独的位置,因为Structure1
无论如何都有两种具体类型):
//this doesn't need a parent any more
class Structure1 {
TypeA1 instanceA;
TypeB1 instanceB;
Structure1() {
instanceA = new TypeA1();
instanceB = new TypeB1();
}
//This doesn't have to be implemented like this
//I kept it to show the relation to your original
//design. I would simply add
//setGenericAttribute(int) to Type
void setGenericAttribute(Type type, int value) {
type.genericAttribute = value;
}
void specificMethod() {
setGenericAttribute(instanceA, 42);
instanceA.specificAttribute = 13;
setGenericAttribute(instanceB, 42);
instanceB.specificAttribute = 13;
}
}
答案 2 :(得分:0)
TL; DR 在您的类型上使用方法转发,如果确实有效,因为事情过于复杂,那么请查看SOLID原则并使用设计模式使您的类型和类遵循该原则。
Structure
课程正在努力实现两个目的。您正在尝试创建一个负责创建和包含对象的数据对象,同时还尝试处理对象的数据。 您基本上需要选择两种设计模式来处理您的意图。我建议使用Bridge和Builder模式。创建一个构建Type对象的构建器类,然后使结构类只包含顶级类的字段。然后结构类不必访问特定于类型的方法或字段。但是构建器会,因此您需要考虑为不同类型构建构建器的最佳SOLID方法。您可能需要为每种类型或每个类别构建一个构建器,具体取决于它的复杂程度,但是如果您的getter和setter不会太糟糕。您还可以考虑将工厂或抽象工厂与构建器一起使用,以便工厂确定对象将使用哪种类型(以及子类/父类),构建器将使用该信息构建该特定类的对象。填写了所有特定字段。方法转发是您的朋友。您似乎已经有了这个想法,但它并没有尽可能多地使用。如果要创建在不同对象上设置值的通用方法,那么使类具有覆盖/重载方法,为您完成工作。在下面的示例中更容易看到解释:
class TypeA {
int genericAttribute;
setAttributes(int genericAttribute){
this.genericAttribute = genericAttribute;
}
}
class TypeB {
int genericAttribute;
setAttributes(int genericAttribute){
this.genericAttribute = genericAttribute;
}
}
class TypeA1 extends TypeA {
int specificAttribute;
setAttributes(int genericAttribute, int specificAttribute){
setAttributes(genericAttribute);
this.specificAttribute = specificAttribute;
}
}
class TypeB1 extends TypeB {
int specificAttribute;
setAttributes(int genericAttribute, int specificAttribute){
setAttributes(genericAttribute);
this.specificAttribute = specificAttribute;
}
}
继续这种模式,即使没有尝试,你也会得到你想要的东西。