2013-06-10 3 views
0

Просто путайте, как правильно ответить.Полиморфизм - Простой

class Cat { 
    public void isClawedBy(Cat c){ 
     System.out.println("Clawed by a cat"); 
    } 
} 

class Kitten extends Cat{ 
    public void isClawedBy(Kitten c){ 
     System.out.println("Clawed by a Kit"); 
    } 
} 

Если следующий называются

Cat g = new Cat(); 
Cat s = new Kitten(); 
Kitten t = new Kitten(); 

g.isClawedBy(t); 
s.isClawedBy(t); 
t.isClawedBy(t); 

Как ответ: когтистого по Cat когтистого по Cat когтистого по Котенок

Я смущен о том, почему s.isClawedBy (t) = когтистая по Cat. Поскольку динамический тип s - котенок, а t - котенок. Это потому, что аргументы разные, поэтому он не отменяет его?

Другая информация, которую я смущен. // Обратите внимание, что аргументы были заменены.

class Cat { 
    public void isClawedBy(Kitten c){ 
     System.out.println("Clawed by a cat"); 
    } 
} 

class Kitten extends Cat{ 
    public void isClawedBy(Cat c){ 
     System.out.println("Clawed by a Kit"); 
    } 
} 

Если следующее называется

Cat g = new Cat(); 
Cat s = new Kitten(); 
Kitten t = new Kitten(); 

g.isClawedBy(t); 
s.isClawedBy(t); 
t.isClawedBy(t); 

Выход: когтистой по Cat когтистой по Cat когтистой по Cat

Как это работает, когда т называется?

ответ

3

О втором запросе: t.isClawedBy(t) с выходом Clawed by Cat.

t Поскольку это Kitten и аргумент, передаваемый в метод t.isClawedBy(t) также Kitten, метод из суперкласса Cat будет называться, поскольку он соответствует аргументы прекрасно.

+0

Если вместо этого было 't.isClawedBy (g);' g типа типа Cat. Тогда это будет когтировано киттом? – user2469515

+0

Исправить. Тогда будет вызван метод с аргументом 'Cat', поэтому вывод будет _Clawed by Kit_ – aksh1t

0

Класс котенка не отменяет isClawedBy(Cat c). Он добавляет новый метод isClawedBy(Kitten c). Время выполнения видит s, на который ссылается Cat, в то время вызывается s.isClawedBy(t), и он заканчивается вызовом метода Cat.

Если вы измените Котик:

class Kitten extends Cat{ 
@Override 
    public void isClawedBy(Cat c){ 
    System.out.println("Clawed by a Kit"); 
    } 
} 

Тогда вы увидите вывод, который вы хотите. Еще интереснее, вы можете сделать:

((Kitten) s).isClawedBy(t); и вы увидите правильный метод.

+0

Значит, он использует статический тип во время выполнения? Таким образом, поскольку метод isClawedBy у котенка не отменяет вышеизложенного, он использует один в cat. – user2469515

+0

Для второй части, is t.isClawedBy (t) «Ищите метод isClawedBy (тип Kitten) в классе Kitten, но не находит его. Так выглядит суперкласс и находит его там? – user2469515

0

Я смущен тем, почему s.isClawedBy (t) = Когтистая кошка. Так как динамический тип s - котенок, а t - котенок.

s имеет ссылочный тип Cat, но содержит объект Kitten. t имеет ссылочный тип Kitten и содержит объект Kitten. Когда метод запускается во время выполнения, он сначала проверяется, если ссылочный тип имеет такой метод, а затем вызывается наиболее конкретная версия метода. Поскольку подкласс не переопределяет метод (разные типы в параметре), вызывается метод в ссылочном типе.

Для вашей второй части это то же самое происходит, нет перегрузки, и котенок действительно может быть передан как Cat к методу ссылочного типа, поэтому этот метод является наиболее конкретным в иерархии и это называется.

0

Что касается первого вопроса;

Переопределение разрешение делается во время выполнения, но перегружать разрешение сделано во время компиляции .
Поскольку подпись ваших методов не идентична (разные типы параметров. Не имеет значения, что это подкласс другого), они перегружены.

С момента разрешения во время компиляции компилятор не знает, что такое тип экземпляра; только объявленный тип.
К компилятору s.isClawedBy(t) относится к способу isClawedBy(Kitten) от , заявленному типуCat.
Компилятор говорит: «Да, Кошка может принять котенка в его методе, вот что это за метод».
Итак, во время выполнения какой метод, который будет вызывать, УЖЕ был выбран компилятором. Поиск не выполняется во время выполнения.

Таким образом, во время выполнения, несмотря на то, что s фактически является объектом Kitten, вызывается метод Cat.

+0

. Я так понимаю, вы тоже собираетесь сдать экзамен на это;) –

+0

Спасибо за ответ. И yup через пару дней хаха – user2469515