【问题标题】:Why is my value null when calling superclass method from subclass?为什么从子类调用超类方法时我的值为 null?
【发布时间】:2020-02-14 22:53:26
【问题描述】:

我正在使用 Java 和 Android Studio IDE。我试图从它的子类调用父类中的方法。我写了一个小测试例程,但我只得到一个空结果。

在我的主项目中,我有父对象/类和子对象/类,我想从子类/对象调用的父对象/类中获取一个值。 (房屋对象由墙对象组成,我的墙对象试图获取房屋类中指定的“墙类型”。但下面是我正在使用的一个小例子。

我已经尝试搜索这个问题,但是多次阅读其他人的代码只会让这个问题让我更加困惑。我一定是误解了这应该如何工作。

我尝试重写获取数据的方式,方法是调用 super.getMethod() 或覆盖父方法。我也尝试过将我的变量/方法设置为公共/私有和受保护的,但一无所获。

我的家长班:

public class Parent {
    protected String myName;
    protected Child parentsChild;

    public Parent() {}

    public Parent (String myName, Child parentsChild) {
        this.myName = myName;
        this.parentsChild = parentsChild;
    }

    public String getMyName() {
        return this.myName;
    }

    public void setMyName(String myName) {
        this.myName = myName;
    }

    public Child getParentsChild() {
        return this.parentsChild;
    }

    public void setParentsChild(Child parentsChild) {
        this.parentsChild = parentsChild;
    }
}

我的孩子班:

public class Child extends Parent {
    String childName;

    public Child() {

    }

    public Child(String childName) {
        this.childName = childName;
    }

    public String getChildName() {
        return childName;
    }

    public void setChildName(String childName) {
        this.childName = childName;
    }

    public String getParentName() {
        return super.getMyName();
    }

    @Override
    public String getMyName() {
        return super.getMyName();
    }
}

我的主要活动:


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        Child child = new Child("Logan");

        Parent parent = new Parent("Karrie", child);

        System.out.println("Parent: My name is " + parent.getMyName());
        System.out.println("Child: My parent's name is " + child.getParentName());
        System.out.println("@Override-> Child: My Parent's name is " + child.getMyName());
    }
}

我希望在使用“Karrie”构造父类时检索父类的名称。相反,我只得到“空”。多么可怜的孩子啊! :-(

这是我的日志:

2019-10-17 20:25:36.594 27040-27040/com.example.android.superclassinheritancetesting I/System.out: Parent: My name is Karrie
2019-10-17 20:25:36.594 27040-27040/com.example.android.superclassinheritancetesting I/System.out: Child: My parent's name is null
2019-10-17 20:25:36.594 27040-27040/com.example.android.superclassinheritancetesting I/System.out: @Override-> Child: My Parent's name is null

感谢您的帮助! :]

【问题讨论】:

  • 您的子构造函数永远不会调用传入父名称的超级构造函数,您也不会在 onCreate 中的任何位置显式设置父名称。这里没有惊喜。
  • 我会尝试调试——答案很清楚。您扩展了父级(忽略子类型在这里没有意义),但您从未设置 myName。这将更好地表示为一个单一的类,有一个孩子的列表,询问哪些只是一个人。
  • "这里的父母清楚地知道自己的名字"???父母只会得到传递给它的东西,不多也不少。如果你的真实代码反映了这段代码,那么请再次阅读我的第一条评论,看看为什么你的上述假设根本上是错误的。
  • 为什么Child 扩展Parent?如果有的话,它应该是相反的。父母永远是别人的孩子,但孩子可能永远也不会成为父母。
  • 你得到 null 是因为你从来没有设置过它,正如@HovercraftFullOfEels 已经告诉你好几次了。

标签: java object subclass superclass


【解决方案1】:

正如其他人所说,这里使用继承可能不是实现所需功能的正确方法。参考 java 教程肯定会帮助您理解继承并将其与组合或聚合区分开来。您的示例同时使用两者,因此初学者很难掌握这些概念。如果您仍然对层次关系(父/子,而不是超/子类)感兴趣,请查看此接口及其在 JDK 中的实现。有一些方法可以在层次结构中获取父对象和子对象。 https://docs.oracle.com/javase/8/docs/api/javax/swing/tree/TreeNode.html

【讨论】:

  • 绝对。我误解了整个概念。现在,在阅读了它之后,我通常对能够从内部类或对象访问外部类方法更感兴趣。我实际上没有要求将类继承与我试图做的事情一起使用。从其他成员那里得到一些好的指点后,我意识到我需要做什么。 :-) 我会检查一下。谢谢!我很高兴能继续学习新的方法和概念并继续前进。
【解决方案2】:

这是因为您在父级中添加子值的方式。

您需要通过子类构造函数传递这些值。我建议您在 Parent 中创建其他构造,在该构造中您只能接收 myName 属性,并且在 Child 类中,您将 myName (parentName) 传递给 Parent 使用超级,就像您在 get 方法中使用的一样。可以这样做:

Parent中添加(或更改)一个新结构:

public Parent (String myName) {
   this.myName = myName;
}

儿童中:

public Child(String childName, String parentName) {
    super(parentName)
    this.childName = childName;
}

而在 onCreate 方法中,您只需要创建一个子实例,如下所示:

Child child = new Child("Logan", "Karrie"); 

这样,Parent类就不需要知道和包含Child类变量了。

【讨论】:

    【解决方案3】:

    正如 cmets 中所指出的,在这种情况下,继承可能不是正确的方法。

    您可以定义一个Node 类来对关系建模。

    class Node {
    
      String name;
      Node parent;
    
      public Node(String name) {
        this.name = name;
      }
    
      public Node(String name, Node parent) {
        this.name = name;
        this.parent = parent;
      }
    
      public String getParentName() {
        return this.parent != null ? this.parent.name : null;
      }
    
    }
    

    然后在您的客户端代码中:

    Node parent = new Node("ParentName");
    Node child = new Node("ChildName", parent)
    System.out.println(child.getParentName());
    

    【讨论】:

    • 天哪,那我可能完全走错了方向。我有十几个不同的类以这种方式建立在彼此之上。我正在尝试建模一个屏幕外壳,在我的逻辑中它是父级。然后 ScreenEnclosure 类有“墙壁和屋顶类”作为孩子(和其他一些),作为回报,每个人都有“屋顶和墙壁部分”作为孩子,最终我有一个“屏幕面板类”,它将测量定义为宽度、高度、屏幕类型等。墙由 x 个墙段组成,其中由 x 个屏幕面板组成。
    • 您所描述的关系似乎是has-a,而不是is-a。如果 Wall 不是真正的一种 ScreenEnclosure,那么在建模该关系时继承将没有帮助。我建议查看Java's Object-Oriented Programming Concepts 以确定继承是否适合您的问题。
    • 你是对的。只有一个实例是我试图在我的整个代码中继承某些东西(感谢上帝),而且它似乎对于我想要完成的事情根本没有任何意义。起初我认为这是有道理的,但我需要更多地阅读这个主题。到目前为止,只有几个月的旅程。感谢您的帮助
    • 我认为我真正的问题不是继承,而是从内部类到外部类的访问,但我现在正在阅读相关内容。 (我想我可能混淆了这些东西)是的,我只能重申我还有很多东西要学。
    • 没问题。祝你好运!如果这回答了您的原始问题,请考虑接受答案。 :)
    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-07-17
    • 2017-10-31
    • 1970-01-01
    • 2023-03-05
    • 2015-06-19
    • 2011-10-24
    相关资源
    最近更新 更多