这是面试问题。

子类继承private吗 字段?

我的回答是“不”,因为我们不能使用“正常的面向对象的方式”访问它们。但是采访者认为它们是继承的,因为我们可以间接或使用反射访问这些字段,并且它们仍然存在于对象中。

回来后,我在javadoc中找到了以下引用:

超类中的私人成员 一个 子类不继承私有 父类的成员。

你知道面试官观点的论据吗?


当前回答

我可以试着帮你。 当一个子类(例如命名为B)扩展一个超类(例如命名为a)时,它自动从它的超类继承字段(例如属性和/或方法)。 现在,B在它的内存布局中为类A中的每个字段提供了空间,包括私有字段。事实上,Java不允许子类B使用私有字段,因为它们是私有的。

其他回答

Well, my answer to interviewer's question is - Private members are not inherited in sub-classes but they are accessible to subclass or subclass's object only via public getter or setter methods or any such appropriate methods of original class. The normal practice is to keep the members private and access them using getter and setter methods which are public. So whats the point in only inheriting getter and setter methods when the private member they deal with are not available to the object? Here 'inherited' simply means it is available directly in the sub-class to play around by newly introduced methods in sub-class.

将下面的文件保存为ParentClass.java并自己尝试它->

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

如果我们尝试在子类的方法中使用ParentClass的私有变量x,那么它不能被任何修改直接访问(意味着不能继承)。但是x可以通过原始类的setX()方法在子类中修改,就像在setXofParent()方法中做的那样,或者可以使用ChildClass对象使用setX()方法或setXofParent()方法修改,最终调用setX()。这里setX()和getX()是一种通往ParentClass的私有成员x的门。

另一个简单的例子是Clock超类将hours和min作为私有成员,将适当的getter和setter方法作为公共方法。然后是数字时钟作为时钟的子类。在这里,如果DigitalClock的对象不包含hours和mins成员,那么事情就搞砸了。

我相信,答案完全取决于所提出的问题。我的意思是,如果问题是

我们可以直接访问超类的私有字段吗 他们的子类?

那么答案是否定的,如果我们查看访问说明符的细节,就会提到,私有成员只能在类本身内访问。

但是,如果问题是

我们可以访问超类的私有字段吗 他们的子类?

这意味着,访问私有成员的操作并不重要。在这种情况下,我们可以在超类中创建public方法,你可以访问private成员。因此,在本例中,您创建了一个接口/桥接器来访问私有成员。

其他oop语言,如c++,有友元函数的概念,通过它我们可以访问其他类的私有成员。

好吧,这是一个非常有趣的问题,我研究了很多,得出的结论是,父类的私有成员确实在子类的对象中可用(但不可访问)。为了证明这一点,这里是一个带有父类和子类的示例代码,我正在将子类对象写入txt文件,并在文件中读取名为“bhavesh”的私有成员,因此证明它确实在子类中可用,但由于访问修饰符而不可访问。

import java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {

}

public int a=32131,b,c;

private int bhavesh=5555,rr,weq,refw;
}

import java.io.*;
import java.io.Serializable;
public class ChildClass extends ParentClass{
public ChildClass() {
super();
}

public static void main(String[] args) {
ChildClass childObj = new ChildClass();
ObjectOutputStream oos;
try {
        oos = new ObjectOutputStream(new FileOutputStream("C:\\MyData1.txt"));
        oos.writeObject(childObj); //Writing child class object and not parent class object
        System.out.println("Writing complete !");
    } catch (IOException e) {
    }


}
}

打开MyData1.txt,搜索名为“bhavesh”的私有成员。请告诉我你们的想法。

私有成员(状态和行为)是继承的。它们(可以)影响类实例化的对象的行为和大小。更不用说,通过所有可用的封装破坏机制,或者它们的实现者可以假定,子类可以很好地看到它们。

虽然继承有一个“事实上的”定义,但它肯定与“可见性”方面没有联系,这是“不”答案所假设的。

所以,没有必要采取外交手段。JLS在这一点上是错误的。

任何认为他们不是“遗传”的假设都是不安全的和危险的。

因此,在两个事实上(部分)相互冲突的定义(我不会重复)中,唯一应该遵循的是更安全(或安全)的定义。

我必须回答,Java中的私有字段是继承的。请允许我演示一下:

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.

    }

}

如果你在一个程序中运行Bar Bar = new Bar();,那么你总是会在输出框中看到数字“2”。由于整数“x”被update()和getX()方法封装,因此可以证明该整数是继承的。

令人困惑的是,因为不能直接访问整数“x”,所以人们认为它不是继承的。然而,类中的每一个非静态的东西,无论是字段还是方法,都是继承的。