子类型重写方法中的Java超级方法调用

子类型重写方法中的Java超级方法调用,java,super,overriding,subtyping,Java,Super,Overriding,Subtyping,有人能解释一下为什么如果我运行这个代码,输出是[4,2]:null而不是[4,2]:purple吗? 我的理解是,问题在于超类中的toString方法。 事实上,如果我在超类中删除toString的“final”并编写一个toString方法,如 public String toString() { return this.makeName(); } 在子类中,所有工作正常。 但我真的不明白这背后的概念。 关于这件事有什么值得一读的吗 谢谢你抽出时间 publ

有人能解释一下为什么如果我运行这个代码,输出是[4,2]:null而不是[4,2]:purple吗? 我的理解是,问题在于超类中的toString方法。 事实上,如果我在超类中删除toString的“final”并编写一个toString方法,如

    public String toString() {
        return this.makeName();
    } 
在子类中,所有工作正常。 但我真的不明白这背后的概念。 关于这件事有什么值得一读的吗

谢谢你抽出时间

public class Point { 
    protected final int x, y;
    private final String name;

    public Point(int x, int y) { 
        this.x = x;
        this.y = y;
        name = makeName();
    }
    protected String makeName() { 
        return "["+x+", "+y+"]";
    }
    public final String toString(){ 
        return name;
    } 
}
ColorPoint.java:

public class ColorPoint extends Point { 
    private final String color;

    public ColorPoint(int x,int y, String color) { 
        super(x, y);
        this.color = color;
    }
    protected String makeName() {
        return super.makeName() + ":" + color;
    }
    public static void main(String[] args) { 
        System.out.println(new ColorPoint(4, 2, "purple"));
    } 
}
当您这样做时:

super(x,y)

它调用超类的构造函数,从而调用
makeName()
方法(由于行
name=makeName();

因为您在子类中重新定义了它,所以它调用了它,但此时并没有定义颜色

因此
返回super.makeName()+“:”+颜色
相当于
返回super.makeName()+“:”+null

因此,执行流程等效于以下内容(简化):

方法返回变量
name
的值。此变量在超类的构造函数中通过调用重写的方法
makeName()
填充

此时,子类的变量
color
尚未填充,因此它正确返回
[4,2]:null

在将值赋给color之前调用super(int,int),因此在color有值之前调用makeName(),因此:null

new ColorPoint(4, 2, "purple") //<-- creating ColorPoint object
super(x, y); //<-- super call
this.x = 4; 
this.y = 2;
name = makeName(); //<-- call makeName() in your ColorPoint class
return super.makeName() + ":" + color; //<-- here color isn't defined yet so it's null
name = "[4, 2]:null";
color = "purple";
/***/
print [4, 2]:null in the console //you call the toString() method, since it returns name you get the following output
class Point { 
    protected final int x, y;

    public Point(int x, int y) { 
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() { 
        return "["+x+", "+y+"]";
    }
}

class ColorPoint extends Point { 
    private final String color;

    public ColorPoint(int x,int y, String color) { 
        super(x, y);
        this.color = color;
    }

    @Override
    public String toString() {
        return super.toString() + ":" + color;
    }
}