子类会继承私有字段吗?

发布于 2024-10-12 04:07:57 字数 366 浏览 10 评论 0原文

这是一道面试题。

子类是否继承私有字段?

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

回来后,我在 javadoc

超类中的私人成员

子类不会继承父类的私有成员。

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

This is an interview question.

Do subclasses inherit private fields?

I answered "No", because we can't access them using the "normal OOP way". But the interviewer thinks that they are inherited, because we can access such fields indirectly or using reflection and they still exist in the object.

After I came back, I found the following quote in the javadoc:

Private Members in a Superclass

A subclass does not inherit the private members of its parent class.

Do you know any arguments for the interviewer's opinion?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

怕倦 2024-10-19 04:07:57

这里的问题/答案中的大部分混乱都围绕着继承的定义。

显然,正如DigitalRoss解释的,一个OBJECT 子类必须包含其超类的私有字段。正如他所说,无法访问私人成员并不意味着它不存在。

但是,这与类的继承概念不同。就像 Java 世界中的情况一样,存在语义问题,仲裁者是 Java 语言规范(当前为第三版)。

正如 JLS 所说(https:/ /docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):

声明为私有的类的成员不会被该类的子类继承。只有声明为 protected 或 public 的类的成员才会被在声明该类的包以外的包中声明的子类继承。

这解决了面试官提出的确切问题:“子类是否继承私有字段”。 (强调是我添加的)

答案是否定的。他们没有。子类的对象包含其超类的私有字段。子类本身没有其超类的私有字段的概念。

这是迂腐的语义吗?是的。这是一个有用的面试问题吗?可能不会。但 JLS 为 Java 世界建立了定义,并且(在本例中)明确地做到了这一点。

Most of the confusion in the question/answers here surrounds the definition of Inheritance.

Obviously, as DigitalRoss explains, an OBJECT of a subclass must contain its superclass's private fields. As he states, having no access to a private member doesn't mean its not there.

However, this is different than the notion of inheritance for a class. As is the case in the Java world, where there is a question of semantics the arbiter is the Java Language Specification (currently 3rd edition).

As the JLS states (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):

Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.

This addresses the exact question posed by the interviewer: "do subCLASSES inherit private fields". (emphasis added by me)

The answer is No. They do not. OBJECTS of subclasses contain private fields of their superclasses. The subclass itself has NO NOTION of private fields of its superclass.

Is it semantics of a pedantic nature? Yes. Is it a useful interview question? Probably not. But the JLS establishes the definition for the Java world, and it does so (in this case) unambiguously.

海螺姑娘 2024-10-19 04:07:57

是的

重要的是要认识到,虽然有两个类,但只有一个对象。

所以,是的,它当然继承了私有字段。据推测,它们对于正确的对象功能至关重要,虽然父类的对象不是派生类的对象,但派生类的实例大多肯定是父类的实例。如果没有所有字段,情况就不可能如此。

不,您无法直接访问它们。是的,它们是遗传的。他们必须是这样。

这是个好问题!


更新:

呃,“不”

好吧,我想我们都学到了一些东西。由于 JLS 起源了确切的“非继承”措辞,回答“否”是正确的。由于子类无法访问或修改私有字段,那么,换句话说,它们不是继承的。但实际上只是只有一个对象,它确实确实包含私有字段,因此如果有人以错误的方式理解JLS和教程措辞,理解 OOP、Java 对象以及真正发生的事情将是相当困难的。

更新更新:

这里的争议涉及一个根本性的歧义:到底正在讨论什么?对象?或者我们在某种意义上谈论的是类本身吗?在描述类而不是对象时,允许有很大的自由度。因此子类不会继承私有字段,但作为子类实例的对象肯定包含私有字段。

Yes

It's important to realize that while there are two classes, there is only one object.

So, yes, of course it inherited the private fields. They are, presumably, essential for proper object functionality, and while an object of the parent class is not an object of the derived class, an instance of the derived class is mostly definitely an instance of the parent class. It could't very well be that without all of the fields.

No, you can't directly access them. Yes, they are inherited. They have to be.

It's a good question!


Update:

Err, "No"

Well, I guess we all learned something. Since the JLS originated the exact "not inherited" wording, it is correct to answer "no". Since the subclass can't access or modify the private fields, then, in other words, they are not inherited. But there really is just one object, it really does contain the private fields, and so if someone takes the JLS and tutorial wording the wrong way, it will be quite difficult to understand OOP, Java objects, and what is really happening.

Update to update:

The controversy here involves a fundamental ambiguity: what exactly is being discussed? The object? Or are we talking in some sense about the class itself? A lot of latitude is allowed when describing the class as opposed to the object. So the subclass does not inherit private fields, but an object that is an instance of the subclass certainly does contain the private fields.

情释 2024-10-19 04:07:57

不。私有字段不会被继承……这就是发明 Protected 的原因。这是设计使然。我想这证明了 protected 修饰符的存在是合理的。


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

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

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

从功能上来说,它不是继承的。但理想,确实如此。


好吧,刚刚查看了 Java 教程,他们引用了以下内容:

超类中的私人成员

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

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

我同意,该字段就在那里。但是,子类在该私有字段上没有任何特权。对于子类,私有字段与任何其他类的任何私有字段相同。

我认为这纯粹是观点问题。你可以塑造任何一方的论点。最好双向证明。

 

No. Private fields are not inherited... and that's why Protected was invented. It is by design. I guess this justified the existence of protected modifier.


Now coming to the contexts. What you mean by inherited -- if it is there in the object created from derived class? yes, it is.

If you mean can it be useful to derived class. Well, no.

Now, when you come to functional programming the private field of super class is not inherited in a meaningful way for the subclass. For the subclass, a private field of super class is same as a private field of any other class.

Functionally, it's not inherited. But ideally, it is.


OK, just looked into Java tutorial they quote this:

Private Members in a Superclass

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

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

I agree, that the field is there. But, subclass does not get any privilege on that private field. To a subclass, the private field is same as any private field of any other class.

I believe it's purely matter of point-of-view. You may mould the argument either side. It's better justify both way.

 

对你而言 2024-10-19 04:07:57

这取决于你对“继承”的定义。子类内存中还有字段吗?确实。可以直接访问它们吗?不,这只是定义的微妙之处;重点是要了解到底发生了什么。

It depends on your definition of "inherit". Does the subclass still have the fields in memory? Definitely. Can it access them directly? No. It's just subtleties of the definition; the point is to understand what's really happening.

不…忘初心 2024-10-19 04:07:57

我将用代码演示这个概念。子类实际上继承超类的私有变量。唯一的问题是它们无法访问
子对象,除非您为私有变量提供公共 getter 和 setter
在超级班里。

考虑 Dump 包中的两个类。孩子扩展了父母。

如果我没记错的话,内存中的子对象由两个区域组成。一个仅是父部分,另一个仅是子部分。孩子可以访问私人空间
仅通过父级中的公共方法在其父级代码中包含部分。

这样想吧。波拉特的父亲博尔托克有一个装有 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

I will demonstrate the concept with code. Subclasses ACTUALLY inherit the private variables of super class. The only problem is that they are not accessible to the
child objects unless you provide public getters and setters for the private variables
in the super class.

Consider two class in package Dump. Child extends Parent.

If I remember correctly, a child object in memory consists of two regions. One is the parent part only and the other is the child part only. A child can access the private
section in the code of its parent only via a public method in the parent.

Think of it this way. Borat's father Boltok has a safe containing $100,000. He does not want to share his "private" variable safe. So, he does not provide a key for the safe. Borat inherits the safe. But, what good is it if he cannot even open it ? If only his
dad had provided the key.

Parent -

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

Child -

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
昵称有卵用 2024-10-19 04:07:57

不,他们不会继承它。

其他类可能间接使用它这一事实并没有说明继承,而是说明了封装。

例如:

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?           
     }
}

这与第一个示例的情况完全相同。属性 count 是隐藏的,并且子类根本继承。尽管如此,正如 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

我想可以在这里找到确切的术语:JavaTM 虚拟机规范

No. They don't inherit it.

The fact some other class may use it indirectly says nothing about inheritance, but about encapsulation.

For instance:

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?
     }
}

You can also get the value of count inside UseIt via reflection. It doesn't means, you inherit it.

UPDATE

Even though the value is there, it is not inherited by the subclass.

For instance a subclass defined as:

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?           
     }
}

This is exactly the same situation as the first example. The attribute count is hidden and not inherited by the subclass at all. Still, as DigitalRoss points out, the value is there, but not by means on inheritance.

Put it this way. If your father is wealthy and gives you a credit card, you can still buy thing with his money, but doesn't mean you have inherited all that money, does it?

Other update

It is very interesting though, to know why the attribute is there.

I frankly don't have the exact term to describe it, but it's the JVM and the way it works that loads also the "not inherited" parent definition.

We could actually change the parent and the subclass will still work.

For instance:

//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

I guess the exact term could be found here: The JavaTM Virtual Machine Specification

桃气十足 2024-10-19 04:07:57

好吧,我对面试官问题的回答是 - 私有成员不会在子类中继承,但只能通过公共 getter 或 setter 方法或原始类的任何此类适当方法来访问它们。通常的做法是保持成员私有并使用公共的 getter 和 setter 方法访问它们。那么,当对象无法使用 getter 和 setter 方法所处理的私有成员时,仅继承 getter 和 setter 方法有什么意义呢?这里的“继承”只是意味着它可以直接在子类中通过子类中新引入的方法来使用。

将以下文件保存为 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() 方法或最终调用 setX() 的 setXofParent() 方法来修改 x。所以这里 setX() 和 getX() 是通往 ParentClass 的私有成员 x 的某种门。

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

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.

Save the below file as ParentClass.java and try it yourself ->

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

If we try to use private variable x of ParentClass in SubClass's method then it is not directly accessible for any modifications (means not inherited). But x can be modified in SubClass via setX() method of original class as done in setXofParent() method OR it can be modified using ChildClass object using setX() method or setXofParent() method which ultimately calls setX(). So here setX() and getX() are kind of gates to the private member x of a ParentClass.

Another simple example is Clock superclass has hours and mins as private members and appropriate getter and setter methods as public. Then comes DigitalClock as a sub-class of Clock. Here if the DigitalClock's object doesn't contain hours and mins members then things are screwed up.

木森分化 2024-10-19 04:07:57

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

Ok, this is a very interesting problem I researched a lot and came to a conclusion that private members of a superclass are indeed available (but not accessible) in the subclass's objects. To prove this, here is a sample code with a parent class and a child class and I am writing child class object to a txt file and reading a private member named 'bhavesh' in the file, hence proving it is indeed available in the child class but not accessible due to the access modifier.

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) {
    }


}
}

Open MyData1.txt and search for the private member named 'bhavesh'. Please let me know what you guys think.

(り薆情海 2024-10-19 04:07:57

看起来子类确实继承了私有字段,因为这些字段在子类的内部工作中使用(从哲学上讲)。子类在其构造函数中调用超类构造函数。如果超类构造函数在其构造函数中初始化了这些字段,则超类私有字段显然会被调用超类构造函数的子类继承。这只是一个例子。但是,如果没有访问器方法,子类当然无法访问超类私有字段(这就像无法弹出 iPhone 的后面板以取出电池来重置手机......但电池仍然在那里)。

聚苯乙烯
我遇到过的继承的众多定义之一:
“继承——一种编程技术,允许派生类扩展基类的功能,继承其所有状态(重点是我的)和行为。”

私有字段即使不能被子类访问,也是超类的继承状态。

It would seem that a subclass does inherit the private fields in that these very fields are utilized in the inner workings of the subclass (philosophically speaking). A subclass, in its constructor, calls the superclass constructor. The superclass private fields are obviously inherited by the subclass calling the superclass constructor if the superclass constructor has initialized these fields in its constructor. That's just an example. But of course without accessor methods the subclass cannot access the superclass private fields (it's like not being able to pop the back panel of an iPhone to take the battery out to reset the phone... but the battery is still there).

PS
One of the many definitions of inheritance that I have come across:
"Inheritance -- a programming technique that allows a derived class to extend the functionality of a base class, inheriting all of its STATE (emphasis is mine) and behaviour."

The private fields, even if not accessible by the subclass, are the inherited state of the superclass.

只是我以为 2024-10-19 04:07:57

例如,

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);
    }
}

For example,

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);
    }
}
霓裳挽歌倾城醉 2024-10-19 04:07:57

内存布局在Java中相对继承

在此处输入图像描述

不考虑填充位/对齐以及在 VTABLE 中包含对象类。所以子类的对象确实有一个地方可以容纳超类的私有成员。但是,无法从子类的对象访问它......

Memory Layout in Java vis-a-vis inheritance

enter image description here

Padding bits/Alignment and the inclusion of Object Class in the VTABLE is not considered. So the object of the subclass does have a place for the private members of the Super class. However, it cannot be accessed from the subclass's objects...

夏の忆 2024-10-19 04:07:57

我不得不回答 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”,所以人们认为它不是继承的。然而,类中的每个非静态事物,无论是字段还是方法,都是继承的。

I would have to answer that private fields in Java are inherited. Allow me to demonstrate:

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.

    }

}

If you run in a program Bar bar = new Bar();, then you will always see the number "2" in the output box. Because the integer "x" is encapsulated with the methods update() and getX(), then it can be proven that the integer is inherited.

The confusion is that because you can't directly access the integer "x", then people argue that it isn't inherited. However, every non-static thing in a class, be it field or method, is inherited.

冷清清 2024-10-19 04:07:57

,私有字段不会被继承。唯一的原因是子类无法直接访问它们。

No, private fields are not inherited. The only reason is that subclass can not access them directly.

愛放△進行李 2024-10-19 04:07:57

正如其他人指出的 JLS 摘录:

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2

声明为私有的类的成员不会被继承
该类的子类。仅声明的类的成员
protected 或 public 由包中声明的子类继承
除了声明该类的类之外。

毫无疑问,答案是,没有任何不确定性。这围绕着继承的定义。根据定义,继承是针对类的,而不是针对对象的。对象是使用类定义创建的。继承只是添加到类定义中的另一个块。 那么,一个类是否继承了超类的任何私有成员?否

As others have pointed out exerpt from JLS:

https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2:

Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.

The answer is NO without a doubt, without any iffs and buts. That revolves around the definition of inheritance. By definition inheritance is for classes, not for objects. Objects are created using class definitions. Inheritance is just another block to add to definition of a class. So, does a class inherits any private member of super class? NO

蓦然回首 2024-10-19 04:07:57

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

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

如果我们查看访问说明符详细信息<,那么答案是 /a>,有人提到,私有成员只能在类本身内部访问。

但是,如果问题是

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

这意味着,您将如何访问私有成员并不重要。在这种情况下,我们可以在超类中创建公共方法,并且您可以访问私有成员。因此,在这种情况下,您将创建一个接口/桥来访问私有成员。

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

I believe, answer is totally dependent on the question, which has been asked. I mean, if question is

Can we directly access the private field of the super-class from
their sub-class ?

Then answer is No, if we go through the access specifier details, it is mentioned, private members are accessible only within the class itself.

But, if question is

Can we access the private field of the super-class from
their sub-class ?

Which means, it doesn't matters, what you will do to access the private member. In that case, we can make public method in the super-class and you can access the private member. So, in this case you are creating one interface/bridge to access the private member.

Other OOPs language like C++, have the friend function concept, by which we can access the private member of other class.

抱猫软卧 2024-10-19 04:07:57

我们可以简单地说,当超类被继承时,超类的私有成员实际上成为子类的私有成员,并且不能被进一步继承,也不能被子类的对象访问。

We can simply state that when a superclass is inherited, then the private members of superclass actually become private members of the subclass and cannot be further inherited or are inacessible to the objects of subclass.

走过海棠暮 2024-10-19 04:07:57

私有类成员或构造函数只能在顶级类的主体内访问(§7.6) 包含成员或构造函数的声明。它不被子类继承。 https://docs.oracle.com /javase/specs/jls/se7/html/jls-6.html#jls-6.6

A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6

云巢 2024-10-19 04:07:57

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


https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html#:~:text=Private%20Members%20in%20a%20Superclass,be%20used %20by%20the%20子类

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass

reference:
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html#:~:text=Private%20Members%20in%20a%20Superclass,be%20used%20by%20the%20subclass.

奶茶白久 2024-10-19 04:07:57

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

I can try to help you.
When a subclass(named B, for example) extends a superclass (named A, for example), it automatically inherits fields (such as attributes and/or methods) from its superclass.
Now, B in its Memory Layout has the space for every field in class A even the private ones. The fact is that Java doesn't allow the subclass B to use the private fields because they are private.

迷你仙 2024-10-19 04:07:57

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

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

我三岁 2024-10-19 04:07:57

私有成员(状态和行为)是继承的。它们(可以)影响类实例化的对象的行为和大小。更不用说通过所有可用的或可由其实现者假设的封装破坏机制,它们对于子类来说是非常明显的。

尽管继承有一个“事实上的”定义,但它绝对与“可见性”方面没有联系,而“可见性”方面是由“否”答案假设的。

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

任何认为它们不是“继承”的假设都是不安全和危险的。

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

Private members (state and behavior) are inherited. They (can) affect the behavior and size of the object which is instantiated by the class. Not to mention that they are very well visible to the subclasses via all the encaptulation-breaking mechanisms that are available, or can be assumed by their implementers.

Although inheritance has a "defacto" definition, it definitely has no link to "visibility" aspects, which get assumed by the "no" answers.

So, there is no need to be diplomatic. JLS is just wrong at this point.

Any assumption that they are not "inherited" is unsafe and dangerous.

So among two defacto (partially) conflicting definitions (which I will not repeat), the only one that should be followed is the one that is safer (or safe).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文