在Java接口中添加新方法,使其对继承类的更改最少
可能重复:在Java接口中添加新方法,使其对继承类的更改最少,java,inheritance,interface,Java,Inheritance,Interface,可能重复: 有一个场景,我有接口X,它已经用我的数千个类实现了。现在我想在接口X中添加新方法。因此,如何以最小的方式进行更改以解决我所有类中方法被重写的问题没有简单的方法可以做到这一点。如果向接口添加方法,则所有实现类都必须重写该方法。如果将接口更改为抽象类,那么还必须重构实现类 但是你有一个类层次结构,对吗?因此,您可以通过仅在基类中实现该方法来最小化工作量。但这取决于您的具体要求和细节,所以我想很高兴实施 如果没有简单的类层次结构,您可以使用它来实现新的方法,那么也许是时候考虑进行重大重写
有一个场景,我有
接口X
,它已经用我的数千个类实现了。现在我想在接口X
中添加新方法。因此,如何以最小的方式进行更改以解决我所有类中方法被重写的问题没有简单的方法可以做到这一点。如果向接口添加方法,则所有实现类都必须重写该方法。如果将接口更改为抽象类,那么还必须重构实现类
但是你有一个类层次结构,对吗?因此,您可以通过仅在基类中实现该方法来最小化工作量。但这取决于您的具体要求和细节,所以我想很高兴实施
如果没有简单的类层次结构,您可以使用它来实现新的方法,那么也许是时候考虑进行重大重写,以减少未来的维护工作量了。我将为您的接口创建一个扩展,仅用于需要附加方法的类
public interface BaseInterface {
public int exampleMethod();
}
public interface ExtendedInterface extends BaseInterface {
public int anotherMethod();
}
数千个类已经实现了BaseInterface
。对于需要额外方法的类,可以将它们更改为实现ExtendedInterface
如果对象存储在诸如BaseInterface[]
数组之类的集合中,这仍然有效,因为ExtendedInterface
类型的对象也是BaseInterface
类型的对象,因此它们仍然可以存储在相同的公共集合中
例如,这仍然是完全有效的
BaseInterface[] objects = new BaseInterface[2];
objects[0] = new ClassThatImplementsBaseInterface();
objects[1] = new ClassThatImplementsExtendedInterface();
但是,如果需要访问扩展接口的新方法,但对象存储在BaseInterface
集合中,则需要将其强制转换为ExtendedInterface
,然后才能使用它
BaseInterface[] objects = new BaseInterface[1];
objects[0] = new ClassThatImplementsExtendedInterface();
if (objects[0] instanceof ExtendedInterface){
// it is an ExtendedInterface, so we can call the method after we cast it
((ExtendedInterface)objects[0]).anotherMethod();
}
else {
// it is a BaseInterface, and not an ExtendedInterface
}
这可能适合也可能不适合,取决于您的使用情况
如果您真的需要数千个对象来实现新方法,则必须将该方法添加到
BaseInterface
,然后使用IDE或文本编辑器的功能在所有类中实现该方法。例如,您可以在文本编辑器中全部打开它们,然后执行“查找-替换”以查找每个类的公共内容,并将其替换为新方法的公共代码+默认代码。非常快而且无痛。我确信某些IDE可能还会自动将方法声明添加到所有继承类中,或者至少在右键单击菜单中有一个选项来执行此操作。如果新方法是接口的真正扩展,然后,正确的做法是编辑接口,并使用开发环境的工具查找必须实现新功能的所有位置。然后做这项工作。Eclipse和Netbeans将做得很好
[NB我有点惊讶重构工具没有考虑一些手动工作,但事实确实如此。]
如果旧的代码中大部分时间不调用新方法,则将新接口视为旧接口的扩展:
public interface NewInterface extends OldInterface {
void newMethod();
}
如果需要使用空版本的newMethod()
将旧接口对象传递给新接口使用者,可以执行以下操作:
public class NewInterfaceWrapper<T extends OldInterface> implements NewInterface {
private T wrapped;
public NewInterfaceWrapper(T wrapped) {
this.wrapped = wrapped;
}
// Define all the old interface methods and delegate to wrapped.method
// Now provide the null implementation of new method.
void newMethod() { }
}
...
wantsNewInterface(new NewInterfaceWrapper(oldImplementer));
公共类NewInterfaceWrapper实现NewInterface{
私人T包装;
公共NewInterfaceWrapper(T包装){
this.wrapped=wrapped;
}
//定义所有旧接口方法并委托给wrapped.method
//现在提供新方法的空实现。
void newMethod(){}
}
...
WantNewInterface(新的NewInterfaceWrapper(旧的实现者));
这并不漂亮,但大型系统通常会随着年龄的增长而变得粗糙。将接口更改为抽象类并提供基本实现?您有数千个类吗?哇。@Verisimility该解决方案不会很快造成维护噩梦并为系统引入许多接口吗?@Verisimility是正确的:从接口继承是最简单、最干净的方法。IMHO…在界面中创建新方法作为默认方法,并为其提供默认实现。您是否阅读了@Verisimilude在评论中发布的链接?如果你不这样做,那么请阅读它,它会改变你的答案和观点。是的,但这迟早不会导致维护问题吗?它还取决于所引入的方法的类型,如果所讨论的方法是在接口的任何地方都可以使用的,如果作为类型使用,那么这个解决方案将不会有多大帮助…这真的取决于,如果你有一堆类,即10+,你只需要其中的一些,即2,然后它将像2个类实现了新方法,8+没有实现(设计也很糟糕)。如果所有实现实际接口的类都应该有这个新方法,那么OP问题就不合适了,我认为OP不需要:)。是的,我的观点是,解决方案在某些情况下可能有效,在某些情况下是不好的建议。因此,在我看来,如果像大多数项目一样需要长期维护,那么正确的方法不是这样的。。但那只是我。。给每个人自己!;-)看起来WATTO工作室和我有相同的想法。如果这不有用,很高兴删除。保留你的帖子-你有一个不同的包装方法-我没有想到这一点!这是同样的事情逼真已经说。同意,但这是更具体的用户的要求,有例子编码,在我看来是更容易理解比链接后。另外,我恰好同意这种方法,所以为什么不写一个这样的答案呢。