未覆盖的方法不显示子类字段

时间:2016-11-30 14:22:38

标签: java inheritance

class Parent {
    String st = "external";

    void print() {
        System.out.println(st); 
        System.out.println(this.st);
    }
}

class Child extends Parent {
    String st = "inner";
}

public static void main(String[] args) {
    new Child().print(); // shows "external"
}

为什么调用子类的print()不显示字符串" inner"?

4 个答案:

答案 0 :(得分:2)

  

为什么在子类上调用的print()不显示字符串 - “内部”?

因为无法覆盖成员变量。类st中的成员变量Child不会覆盖类st中的成员变量Parent。两个成员变量是两个独立的变量,它们碰巧具有相同的名称。

Parent中的方法看到类st中定义的成员变量Parent,而不是类Child中的那个,即使对象确实是类Child的实例。

只能覆盖方法。

Oracle Java教程中的更多信息:Hiding Fields(感谢@JonK)。

答案 1 :(得分:1)

正如其他人提到的那样,隐藏了st类的字段Parent。如果你想要它打印“内部”,只需添加一个。

Child课改为:

class Child extends Parent {
    public Child() {
        st = "inner";
    }
}

这样,来自st类的Parent的值被覆盖!

答案 2 :(得分:0)

  

为什么在子类上调用的print()不显示字符串 - "内部" ?

为什么要这样?你正在调用只在父类中覆盖的方法print(),在父类中,st只保存值" 外部"

答案 3 :(得分:0)

其他答案涵盖了您注意到的行为的原因,因此我不会涉及到这一点。就你的问题的解决方案而言,有一些值得一提(忽略了诸如反射和子类投射之类的东西;技术上的解决方案,但是很差的解决方案。)

选项1:设置参数

如上所述,只需在Child:

中设置参数即可
class Child extends Parent{
    public Child() {
        st = "inner";
    }
}

选项2:方法覆盖

也可以覆盖print()方法(因为,如上所述,只能覆盖方法)。 Child会变成以下内容:

class Child extends Parent{
    ...

    @Override
    void print() {
        // Child-specific implementation here.
    }
}

这将导致Child个对象使用其print方法代替Parent的方法。

选项3:战略模式

另一种选择是使用策略模式。请考虑以下事项:

public interface Strategy {
    String getString();
}

public class ParentStrategy implements Strategy {
    @Override
    public String getString() {
        return "external";
    }
}

public class ChildStrategy implements Strategy {
    @Override
    public String getString() {
        return "inner";
    }   
}

从这里,您需要做的就是更改您的Parent对象,使其默认为ParentStrategy,提供更改策略的访问者,更改其print方法以使用其Strategy对象的getString()方法,以及更改策略在Child中使用ChildStrategy:

class Parent{
    Strategy strat = new ParentStrategy();

    void setStrategy(Strategy s) {
        strat = s;
    }

    void print() {
        System.out.println(strat.getString()); 
    }
}
class Child extends Parent{
    public Child() {
        super();
        setStrategy(new ChildStrategy());
    }
}

在实际应用中,此模式是制作灵活应用程序的基本工具。