2

我很好奇是否可以声明一个类的成员,使其根本不暴露给派生类,或者至少在子类调用super(). Java中有这样的功能吗?

 class A{
      static int foo = 1;
    }

    class B extends A{
      public B(){
         System.out.print(foo);/// how do I make this not work?
      }
    }

编辑:我实际上是偶然用解决方案输入了我的问题(我的实际代码缺少私有代码)。因此,我将编辑我的问题并删除私人问题,以便这是一个有意义的问题:)

4

4 回答 4

3

那已经行不通了-该成员是私有的,因此从 B 中看不到。

但是,如果您试图隐藏子类中已经可见的成员,例如

public class A {
    public void foo() {
        // Whatever
    }
}

public class B extends A {
    // ???
}

...
B b = new B();
b.foo(); // I don't want this to work, because it's a B!

......那么你不能那样做。这将打破Liskov 的替代原则

于 2013-03-15T22:17:45.923 回答
2

对该问题的一种解释是,您希望访问foo失败,但访问super.foo成功。它可能发生在一种特定情况下 - 如果 A 和 B 都包含在同一个顶级类中,或者其中一个是包含另一个的顶级类。

class X

    class A  
        private int foo;

    class B extends A

        print(foo);           // fail
        print(super.foo);     // ok  
        print(((A)this).foo); // ok...

或者

class A
    private int foo;

    static class B extends A    // declared inside A

        print(foo);           // fail
        print(super.foo);     // ok  
        print(((A)this).foo); // ok...

原因是私有成员不是继承的,所以this.foo不存在;但是它们可以通过适当的限定符在整个顶级类中访问,因此A.foo是可访问的。请参阅http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1-100-D-3

于 2013-03-15T22:31:00.490 回答
1

如果将变量标记为,private则子类将无权访问它。

(另外,你可能不希望static在你的 foo 声明中。)

于 2013-03-15T22:18:02.723 回答
1

访问修饰符(例如,将成员声明为private)是唯一真正阻止访问成员的东西。(即便如此,您仍然可以使用反射来获取私有成员。)


当您提到 时super,您可能正在考虑使用Java 意义上的隐藏;例如,您声明其他内容的地方称为foo隐藏原始声明。但是,它在这里无济于事。

  • 您必须声明第二个fooinB或某些子类C,例如A... extends C... extends B

  • 由于这些是静态的,B因此始终可以将原始文件foo作为A.foo. 事实上,既然<class>.<name>是推荐的方法,这种(假设的)隐藏使用并没有取得任何有价值的结果(IMO)。

  • 即使它确实有效,它也只是将 one 替换foo为 another foo,这不是您的用例所需要的。

简而言之,隐藏不是减少或控制暴露的有效手段。

于 2013-03-15T23:36:10.367 回答