【问题标题】:How to prohibit a subclass from having a method?如何禁止子类拥有方法?
【发布时间】:2017-04-28 21:09:15
【问题描述】:

在我的 Java 项目中,我有 addType1AndType2() 方法,它有窗口,您可以在其中展开列表并从列表中选择对象。创建非常复杂且耗时,因为必须滚动并且 xpath 不断变化。其中有两个列表是实际名称,但由于公司专有信息,我将它们称为Tyep1Type2

现在我有一个UpdateType1 类,它使用AddType1AndType2 中的所有复杂方法,但与Type2 没有任何关系。我可以复制AddType1AndType2 并剪切我不需要的所有内容,但这将是复制,并且必须在两个类中复制更改。这违背了继承和可重用的目的。

我可以制作一个class UpdateType1 extends AddType1AndType2{},我已经完成了。但是仍然有像selectType2Value()这样的方法被继承但在子类中是不可能的。

如果我执行@Override 并在子类中将该类声明为私有,我会收到一个错误,即我无法降低子类中的可见性。

知道我能做什么吗?现在我只是放了一个throw new AssertError("Do not use"),但这似乎有点蹩脚。有没有更好的办法,甚至会在运行时给出编译时错误而不是断言,或者这是最好的方法?

【问题讨论】:

  • 我也不认为抛出异常是最好的解决方案。也就是说,考虑使用java.lang.UnsupportedOperationException。它同样蹩脚,但与现有环境更加融合。
  • 关于命名的旁注:方法名称在 java 中采用 camelCase。

标签: java inheritance visibility


【解决方案1】:

问题是:你的模型错了。

继承更多不仅仅是在源代码中添加“A 扩展 B”。 A 扩展 B 意思是:A“是”B。

无论何时使用 B 对象,您都应该能够放置一个 A 对象(称为 Liskov substitution principle)。

长话短说:如果 B 有 A 不应该有的方法......那么你不应该有 A 扩展 B。

所以真正的答案是:你应该退后一步,仔细决定你真正想要分享的方法。你把它们放在你的基类上。其他任何事情都必须去。你可能会定义额外的接口和更多的基类,比如

class EnhancedBase extends Base implements AdditionalStuff {

编辑:给出您的评论;最好的方法是:

  1. 创建接口,表示应该一起使用的各种方法组
  2. 扩展那个基类,使用composition:创建一个新的类A,使用一些B对象来实现一个/更多这些新界面。

记住这是一个很好的例子,为什么 LSP 真的很有意义 ;-)

【讨论】:

  • 非常正确。但是,该类已经存在了一段时间并已集成到系统中;-(
【解决方案2】:

创建接口

public interface IAddType1 {... /* methods signtatures to add Type1 */}
public interface IAddType2 {... /* methods signtatures to add Type2 */}
public interface IUpdateType1 {...  /* methods signtatures to update Type1 */}

那么你在AddType1AndType2 的当前代码将成为一个基本的帮助类:

 public abstract class BaseOperationsType1AndType2{  
     //code originally at AddType1AndType2: methods that add Type1 and Type2
 } 

那么您的新 AddType1AndType2 课程将是:

public class AddType1AndType2 
     extends BaseOperationsType1AndType2, 
     implements IAddType1 , IAddType2 {
        //nothing special. 
 } 

你的新UpdateType1可以定义为

 public class UpdateType1 
      extends BaseOperationsType1AndType2 
      implements IUpdateType1 {
       //
 }

瞧。

【讨论】:

    【解决方案3】:

    您可以使用'final'关键字来禁止在子类中扩展方法。

    带有“final”修饰符的方法不能在子类中被覆盖。

    【讨论】:

      猜你喜欢
      • 2012-10-12
      • 2020-08-03
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      • 1970-01-01
      相关资源
      最近更新 更多