2014-09-15 2 views
-1

В следующем коде, я не понимаю, почему, когда a1.k() называется, this.x в классе C возвращается 100 вместо 1. Я понимаю, что this относится к текущему объекту, но статический тип текущей переменной a1 является A. Так не должно this.x возвращает 1, что является переменной для типа A? Я имею в виду a1.x должен вернуть 1, правильно? Большое спасибо!подкласс и ключевое слово это в Java

class A { 
    public int x = 1; 
    public String k() { return "A" + this.x; } 
} 
class B extends A { 
    public int x = 10; 
    ... 
} 
class C extends B { 
    public int x = 100; 
    public String k() { return "C" + this.x; } 
} 
class TestABC { 
    public static void main(String[] args) { 
     A a1 = new C(); 
     C c1 = new C(); 
     System.out.println(a1.k()); 
    } 
} 
+0

Нет такой вещи, как статический тип объекта. То, о чем вы говорите, это статический тип переменной или просто тип выражения. –

+0

'a1' не должен иметь метод' k() ', во время компиляции его тип' A' правильный? Также 'x' из класса' C', вероятно, переопределяет 'x' как из' A', так и 'B'. –

+0

Извините, ребята, да, я имею в виду, что статический тип переменной a1 равен A. Также я редактировал вопрос, изначально я оставил метод k() в классе A. Итак, да k() в классе C переопределяет суперкласс k (). Но меня смущает то, что почему a1.k() возвращает 100, когда статический тип a1 равен A. – user3735871

ответ

1

Когда вы вызываете a1.k(), вы динамически отправляете метод k, который определяется фактическим объектом, ссылка которого находится в a1. В этом случае это C не A или B, и, следовательно, метод k является переопределением, определенным в C.

Статический тип (из a1 например) используется для статического разрешения; например разрешая методы static, сигнатуры перегрузки и поля. Но, например, вызов метода, конечный выбор метода для вызова является динамическим.

Я знаю, что k() в классе C следует вызывать, а не k() в классе A. Но почему this.x возвращает 100? Я думал, что переменная экземпляра ограничена статическим типом.

Ну, это так. Но именно статический тип определяет, какой x используется this.x в звонке k() является статическим типом thisв способе C.k тело!

+0

Спасибо! Теперь это начинает иметь смысл. Но a1.x все равно должен вернуть 1, как в классе A? – user3735871

+0

Предполагая, что статический тип 'a1' равен' A', тогда да. –

1

Эта функция называется динамическим полиморфизмом. Вызываемые методы не зависят от типа его объявления, а от типа, которому он назначен (определение).

Для этого классы должны наследовать и также переопределять методы в родительском классе.

Здесь C, B расширяет A и переопределяет метод k;

Если вы попытаетесь вызвать некоторые специальные методы или переменные C, это вызовет ошибку. (Так как не знает об этом)

А держит ссылку на C (указывает на С)

a1.k фактически C построен объект и его новый C(). К() где х 100 в С.

class Base{ 
    int x=10; 
    public int getx(){return x;} 
} 

class Sub extends Base{ 
    int x=100; 
    public int getx(){return x;} 
} 

class Test 
{ 
    public static void main (String[] args) 
    { 
     Base b = new Base(); 
     Sub s = new Sub(); 
     System.out.println("sub: getx:"+s.getx()+" .x:"+s.x+" Class: "+s.getClass().getName()); 
     System.out.println("base: getx:"+b.getx()+" .x:"+b.x+" Class: "+b.getClass().getName()); 
     Base btoS = new Sub(); 
     System.out.println("btos: getx"+btoS.getx()+" .x:"+btoS.x+" Class: "+btoS.getClass().getName()); 
    } 
} 

Результаты в

sub: getx:100 .x:100 Class: Sub 
base: getx:10 .x:10 Class: Base 
btos: getx100 .x:10 Class: Sub 
+0

Спасибо! Я знаю, что k() в классе C следует вызывать, а не k() в классе A. Но почему this.x возвращает 100? Я думал, что переменная экземпляра ограничена статическим типом. – user3735871

0

поскольку вы объявляете a1, как new C(), a1 будет рассматриваться как объект instanc e класса C, который переопределяет поля своего родительского класса B и A. Итак, почему вы делали бы такие вещи, как (или вы можете увидеть много таких реализаций), есть рекомендация «программирование для интерфейса, а не фактическая реализация». Я думаю, что this лучше объясняет.

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