有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

继承Java:为什么基类方法可以调用不存在的方法?

class BaseClass {
    private void f() {
        System.out.println("Baseclass f()");
    }

    public static void main(String[] args) {
        BaseClass dc = new DerivedClass();
        dc.f();
    }
}

class DerivedClass extends BaseClass {
    public void f() {
        System.out.println("DerivedClass f()");
    }
}

在我看来,dc引用的对象应该只有一个非重写方法-public void f()方法,这使得它(public方法)在使用基类引用引用时不可见。由于dc引用的对象没有私有void f()方法,或者因为DeriverClass无法继承私有方法,因此dc引用的对象如何调用方法f()

谢谢


共 (3) 个答案

  1. # 1 楼答案

    四点:

    (1)为了详细说明vivyzer写了什么,代码编译是因为基类中的主方法可以访问该类自己的私有方法。如果您将代码编写为:

    class BaseClass {
      private void f() { }
    }
    
    class DerivedClass {
      public void f() { }
    }
    
    class Bystander {
      public static void main() {
        BaseClass inst = new DerivedClass();
        inst.f();
      }
    }
    

    那么代码就无法编译

    (2)这是语言允许的,以支持基类的作者可以添加新的私有方法而不必担心其他作者的派生类型的用例

    (3)如果方法不是私有的,您将看不到这一点。如果基类的f()具有包或受保护的可见性,那么该方法将是一个虚拟方法

    (4)Java不支持点#2的相反方向。具体来说,如果派生类具有私有方法,并且新版本的基类型引入了具有相同签名的非私有方法,则派生类和新基类不能一起使用。还有其他一些语言(例如C#)更全面地解决了这些模块化、代际发展问题。如果你对这方面感兴趣,这是一本关于Artima的好读物:Versioning, Virtual, and Override

  2. # 2 楼答案

    一个常见的(ish)误解是私有是每个实例,而不是每个类

    例如:

    class Foo
    {
        private int a;
    
        public bar(final Foo other)
        {
            other.a = 5;
        }
    }
    

    有些人认为上面的代码不应该起作用,因为“a”是“私人的”。事实并非如此,任何Foo实例都可以访问任何其他Foo实例的私有变量/方法。“private”只是意味着其他类(本例中的Foo除外)的实例无法访问私有成员

  3. # 3 楼答案

    主方法位于基类内部,私有方法对其可见。如果main在其他类中,它将不会编译