"Я сказал 2, когда мы проверяем, является ли объект собакой; поскольку собака - это класс с методом лая, если это так, мы вызываем его, который выведет: s"
Ваше обоснование правильное, но это не так.
Java - это статический типизированный язык, который означает, что валидность методов, на которые может ответить объект, проверяется в время компиляции .
Вы можете подумать, чек:
if( a instanceof Dog )
Подойдет, но на самом деле это не так. Компилятор проверяет «интерфейс» объявленного типа (в данном случае Animal). «Интерфейс» состоит из методов, объявленных в классе Animal.
Если метод bark () не определен в суперклассе Animal , компилятор говорит: «Эй, это не сработает».
Это полезно, потому что «иногда» мы делаем опечатки во время кодирования (например, вместо этого вводим barck ())
Если компилятор не предупреждает нас об этом, вам нужно будет найти его во время выполнения, а не всегда с четким сообщением (например, JavaScript в IE говорит что-то вроде «неожиданного объекта»)
Тем не менее, статический типизированный язык, такой как java, позволяет нам форсировать вызов. В этом случае используется оператор «cast» ()
Как это
1. Animal a = new Dog();
2. if (a instanceof Dog){
3. Dog imADog = ( Dog ) a;
4. imADog.bark();
5. }
В строке 3 вы «приводите» к типу Dog, поэтому компилятор может проверить, является ли лай действительным сообщением.
Это инструкция для компилятора, говорящая: «Эй, я программист, я знаю, что делаю». И компилятор, проверки, ОК, собака, может получить сообщение bark (), продолжить. Тем не менее, если во время выполнения животное не является собакой, возникнет исключение во время выполнения.
Состав также может быть сокращен как:
if( a instanceof Dog ) {
((Dog)a).bark();
}
Это будет работать.
Итак, правильный ответ: 4:" вызов лая вызывает ошибку времени компиляции "
Надеюсь, это поможет.