Вместо A
s и B
s давайте перейдем к конкретному примеру.
class Person {
public void greet() {
System.out.println("Hello there!");
}
}
class ComputerScientist extends Person { // Does he, really?
@Override
public void greet() {
System.out.println("Hello there! I work at the Informatics Department.");
}
public void validateAlgorithm(Algorithm a)
throws InvalidAlgorithmException {
// ...
}
}
Когда у вас есть ComputerScientist
как
ComputerScientist cs = new ComputerScientist();
Вы можете получить доступ как к greet
, так и к validateAlgorithm
. Вы знаете, что он Person
, и можете greet
его/ее, как и любой другой человек. Однако вы также можете обращаться с ним/ней конкретно как с ComputerScientist
.
Когда вы присваиваете этот объект переменной типа Person
, все, что вы делаете, это говорите "Меня больше не волнует, что вы ComputerScientist
. Отныне я буду относиться к вам так же, как к любому другому Person
".
Person p = cs;
Что эквивалентно
Person p = (Person) cs;
Объект, на который ссылается p
, все еще знает, как validateAlgorithm
, и все еще говорит вам, что он (она) работает в отделе информатики. Однако при доступе к нему через p
вы сообщаете компилятору, что хотите только greet
это Person
, и ничего больше.
Это называется восходящим преобразованием, потому что переменная поднимается вверх в дереве иерархии, где вверх означает более общий/абстрактный и вниз означает более конкретный. Вы обобщаете ComputerScientist
как Person
.
person
afsantos
schedule
29.09.2013