2015-09-24 2 views
1

Я не совсем понимаю про процедуру расширения класса. Учитывая следующий фрагмент кода, почему вывод равен 32?Java-процедуры расширения абстрактного класса

class Rts { 
    public static void main(String[] args) { 
     System.out.println(zorg(new RtsC())); 
    } 

    static int zorg(RtsA x) { 
     return x.f()*10 + x.a; 
    } 
} 

abstract class RtsA { 
    int a = 2; 
    int f() { return a; } 
} 

class RtsB extends RtsA { 
    int a = 3; 
    int f() { return a; } 
} 

class RtsC extends RtsB { 
    int a = 4; 
} 

ответ

3

Во-первых, поля не переопределен, так что все это эквивалентно

public class Rts { 
    public static void main(String[] args) { 
     System.out.println(zorg(new RtsC())); 
    } 
    static int zorg(RtsA x) { 
     return x.f()*10 + x.a; 
    } 
} 

abstract class RtsA { 
    int a = 2; 
    int f() { return a; } 
} 
class RtsB extends RtsA { 
    int b = 3; 
    int f() { return b; } 
} 
class RtsC extends RtsB { 
    int c = 4; 
} 

Реализация f() для объекта типа RtsC происходит от RtsB, так как это самый низкий уровень, класс, который переопределяет f(), поэтому его реализация используется и возвращает b, что составляет 3. Это умножается на 10, а затем добавляется к a от RtsA, так как zorg знает только, что x имеет тип RtsA, так что используется поле. Это 3 * 10 + 2 = 32.

(Обратите внимание, что тот факт, что RtsA абстрактна не пришли в это вообще,., Которые в основном только те вопросы, если у вас есть абстрактные методы, чтобы беспокоиться о)

+0

Понял. Так ясно. Спасибо – codemonkey

+0

У меня есть еще один вопрос об этом. Поскольку я вызываю zorg (новый RtsC()) в своей основной функции, как вы сказали, zorg знает только, что x имеет тип RtsA, как мы используем этот x для вызова f()? Мое понимание - это задача RtsC upcast для RtsA автоматически. Confused – codemonkey

+0

Если вы переопределите метод в подклассе, его всегда вызывает метод переопределения, вызываемый. –

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