继承中的私有方法

时间:2013-01-18 03:44:51

标签: java inheritance private

这是一个有趣的代码片段:

public class Superclass {

    public static void main (String[] args){
        Superclass obj = new Subclass();
        obj.doSomething(); #prints "from Superclass"
    }

    private void doSomething(){System.out.println("from Superclass");}
}

class Subclass extends Superclass {

    private void doSomething(){System.out.println("from Subclass");}

}

我知道子类不会继承其父级的私有成员,但是obj设法调用它应该没有访问权限的方法。在编译时,obj的类型为Superclass,在运行时类型为Subclass。

这可能与doSomething()的调用发生在驱动程序类中的事实有关,这恰好是它自己的类(以及为什么可以首先调用doSomething())。

所以问题归结为,obj如何访问其父级的私有成员?

9 个答案:

答案 0 :(得分:15)

私人方法仅适用于所有者。

甚至不是所有者的孩子,亲戚或朋友。

答案 1 :(得分:13)

你自己回答了。由于私有方法不是继承的,因此超类引用会调用自己的私有方法。

答案 2 :(得分:5)

Superclass obj = new Subclass();

此时,obj既是事物,也是SubclassSuperclass对象。在变量声明中使用Superclass这一事实只是一个问题。

执行:obj.doSomething()时,您告诉编译器调用doSomething()的私有方法obj。因为您是从Superclass内的主静态方法执行的,所以编译器可以调用它。

如果您使用Subclass的主要方法而不是Superclass中的方法,则无法访问该方法,因为正如您所说,它既不是继承的,也不是您的一部分Subclass的定义。

所以基本上你理解了继承。问题与私人方法的可见性有关。

答案 3 :(得分:4)

它有效,因为您从Superclass的方法中转换为Superclass。在该上下文中,编译器可以使用Superclass.doSomething

如果要将超类和子类更改为两个不同的任意类A和B,与包含main方法的类无关,并尝试使用相同的代码,编译器会抱怨无法访问方法。

答案 4 :(得分:3)

当您使用此行时:

Superclass obj = new Subclass();

您将Subclass转换为超类对象,该对象仅使用超类的方法和相同的数据。如果将它转换回子类,则可以再次使用Subclass方法,如下所示:

((Subclass)obj).doSomething(); #prints "from Subclass"

答案 5 :(得分:3)

由于对象obj的引用类型为SuperClass,因此对doSomething()的调用会尝试访问SuperClass本身定义的私有方法(不能覆盖私有方法) )。 由于doSomething()可以在SuperClass内访问,main方法可以调用doSomething()而不会出现任何错误。

希望这有帮助! : - )

答案 6 :(得分:1)

  

为什么首先可以调用doSomething()?

为什么不呢? objSubclassSuperclass的一个实例,doSomething()中声明了Superclassobj中使用了Superclass.doSomething(),因此您访问doAnotherThing(),您可以尝试重命名您的方法(例如obj),您仍然可以访问它。

  

obj如何访问其父级的私有成员?

私有方法没有父/子,并且Superclass也是obj的类型,因此它可以访问其中声明的所有私有方法/字段,因为{{1在这个类中使用。如果您不在Superclass或具有Superclass作为成员的类(嵌套类),您将失去此访问权限。

那又怎样?

SuperClass的私有方法和SubClass的私有方法之间没有任何关系/继承,即使它们具有相同的名称和签名,也来自Java Language Specification, Java SE 8 Edition

  

私有方法和在final中立即声明的所有方法   class(§8.1.1.2)表现得好像是最终的,因为它是不可能的   覆盖它们。

答案 7 :(得分:0)

要理解这个问题,你可以将私有方法与超类和子类的成员变量联系起来。

所以我们知道成员变量不会在子类中被覆盖。

例如:

Class A{
 int i = 10;
}

Class B extends A{
  int i = 11;
}

Class C extends A {
   int i = 12;
}

A a1 = new B();
print(a1.i) // Will print 10

A a2 = new B();
print(a2.i) // Will print 10 

类似的方式,当没有继承引用变量时,将考虑超类。

答案 8 :(得分:-1)

当我们在派生类中定义一个具有相同名称的私有方法时,它会成为一个新方法,因为派生类不会继承私有成员。

由于私有方法在类外部甚至不可见,我们永远不能从派生类调用基类私有方法,它会抛出编译错误:

线程“main”中的异常java.lang.Error:未解决的编译问题:     来自Base类型的方法aPrivateMethod()不可见

我们可以使用向下转换到父类引用来调用派生类私有方法,该方法只能在该派生类中访问。