在java中的继承上下文中通过对象调用类成员时会发生啥

Posted

技术标签:

【中文标题】在java中的继承上下文中通过对象调用类成员时会发生啥【英文标题】:what happens when calling a class member via an object in the context of inheritance in java在java中的继承上下文中通过对象调用类成员时会发生什么 【发布时间】:2018-09-11 16:48:11 【问题描述】:

编辑:它不是重复的:我已经知道私有只能在类中访问,在类和子类中受保护,并且同一包中的其他类和公共在任何地方都可以访问,没有修饰符 = 仅包。这不是我要说的。我说的是从一个对象访问:object.var。 只需阅读示例并尝试自己了解编译器错误,仅凭这个简单的规则就无法做到。

在结束问题之前,确保你明白了,这不是一个简单的问题,如果你这么认为,你可能没有得到这个问题。

这是我的代码,我不明白 object.privateVar 和 object.protectedVar 在从不同类调用时的行为方式 在子类 A 中,我可以调用daughterBObject.protected,而在 java 文档中,它说只有当我们调用的类参与创建对象时,我们才能调用 object.protectedVar。

heritage.closefamilly.Mother:

package heritage.closefamilly;

import heritage.faraway.Auntie;

public class Mother 
    private int priv;
    protected int prot;
    public int pub;

    public Mother()
        priv = 1;
        prot = 5;
        pub = 10;
    

    public void testInheritance(Mother m, Daughter d, Auntie a)
        System.out.println(""+m.priv+m.prot+m.pub);
        System.out.println(""+d.priv+d.prot+d.pub); // d.priv compiler error
        System.out.println(""+a.priv+a.prot+a.pub);// a.priv compiler error
    

heritage.closefamilly.Daughter :

package heritage.closefamilly;

import heritage.faraway.Auntie;

public class Daughter extends Mother

    public void testInheritance(Mother m, Daughter d, Auntie a)
        System.out.println(""+m.priv+m.prot+m.pub); // m.priv compiler error
        System.out.println(""+d.priv+d.prot+d.pub); // d.priv compiler error why ? we are in daughter class !
        System.out.println(""+a.priv+a.prot+a.pub); // a.priv compiler error, why does a.prot compile while we are in daughter class, it doesn't extends auntie neither it is auntie's subclass .. Javadoc says Object.prot shouldn't work when class it is called in is not involed in creating Object
    

heritage.faraway.Auntie:

package heritage.faraway;

import heritage.closefamilly.Daughter;
import heritage.closefamilly.Mother;

public class Auntie extends Mother

    public void testInheritance(Mother m, Daughter d, Auntie a)
        System.out.println(""+m.priv+m.prot+m.pub);// m.priv & m.prot compiler error
        System.out.println(""+d.priv+d.prot+d.pub); // d.priv & d.prot compiler error javadoc says " it is not involved in the implementation of mother and daughter"
        System.out.println(""+a.priv+a.prot+a.pub); // a.priv compiler error whY? we are in auntie class
    

谁能向我解释这些行为?

【问题讨论】:

d.priv - priv 变量在 Daughter 类中不是。它在母亲类中 In Java, difference between package private, public, protected, and private的可能重复 docs.oracle.com/javase/tutorial/java/IandI/subclasses.html 学习这个 关于您的编辑:您的示例的行为与人们期望它们的行为完全相同。我不确定你不明白哪一部分。例如,Mother 有一个私有变量“priv”。女儿无法访问它,因为它是私有的,因此访问 d.priv 将永远无法工作。这是你难以理解的部分吗? 例如:a.prot 在 Daughter 类中有效!可女儿不给阿姨送,阿姨也不给女儿送。而且女儿和阿姨不在同一个包裹里……你怎么解释? 【参考方案1】:

首先,子类不继承其父类的私有成员,这意味着 Daughter 类实际上不包含priv。为了使其工作,您需要在 Mother 类中指定一个通常称为(在此用例中)getPriv() 的公共/受保护方法。在该方法中,您返回priv,以便子类可以相应地使用该变量。

其次,在子类中实现方法testInheritance没有意义,因为它与在Mother类中基本相同。如果您要在子类中更改此方法,以便它们根据其功能提供不同的实现,那么这将是有意义的。在这种情况下,您需要使用注解@Override

我认为这将是您从理论上理解继承的整个概念的好读物:https://beginnersbook.com/2013/03/oops-in-java-encapsulation-inheritance-polymorphism-abstraction/

【讨论】:

这正是我已经知道的。我忘记@override 不好,但它并没有改变任何一件事。编译器仍然会出现同样的错误。如果我为 priv 设置了一个 getter,这意味着 priv 实际上在子类中,并且这些子类确实包含 priv。但是让我们假设您所说的完全正确,那么为什么 m.priv 只能在 Mother 类中编译?关于受保护?只是试着去想它,你不会明白它的行为方式。在所有类中写入相同的 testInheritance 背后的要点是,我们可以从 IDE 中看到编译器无法编译的位置。试试吧 a.prot 在 Daughter 类中有效!可女儿不给阿姨送,阿姨也不给女儿送。而且女儿和阿姨不在同一个包裹里。上面发布的所有链接都没有假设我不知道 java 基础知识可以解决这个问题。让我们假设这个问题并不那么容易,并且是一个真正的问题 如果要在子类中调用m.priv,需要使用super。这是您可以从上层类访问变量的唯一方法。这里的问题是您指定为私有的标识符,这意味着除非您使用 getter 方法,否则子类将没有 priv。确切地说,getter 方法允许子类在其中包含 priv 变量,因为 getter 是公共的。 Daughter 类中的 a.prot 有效,因为阿姨和女儿都是母亲的孩子,所以它们继承了完全相同的值。 这里的包根本不相关,因为你从不使用默认标识符(基本上只是给它没有标识符的数据类型)。

以上是关于在java中的继承上下文中通过对象调用类成员时会发生啥的主要内容,如果未能解决你的问题,请参考以下文章

java中,当实例化子类时会递归调用父类中的构造方法。这个说法对么?为啥

java中私有的属性、静态成员可以被子类继承吗?

关于java的this继承多态的理解

java面向对象特征

Java面向对象_继承思想——子类初始化过程

Java 子类继承父类成员中的问题