如何禁止子类有方法?

How to prohibit a subclass from having a method?

在我的 Java 项目中,我有方法 addType1AndType2(),其中包含 windows 扩展列表和列表中的 select 对象。创建起来非常复杂且耗时,因为必须滚动并且 xpaths 不断变化。这里有两个列表是实际名称,但由于公司专有信息,我将只称它们为 Tyep1Type2.

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

我可以做一个class UpdateType1 extends AddType1AndType2{},我已经做到了。但是仍然有像selectType2Value()这样的方法在subclass.

中是继承的但是不可能的

如果我执行 @Override 并在子 class 中将 class 声明为私有,我会收到一个错误,提示我无法降低子 [=33= 中的可见性].

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

问题是:你的模型是错误的。

继承 不仅仅是将 "A extends B" 放入源代码。 A extends B表示:A"is a"B.

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

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

所以真正的答案是:你应该退后一步,仔细决定你真正想要分享的方法。你把那些放在你的基地 class。其他任何事情都必须去。您可能会定义其他接口和更多基础 classes,例如

class EnhancedBase extends Base implements AdditionalStuff {

编辑:鉴于您的评论;最好的方法是:

  1. 创建接口来表示应该一起使用的各种方法组
  2. 而不是扩展那个基础class,使用组合:创建一个新的class A那个使用 一些 B 对象来实现 one/more 这些新接口。

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

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

带有 'final' 修饰符的方法不能在子类中重写。

创建接口

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 的当前代码将变成一个基础助手 class:

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

那么您的新 AddType1AndType2 class 将是:

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

而您的新 UpdateType1 可以定义为

 public class UpdateType1 
      extends BaseOperationsType1AndType2 
      implements IUpdateType1 {
       //
 }

瞧。