2013-11-24 2 views
1

может кто-нибудь объяснить мне, почему, если я запустил этот код, вывод будет [4, 2]: null, а не [4,2]: фиолетовый? Я понимаю, что проблема заключается в методе toString в суперклассе. На самом деле, если я удалить «окончательное» из ToString в SuperClass и написать метод ToString какJava вызов метода super в подтипированном переопределенном методе

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

ответ

3

Когда вы делаете:

super(x, y);

он вызывает конструктор своего суперкласса и, следовательно, makeName() метод (из-за линии name = makeName();).

Поскольку вы переопределили его в своем подклассе, он называет его, но цвет не определен в данный момент.

Следовательно return super.makeName() + ":" + color; эквивалентно return super.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; 
    } 
} 
0

Ваш метод toString() возвращает значение переменной name. Эта переменная заполняется во время конструктора вашего суперкласса, вызывая переопределенный метод makeName().

В это время, переменная color подкласса еще не заполнен, поэтому он правильно возвращает [4,2]:null

0

Вы называете супер (интермедиат, Int), прежде чем присваивать значение в цвет, так makeName() является вызывается перед цветом имеет значение, поэтому: null.

Смежные вопросы