【发布时间】:2011-09-26 11:09:41
【问题描述】:
有人告诉我,Java 子类可以继承其超类的所有成员。那么这是否意味着即使是私人成员?我知道它可以继承受保护的成员。
谁能给我解释一下。我现在完全糊涂了。
【问题讨论】:
标签: java inheritance subclass superclass private-members
有人告诉我,Java 子类可以继承其超类的所有成员。那么这是否意味着即使是私人成员?我知道它可以继承受保护的成员。
谁能给我解释一下。我现在完全糊涂了。
【问题讨论】:
标签: java inheritance subclass superclass private-members
您将在这里 100% 满意。我在我的电脑上测试了它,我得出的结论是我要把它贴在这里。只需通过下面编写的程序,查看程序输出并阅读最后给出的结论。 要自己测试,请将整个程序复制并保存在名为“InheritanceTest.java”的文件中,然后编译并最终运行。
// Testing if a subclass can access the private members of a superclass
class Class1 {
private String name;
public void setName(String name) {
this.name = name;
System.out.println("The name has been set successfully.");
}
public void showName() {
System.out.println("The name is: " + name);
}
}
class Class2 extends Class1 {
private int age;
public void setAge(int age) {
this.age = age;
System.out.println("The age has been set successfully.");
}
public void showAge() {
System.out.println("The age is: " + age);
}
public void displayName() {
//Accessing the private member of superclass here
//System.out.println("The name is: " + name); //error, can't compile because access to the private member name of the superclass Class1 is not permitted here.
}
}
class InheritanceTest {
public static void main(String[] args) {
Class1 c1 = new Class1();
Class2 c2 = new Class2();
c1.setName("Name_C1");
c2.setName("Name_C2"); //No error, setName() is a public member of the superclass which indirectly gives access to the private member "name".
c1.showName();
c2.showName(); //No error, showName() is a public member of the superclass which indirectly gives access to the private member "name".
c2.setAge(25);
c2.showAge();
//c2.displayName(); //error
}
}
The name has been set successfully.
The name has been set successfully.
The name is: Name_C1
The name is: Name_C2
The age has been set successfully.
The age is: 25
是的,子类可以间接访问超类的私有成员。子类不能直接访问超类的私有成员。
超类的所有公共、私有和受保护成员(即所有字段和方法)都由子类继承,但子类只能直接访问超类的公共和受保护成员。如果从超类继承的成员允许访问超类的私有成员,则子类可以使用这个继承的成员访问超类的私有成员。
【讨论】:
这取决于您对继承一词的确切用法。我会举例说明。
假设您有两个类:Parent 和 Child,其中 Child 扩展了 Parent。此外,Parent 有一个名为 value 的私有整数。
现在问题来了:Child 是否继承了私有的value?在 Java 中,定义继承的方式是回答“否”。但是,在一般的 OOP 术语中,有轻微的歧义。
您可以说它没有继承,因为Child 无法明确引用value。 IE。 this.value 之类的任何代码都不能在 Child 中使用,obj.value 也不能在某些调用代码中使用(显然)。
然而,在另一种意义上,你可以说value 是继承的。如果您认为Child 的每个实例也是Parent 的一个实例,那么该对象必须包含value 中定义的Parent。即使Child 类对此一无所知,一个名为value 的私有成员仍然存在于Child 的每个实例中。所以从这个意义上说,你可以说value继承了Child。
所以不要使用“继承”这个词,只要记住子类不知道父类中定义的私有成员。但也要记住,这些私有成员仍然存在于子类的实例中。
【讨论】:
虽然https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 表明私有成员没有被继承。实际上,它是由子类继承的。当我们使用调试器跟踪变量时,它会显示“继承”标签下的私有成员,所以请尝试一下。还有一个帖子在讨论这个问题,大部分人认为不是遗传的,这误导了很多人,包括我一开始。
【讨论】:
IMO 绝不是定义问题。在基于类的继承中,意味着将行为传播给后代。因此,私有成员确实会被继承,我不会详细说明这是如何发生的。
实际上,我发现“不继承”的答案对新开发人员来说是危险的,他们并没有立即理解私有成员隐藏在你的类的皮肤下并且它们(可能)对其行为产生严重影响,对象的大小等。
在计算机科学中“开发先于理解”是很常见的,但是我们要避免构建(或破坏)我们对 OOP 的概念化,假设某些技术人员在编写一个著名的基于类的 OO 平台手册时采用了错误的“定义” .
很抱歉在这么旧的帖子中陈述了一些东西,但问题总是有效的。
【讨论】:
不,私有成员不被继承,因为私有成员的范围仅限于定义它的类.只有 public 和 protected 成员被继承。
超类中的私有成员
子类不继承 其父类的私有成员。 但是,如果超类有 public 或访问其受保护的方法 私有字段,这些也可以使用 由子类。嵌套类有 访问所有私有成员 它的封闭类——包括字段和 方法。因此,公众或 由 a 继承的受保护的嵌套类 子类可以间接访问所有 超类的私有成员。
来自JLS,
类的成员被声明 私有不被继承 该类的子类。只有会员 被声明为受保护的类的 或 public 被子类继承 在包装以外的其他包装中声明 声明类的地方。
【讨论】: