是否有办法在编译时阻止子类公开除基类中定义的公共方法之外的公共方法?
例如:
abstract public class AClass {
abstract public void anAllowedMethod();
}
public class BClass extends Aclass {
public void anAllowedMethod() {
}
public void anAdditionalNonAllowedMethod() {
}
private void thisMethodIsAllowedBecauseItsNotPublic() {
}
}
也许我可以在AClass中使用一些关键字来声明子类只能实现在AClass中定义的方法(即“anAllowedMethod()”)?
答案 0 :(得分:3)
不是真的。当你定义一个类并说它扩展/实现另一个类时,它必须遵守它扩展/实现的类的契约。对进一步包含所述类别的行为没有限制。
在我正在开发的项目中,一些开发人员正在为子类添加额外的方法,这些方法是不必要的
正如我所看到的,这实际上意味着您的设计会因为开发人员做出他们喜欢的事情(通过向对象添加新的公共行为)而成为碎片。
不幸的是,如果你在设计处于实施阶段(编码)时没有管理,那么坏事一定会发生。请考虑审核流程(自动/手动)
答案 1 :(得分:2)
你可以让这个类最终,因此它不能被子类化(当然不能是抽象的),而是将它设计为使用组合/委托,所以不是通过子类改变实现,而是通过什么策略来改变它您在类的实例组合中使用的对象。
答案 2 :(得分:1)
Java不支持此功能。但是,如果您希望类的客户端仅使用您定义的接口,则可以声明一个java接口,然后使用工厂创建实现该接口的对象。因此,客户端只能从接口调用方法。当然,如果有人确定他们可以找到解决方法(比如做一个明确的演员),但如果人们故意破坏你的设计,你就会遇到更大的问题。
答案 3 :(得分:1)
在游戏的这个阶段,它可能为时已晚,但您可以做的是使用相关方法创建一个最终类,该方法在其具有实际实现的不同类型的构造函数中获取委托,并且具有以下方法:最后一个类调用委托。这样他们添加到委托中的任何内容都不会被调用。
答案 4 :(得分:0)
不是一般情况......
但是...
如果您尝试阻止特定接口,则可以使用接口中的方法名称在抽象基类中声明最终方法。这不会阻止任何人使子类实现接口,但它肯定会阻止他们对方法调用做任何事情。
我想你可以在运行时使用反射来禁止它......
你绝对可以用AOP容器做到这一点。我刚看到关于OP的其他评论,我现在看到你的目标。我的建议是将其视为应在源代码管理级别进行管理的内容 - 要么具有对问题进行运行时检查的测试模式(即将其视为实现单元测试),要么(如果您使用的是CI系统) )在办理登机手续时测试过这种东西。
答案 5 :(得分:0)
您是否考虑过最终?
我知道,这不是你要求的,但是语言中没有这样的功能。或者,就此而言,我知道的任何语言 - 我都知道很多。
这导致我们试图找到另一种方法去做你想做的事情 - 以满足潜在的需求。
然而,由于我无法想象这样做的明智理由,我很难过。
为什么要阻止子类添加方法?你害怕会发生什么事?
答案 6 :(得分:0)
我同意线上的其他人,你想要做的事情是不可取的。但是,我相信您可以使用反射来确保声明的任何方法都是您期望的方法。
Method[] methods = this.getClass().getMethods();
for (Method method : methods)
{
if (method.getName() ... ) // check to make sure method is expected
{
.... // if method not expected throw an exception
}
}