Java 子类继承私有字段吗?
这是一个面试问题 子类继承私有类吗 田地 我回答“不”,因为我们不能用“正常的OOP方式”访问它们。但是采访者认为它们是遗传的,因为我们可以间接地或使用反射访问这些字段,并且它们仍然存在于对象中 回来后,我在网站上找到了以下引语: 超类中的私有成员 A 子类不继承私有类 其父类的成员Java 子类继承私有字段吗?,java,oop,inheritance,private,Java,Oop,Inheritance,Private,这是一个面试问题 子类继承私有类吗 田地 我回答“不”,因为我们不能用“正常的OOP方式”访问它们。但是采访者认为它们是遗传的,因为我们可以间接地或使用反射访问这些字段,并且它们仍然存在于对象中 回来后,我在网站上找到了以下引语: 超类中的私有成员 A 子类不继承私有类 其父类的成员 你知道面试官的观点有什么依据吗?这取决于你对“继承”的定义。子类的内存中是否仍有字段?肯定它能直接访问它们吗?不,这只是定义的微妙之处;关键是要了解到底发生了什么。不,他们不会继承它 事实上,其他一些类可能会间接地
你知道面试官的观点有什么依据吗?这取决于你对“继承”的定义。子类的内存中是否仍有字段?肯定它能直接访问它们吗?不,这只是定义的微妙之处;关键是要了解到底发生了什么。不,他们不会继承它 事实上,其他一些类可能会间接地使用它,这与继承无关,而与封装有关 例如:
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?
}
}
您还可以通过反射获取count
内部UseIt
的值。这并不意味着你继承了它
更新
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
即使值存在,它也不会被子类继承
例如,定义为以下内容的子类:
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?
}
}
这与第一个示例的情况完全相同。属性count
是隐藏的,子类根本不会继承它。尽管如此,正如DigitalRoss指出的,价值是存在的,但不是通过继承的方式
这样说吧。如果你父亲很富有,给了你一张信用卡,你仍然可以用他的钱买东西,但这并不意味着你继承了所有的钱,是吗
其他更新
虽然很有趣
坦率地说,我没有确切的术语来描述它,但加载“非继承”父定义的也是JVM及其工作方式
我们实际上可以更改父类,子类仍然可以工作
:
我想这里可以找到确切的术语:不。私有字段不是继承的。。。这就是为什么保护被发明的原因。这是故意的。我想这证明了受保护修饰语的存在
import java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {
}
public int a=32131,b,c;
private int bhavesh=5555,rr,weq,refw;
}
现在来谈谈上下文。您所说的继承是什么意思——如果它存在于从派生类创建的对象中?是的 若你们的意思是说,派生类是否有用。嗯,没有 现在,在函数式编程中,超类的私有字段对于子类来说并不是以有意义的方式继承的。对于子类,超类的私有字段与任何其他类的私有字段相同 在功能上,它不是继承的。但理想情况下,它是
好的,刚刚看了Java教程,他们引用了以下内容: 超类中的私有成员
子类不继承其父类的私有成员。但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法 参考: 我同意,这个领域是存在的。但是,子类在这个私有字段上没有任何特权。对于子类,私有字段与任何其他类的私有字段相同 我认为这纯粹是观点问题。你可以左右双方的论点。最好是两全其美 是 重要的是要认识到,虽然有两个类,但只有一个对象 所以,是的,它当然继承了私有字段。据推测,它们对于适当的对象功能是必不可少的,虽然父类的对象不是派生类的对象,但派生类的实例基本上肯定是父类的实例。如果没有所有的领域,这不太可能 不,您不能直接访问它们。是的,它们是遗传的。他们一定是 这是个好问题
更新: 呃,“不” 我想我们都学到了一些东西。由于“不继承”的措辞是准确的,因此回答“不”是正确的。由于子类不能访问或修改私有字段,因此,换句话说,它们不会被继承。但是实际上只有一个对象,它确实包含私有字段,因此如果有人错误地理解JLS和教程的措辞,那么很难理解OOP、Java对象以及真正发生的事情 更新到更新:
这里的争论涉及到一个基本的模糊性:到底讨论了什么?目标是什么?或者我们是在某种意义上谈论课堂本身?当描述类而不是对象时,允许有很大的自由度。因此,子类不继承私有字段,但作为子类实例的对象肯定包含私有字段。这里的问题/答案中的大部分混淆都围绕着继承的定义 显然,@DigitalRoss解释说,子类的对象必须包含其超类的私有字段。正如他所说,没有私人会员并不意味着没有私人会员 不过。这与类的继承概念不同。与java世界的情况一样,在java世界中存在语义问题,仲裁者是(目前为第3版) 正如JLS所述(): 声明的类的成员 私人财产不由继承人继承 该类的子类。只有成员 声明为受保护的类的 或public由子类继承 在包中声明,而不是 声明类的对象 这正好解决了面试官提出的问题:“子类继承私有字段吗?”。(重点由我补充) 答案是否定的,他们没有。
public class ParentClass {
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
class SubClass extends ParentClass {
private int y;
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void setXofParent(int x) {
setX(x);
}
}
class Main {
public static void main(String[] args) {
SubClass s = new SubClass();
s.setX(10);
s.setY(12);
System.out.println("X is :"+s.getX());
System.out.println("Y is :"+s.getY());
s.setXofParent(13);
System.out.println("Now X is :"+s.getX());
}
}
Output:
X is :10
Y is :12
Now X is :13
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
public class Foo {
private int x; // This is the private field.
public Foo() {
x = 0; // Sets int x to 0.
}
//The following methods are declared "final" so that they can't be overridden.
public final void update() { x++; } // Increments x by 1.
public final int getX() { return x; } // Returns the x value.
}
public class Bar extends Foo {
public Bar() {
super(); // Because this extends a class with a constructor, it is required to run before anything else.
update(); //Runs the inherited update() method twice
update();
System.out.println(getX()); // Prints the inherited "x" int.
}
}