Java 子类继承私有字段吗?

Java 子类继承私有字段吗?,java,oop,inheritance,private,Java,Oop,Inheritance,Private,这是一个面试问题 子类继承私有类吗 田地 我回答“不”,因为我们不能用“正常的OOP方式”访问它们。但是采访者认为它们是遗传的,因为我们可以间接地或使用反射访问这些字段,并且它们仍然存在于对象中 回来后,我在网站上找到了以下引语: 超类中的私有成员 A 子类不继承私有类 其父类的成员 你知道面试官的观点有什么依据吗?这取决于你对“继承”的定义。子类的内存中是否仍有字段?肯定它能直接访问它们吗?不,这只是定义的微妙之处;关键是要了解到底发生了什么。不,他们不会继承它 事实上,其他一些类可能会间接地

这是一个面试问题

子类继承私有类吗 田地

我回答“不”,因为我们不能用“正常的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.

    }

}