这是面试问题。
子类继承private吗 字段?
我的回答是“不”,因为我们不能使用“正常的面向对象的方式”访问它们。但是采访者认为它们是继承的,因为我们可以间接或使用反射访问这些字段,并且它们仍然存在于对象中。
回来后,我在javadoc中找到了以下引用:
超类中的私人成员 一个 子类不继承私有 父类的成员。
你知道面试官观点的论据吗?
这是面试问题。
子类继承private吗 字段?
我的回答是“不”,因为我们不能使用“正常的面向对象的方式”访问它们。但是采访者认为它们是继承的,因为我们可以间接或使用反射访问这些字段,并且它们仍然存在于对象中。
回来后,我在javadoc中找到了以下引用:
超类中的私人成员 一个 子类不继承私有 父类的成员。
你知道面试官观点的论据吗?
当前回答
不。他们没有继承。
其他一些类可能间接使用它的事实不是关于继承,而是关于封装。
例如:
class Some {
private int count;
public void increment() {
count++;
}
public String toString() {
return Integer.toString( count );
}
}
class UseIt {
void useIt() {
Some s = new Some();
s.increment();
s.increment();
s.increment();
int v = Integer.parseInt( s.toString() );
// hey, can you say you inherit it?
}
}
您还可以通过反射在UseIt中获取count的值。这并不意味着你继承了它。
更新
即使值在那里,它也不会被子类继承。
例如,一个子类定义为:
class SomeOther extends Some {
private int count = 1000;
@Override
public void increment() {
super.increment();
count *= 10000;
}
}
class UseIt {
public static void main( String ... args ) {
s = new SomeOther();
s.increment();
s.increment();
s.increment();
v = Integer.parseInt( s.toString() );
// what is the value of v?
}
}
这和第一个例子的情况完全一样。属性计数是隐藏的,根本不被子类继承。不过,正如DigitalRoss指出的那样,价值是存在的,但不是通过继承来实现的。
这么说吧。如果你父亲很富有,给你一张信用卡,你仍然可以用他的钱买东西,但这并不意味着你继承了所有的钱,不是吗?
其他更新
但是,了解属性为什么在那里是非常有趣的。
坦白地说,我没有确切的术语来描述它,但正是JVM及其工作方式加载了“非继承”的父定义。
我们可以改变父类,子类仍然可以工作。
例如:
//A.java
class A {
private int i;
public String toString() { return ""+ i; }
}
// B.java
class B extends A {}
// Main.java
class Main {
public static void main( String [] args ) {
System.out.println( new B().toString() );
}
}
// Compile all the files
javac A.java B.java Main.java
// Run Main
java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0
// Change A.java
class A {
public String toString() {
return "Nothing here";
}
}
// Recompile ONLY A.java
javac A.java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to
// inheritance but the way Java loads the class
Output: Nothing here
我想确切的术语可以在这里找到:java虚拟机规范
其他回答
正如其他人所指出的那样:
https://docs.oracle.com/javase/specs/jls/se8/html/jls - 8. - html # jls - 8.2:
声明为private的类的成员不会被继承 该类的子类。只声明类的成员 Protected或public由包中声明的子类继承 除了声明类的那个。
答案无疑是否定的,没有任何“如果”和“但是”。这围绕着继承的定义。根据定义,继承是针对类的,不是针对对象的。对象是使用类定义创建的。继承只是添加到类定义中的另一个块。那么,类是否继承了父类的私有成员?没有
子类不继承父类的私有成员。但是,如果父类具有用于访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。
这取决于你对“继承”的定义。子类在内存中仍然有字段吗?肯定。它能直接访问它们吗?不。这只是定义的微妙之处;关键是要理解到底发生了什么。
我们可以简单地声明,当父类被继承时,父类的私有成员实际上成为子类的私有成员,并且不能被进一步继承或子类的对象不可访问。
我将用代码演示这个概念。子类实际上继承了父类的私有变量。唯一的问题是他们不能访问 子对象,除非您为私有变量提供公共getter和setter 在超级班。
考虑包转储中的两个类。子扩展父。
如果我没记错的话,内存中的子对象由两个区域组成。一个是父部分,另一个是子部分。子程序可以访问私有文件 节只能通过父类中的公共方法在其父类的代码中调用。
这样想。波拉特的父亲博尔托克有一个装有10万美元的保险箱。他不想共享他的“私有”变量保险箱。所以,他没有提供保险箱的钥匙。波拉特继承了保险箱。但是,如果他连门都打不开,那又有什么用呢?要是他的 爸爸提供了钥匙。
父母,
package Dump;
public class Parent {
private String reallyHidden;
private String notReallyHidden;
public String getNotReallyHidden() {
return notReallyHidden;
}
public void setNotReallyHidden(String notReallyHidden) {
this.notReallyHidden = notReallyHidden;
}
}//Parent
孩子,
package Dump;
public class Child extends Parent {
private String childOnly;
public String getChildOnly() {
return childOnly;
}
public void setChildOnly(String childOnly) {
this.childOnly = childOnly;
}
public static void main(String [] args){
System.out.println("Testing...");
Child c1 = new Child();
c1.setChildOnly("childOnly");
c1.setNotReallyHidden("notReallyHidden");
//Attempting to access parent's reallyHidden
c1.reallyHidden;//Does not even compile
}//main
}//Child