这是面试问题。

子类继承private吗 字段?

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

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

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

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


当前回答

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

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

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

但是,如果问题是

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

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

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

其他回答

不。私有字段没有被继承…所以我们才发明了"保护"这是有意为之。我想这证明了受保护修饰符的存在。


现在来看看上下文。继承是什么意思——如果它存在于从派生类创建的对象中?是的,它是。

如果你的意思是它是否对派生类有用。嗯,没有。

现在,当你进行函数式编程时,父类的私有字段不会以一种有意义的方式继承给子类。对于子类,超类的私有字段与任何其他类的私有字段相同。

在功能上,它不是遗传的。但理想情况是这样的。


好吧,刚刚看了一下Java教程,他们引用了这样的话:

超类中的私人成员 子类不继承父类的私有成员。但是,如果父类具有用于访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

参见:http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html

我同意,这个领域是存在的。但是,子类在私有字段上没有任何特权。对于子类,私有字段与任何其他类的私有字段相同。

我相信这只是个人观点的问题。你可以左右争论的任何一方。这两种方法都是合理的。

 

不。他们没有继承。

其他一些类可能间接使用它的事实不是关于继承,而是关于封装。

例如:

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虚拟机规范

好吧,这是一个非常有趣的问题,我研究了很多,得出的结论是,父类的私有成员确实在子类的对象中可用(但不可访问)。为了证明这一点,这里是一个带有父类和子类的示例代码,我正在将子类对象写入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”的私有成员。请告诉我你们的想法。

例如,

class Person {
    private String name;

    public String getName () {
        return this.name;
    }

    Person(String name) {
        this.name = name;
    }
}
public class Student extends Person {

    Student(String name) {
        super(name);
    }
    
    public String getStudentName() {
        return this.getName(); // works
        // "return this.name;" doesn't work, and the error is "The field Person.name is not visible"

    }
}

public class Main {
    public static void main(String[] args) {
        Student s = new Student("Bill");

        String name = s.getName(); // works
        // "String name = s.name;" doesn't work, and the error is "The field Person.name is not visible"

        System.out.println(name);
    }
}

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