Не пойму сужений-расширений.
Класс Animal - родительский. Когда мы добавляем ему класс Cat - он его "расширяет" - так пишут здесь, пишут в "Head first Java". И вот тут наступают противоречия с простой банальной логикой:
- класс Animal - это самый широкий класс, ведь он в себя вмещает всех животных. И класс Cat - это сужение класса. А пишут все как раз наоборот. Вероятно, так именно с точки зрения программистов, так как классу Cat доступны поля и методы класса Animal, а классу Animal не доступны поля и методы класса Cat.
- хорошо, класс Cat - расширение класса Animal. Но почему тогда он требует явного приведения переменной:
Animal animal = new Cat();
Cat cat = (Cat) animal?
Ну или пример из статьи:
Cow cow = new Whale(); //в лекции класс Whaleнаследует класс Cow
if (cow instanceof Whale)
{
Whale whale = (Whale) cow;
}
Если вспомнить примитивы, то если тип переменной шире (больше) текущей, используется неявное приведение:
int a = 20;
long b = a;
А вот если наоборот, то надо явно указывать своё желание:
int a = 3400099;
short h = (short) a; - потому что идет сужение типа и возможно потеря значений
Animal animal = new Dog();то объекту animal будут доступны все методы класса Animal, только в том виде, как они переписаны в классе Dog. А когда мы animal приводим к классу Dog - мы расширяем переменную, ведь она получит ранее недоступные ей методы. А вот если мы создалиAnimal animal = new Dog();и теперь решили эту переменную передать классу Cat - вот тут она все равно (скорей всего) получит расширение - дополнительные методы. Вот только доступные ей ранее методы класса Animal, возможно, будут переопределены и это, возможно, приведет к сбою в программе. И дополнительно: Когда переопределяем методы родительского класса, надо ли писать @Override ??