Java 让一个类成为几个超类的子类
在我无法更改的代码中,有几个(5+)类需要扩展几个字段。有没有办法不用编写(每次需要修改时都要编辑)几乎完全相同的代码5次就可以做到这一点?那么还有比这更优雅的方式吗:Java 让一个类成为几个超类的子类,java,inheritance,Java,Inheritance,在我无法更改的代码中,有几个(5+)类需要扩展几个字段。有没有办法不用编写(每次需要修改时都要编辑)几乎完全相同的代码5次就可以做到这一点?那么还有比这更优雅的方式吗: class Subclass1 extends Superclass1 { private String newField; public String getNewField() { return newField; } public void setNewField
class Subclass1 extends Superclass1 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
class Subclass2 extends Superclass2 {
private String newField;
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
//...
我不想要多重继承,我想要5个独立的子类-只是没有重复的代码,因为所有的子类添加完全相同
我能想到的唯一替代方法是复制原始类,并让副本扩展一个可能更糟糕的超类。您可以使用一个泛型包装类,只要它不会太繁琐而无法更改使用它的其余代码
class Wrapper<E> {
private E obj;
private String newField;
public Wrapper (E obj) {
this.obj = obj;
}
public E get() {
return obj;
}
public String getNewField() {
return newField;
}
public void setNewField(String newField) {
this.newField = newField;
}
}
类包装器{
私人电子商务;
私有字符串newField;
公共包装器(E obj){
this.obj=obj;
}
公共E get(){
返回obj;
}
公共字符串getNewField(){
返回newField;
}
public void setNewField(字符串newField){
this.newField=newField;
}
}
不,在Java中不能这样做。您可以使用某些其他基于JVM的语言,例如Scala(traits)。但是,如果必须使用纯java,您可以考虑以下内容:
- 确定要添加的字段的用途(希望是单一用途)以及所需的行为
- 创建一个包含所有字段和新方法的新类。例如:
public class ExtraFields // Don't use this name! { private String myExtraField1; private String myExtraField2; // etc. public void doSomethingWithExtraFields() { // etc. } }
public class Subclass1 extends Superclass1 { private ExtraFields extraFields; public MySubclass() { super(); extraFields = new ExtraFields(); } public void doSomethingWithExtraFields() { extraFields.doSomethingWithExtraFields(); } }
public class Wrapper<T> // Don't use this name either... { private ExtraFields extraFields; private T myClass; public Wrapper(T myClass) { this.myClass = myClass; this.extraFields = new ExtraFields(); } }
public class ExtraFields // Don't use this name!
{
private String myExtraField1;
private String myExtraField2;
// etc.
public void doSomethingWithExtraFields() {
// etc.
}
}
public class Subclass1 extends Superclass1
{
private ExtraFields extraFields;
public MySubclass()
{
super();
extraFields = new ExtraFields();
}
public void doSomethingWithExtraFields()
{
extraFields.doSomethingWithExtraFields();
}
}
public class Wrapper<T> // Don't use this name either...
{
private ExtraFields extraFields;
private T myClass;
public Wrapper(T myClass) {
this.myClass = myClass;
this.extraFields = new ExtraFields();
}
}
public class ExtraFields // Don't use this name!
{
private String myExtraField1;
private String myExtraField2;
// etc.
public void doSomethingWithExtraFields() {
// etc.
}
}
public class Subclass1 extends Superclass1
{
private ExtraFields extraFields;
public MySubclass()
{
super();
extraFields = new ExtraFields();
}
public void doSomethingWithExtraFields()
{
extraFields.doSomethingWithExtraFields();
}
}
public class Wrapper<T> // Don't use this name either...
{
private ExtraFields extraFields;
private T myClass;
public Wrapper(T myClass) {
this.myClass = myClass;
this.extraFields = new ExtraFields();
}
}
公共类包装器//也不要使用此名称。。。
{
私人外域外域;
私人密室;
公共包装器(T myClass){
this.myClass=myClass;
this.extraFields=新的extraFields();
}
}
在第二种方法中,您不需要严格地使用ExtraFields
类。但这样做通常还是一个好主意,以便封装相关功能希望有帮助 因为不能更改基类,所以不可能消除冗余。Eric Galluzzo在一个单独的类中存储额外字段的想法是迄今为止最好的,但我不知道这在您的情况下是否可行。如果不是,则创建一个定义额外字段的
接口
。您仍然需要进行大量重复键入,但至少在出错时您会立即知道。简短回答:在Java中,这是不可能的。即使在Java8中,通过使用默认方法的接口,您也可以实现部分功能,但不是全部功能,因为接口不能有实例字段扩展,这使Seans的建议更进一步。。。您可以使用java8/interfaces/defaults进行一些恶意攻击,以避免代码重复。类似于将贴图作为常量添加到接口。映射键为“this”(以便识别不同的对象);这个值可能是另一张地图。。。允许您存储键/值对。不确定这是否有效;但也许有兴趣发现。。。但当然:这将是一个糟糕的黑客行为;如果您使用Spring,您可以尝试使用介绍:(基于AOP的mixin功能)@Nathanhughs您可以使用静态AspectJ编译获得相同的功能,而不使用Spring。(春天很酷,但你应该有正确的理由使用它)@Sean:我的意思是,如果OP有现有的基础设施,他可能会利用它。如果他能使用AspectJ,那也行。