如果公共成员访问私有成员,则不要继承私有成员

时间:2013-07-03 01:19:55

标签: java inheritance

如果可以一直询问这个问题,我很抱歉,但是我搜索过,找不到足够的答案。

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

所以考虑一下:

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有一个类型为MemberA的字段。这符合Java规则,因为如果公共成员可以访问私有成员,那么它将被继承。 但是在B中,“a”是无用的,只是占用内存 - 即使你没有在B的构造函数中实例化它,因为B调用它的超级构造函数并且它必须在A中实例化,因为它非常适用于a。

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

基本上,我需要知道如何重载和重写方法。或重复代码。怎么办?

2 个答案:

答案 0 :(得分:5)

这种情况 - 类具有您不想继承的数据成员 - 称为"Refused Bequest" antipattern,它通常意味着您的继承关系是错误的。您需要一个独立实现的接口C,而不是让B扩展A.如果您想要共享的重要实现,那么也许您可以引入A和B可以共享的抽象基类。

答案 1 :(得分: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();

并且在foo()无需重载,您拨打myMember.methodCall()

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