0

如果这个问题可能一直被问到,我很抱歉,但我搜索并找不到足够的答案。

如果公共成员/方法正在访问私有成员/字段,如何禁用它们的继承?

所以考虑一下:

public class A {
    private MemberA a = new MemberA();

    public void foo(TypeA x) {
    a.methodCall(); //access to a
    }
}

public class B extends A {
    private MemberB b = new MemberB();

    public void foo(TypeB x) {
    b.methodCall(); 
    }
}

如果你点击调试器,你会看到,B 有一个字段 a,类型为 MemberA。这符合 Java 规则,因为如果公共成员可以访问私有成员,它将被继承。但是在 B 中,“a”是无用的,只会占用内存——即使你没有在 B 的构造函数中实例化它,因为 B 调用它是超级构造函数,并且它必须在 A 中实例化,因为 a 对 a 有很大用处。

需要A 和 B 具有相同的方法名称,并且它们必须是公共的,但是由于它们做了根本不同的事情但也共享共同的逻辑 B 需要从 A 继承。

所以基本上,我需要知道如何同时重载和覆盖一个方法。或者重复代码。该怎么办?

4

2 回答 2

5

这种情况——一个类有你不想继承的数据成员——被称为“拒绝遗赠”反模式,它通常意味着你的继承关系是错误的。而不是让 B 扩展 A,您需要一个接口 C,它们都独立实现。如果您确实想要共享重要的实现,那么也许您可以引入 A 和 B 可以共享的抽象基类。

于 2013-07-03T01:26:01.540 回答
0

或者,也可能是 MemberA 和 MemberB(不是 A 和 B)共享公共接口(或抽象类),比如“Member”,包括 methodCall()。然后你可以做

public class A {
  protected Member myMember;  // sounds like an Austin Powers movie...

  // in the constructor
  myMember= new A();
}

而在 B 类中,构造函数会这样做:(或使用 DI 等...)

  myMember = new B();

和 in foo()不需要重载,你调用myMember.methodCall().

在不知道您的问题的情况下,很难说这种方法或@Ernest 的方法是否更好。在任何一种情况下,您都在寻找通用功能,而且工作量可能相同。

于 2013-07-03T02:11:18.010 回答