有人告诉我,对于Java子类,它可以继承其超类的所有成员。这甚至意味着私人会员呢?我知道它可以继承受保护的成员。
有人可以向我解释一下。我现在完全糊涂了。
答案 0 :(得分:17)
不,私有成员 未继承 ,因为私有成员的范围仅限到定义它的类。仅继承public和protected成员。
超类中的私人会员
子类 不会继承 其父类的私人成员 。 但是,如果超类有公共 或访问其的受保护方法 私人领域,这些也可以使用 由子类。嵌套类有 访问所有私人成员 它的封闭类 - 两个领域和 方法。因此,公众或 受保护的嵌套类由a继承 子类可以间接访问所有 超类的私人成员。
来自JLS
,
声明的类 的成员 私人不是继承的 该类的子类。只有会员 声明受保护的类的 或public由子类继承 在除以外的包中声明 宣布上课的人。
答案 1 :(得分:17)
这取决于你对继承这个词的确切用法。我会举例解释。
假设您有两个类:Parent
和Child
,其中Child
扩展Parent
。此外,Parent
有一个名为value
的私有整数。
现在出现了一个问题:Child
是否会继承私有value
?在Java中,继承是定义的,其答案是“否”。但是,在一般的OOP术语中,存在轻微的歧义。
您可以说它不继承,因为Child
无处可明确引用value
。即this.value
之类的任何代码都不能在Child
中使用,也不能在某些调用代码中使用obj.value
(显然)。
但是,从另一个意义上讲,您可以说value
是继承的。如果您认为Child
的每个实例也是Parent
的实例,则该对象必须包含value
中定义的Parent
。即使Child
类对此一无所知,名为value
的私有成员仍然存在于Child
的每个实例中。因此,从这个意义上讲,您可以说value
中继承了Child
。
因此,如果不使用“继承”一词,请记住子类不了解父类中定义的私有成员。但是请记住,那些私有成员仍然存在于子类的实例中。
答案 2 :(得分:2)
IMO绝不是定义问题。在基于类的继承中,意味着将行为传播给后代。因为这样的私人成员会继承,我不会详细说明这是如何发生的。
实际上我发现“不继承”的答案对新开发者来说是危险的,他们不能立即理解私人成员隐藏在你班级的皮肤下,他们(可能)会对其行为产生严重影响,对象的大小等。
在计算机科学中“开发先于理解”是很常见的,但是让我们避免构建(或破坏)我们的OOP概念化,假设某些技术人员编写了一个众所周知的基于OO平台的手册的错误“定义”
很抱歉在这么老的帖子中陈述某些内容,但问题始终有效。
答案 3 :(得分:1)
尽管https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2显示不继承私有成员。实际上,它是由子类继承的。当我们使用调试器跟踪变量时,它将在“继承”标签下显示私有成员,因此只需尝试一下即可。还有另一篇文章讨论了这个问题,其中大多数人认为不是继承的,这误导了包括我在内的许多人。
答案 4 :(得分:0)
您将在这里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
是的,子类可以间接访问超类的私有成员。子类不能直接访问超类的私有成员。
超类的所有公共,私有和受保护成员(即所有字段和方法)均由子类继承,但子类只能直接访问超类的公共和受保护成员。如果从超类继承的成员可以访问超类的私有成员,则子类可以使用该继承的成员来访问超类的私有成员。