Действительно ли возможно назвать методы подклассов на суперобъекте класса?

  • Модульные тесты ориентированы на тестирование отдельных компонентов и не зависят от внешних зависимостей. Они обычно используются с насмешками или заглушками.
  • Интеграционные тесты включают в себя несколько компонентов и могут опираться на внешние зависимости.

Я думаю, что оба ценны, и ни один не может заменить другого в работе, которую они делают. Я вижу много интеграционных тестов, маскирующихся под юнит-тесты, хотя они имеют зависимости и требуют много времени для запуска. Они должны функционировать отдельно и как часть системы непрерывной интеграции.

Интеграционные тесты часто находят то, чего нет в модульных тестах ...

16
задан Ryan Gates 30 December 2013 в 19:23
поделиться

7 ответов

Это не будет компилироваться, так как Animal не имеет метода под названием bark. Подумайте об этом так: все собаки - животные, но не все животные - собаки. Все собаки лают, но не все животные.

32
ответ дан 30 November 2019 в 15:04
поделиться

нет - ответ;

4) вызов bark вызывает ошибку времени компиляции

метод bark не определен как метод для назначенного типа Animal, который, следовательно, будет привести к проблеме времени компиляции; это может быть решено преобразованием:

((Dog)a).bark();
27
ответ дан 30 November 2019 в 15:04
поделиться

В Head First Java они используют очень хорошую аналогию с пультом дистанционного управления телевизором для ​​ссылки и вашего телевизора в качестве объекта , на который указывает ссылка. Если на вашем пульте дистанционного управления есть только кнопки (методы) для включения, выключения, увеличения и уменьшения канала, увеличения и уменьшения громкости, не имеет значения, какие интересные функции есть у вашего телевизора. Вы по-прежнему можете выполнять только эти несколько основных действий с пульта дистанционного управления. Например, вы не можете отключить звук телевизора, если на вашем пульте дистанционного управления нет кнопки отключения звука.

Справочник Animal знает только о методах Animal. Не имеет значения, какие еще методы есть у базового объекта, вы не можете получить к ним доступ из ссылки Animal.

5
ответ дан 30 November 2019 в 15:04
поделиться

Ключ находится в следующей строке:

Animal a = new Dog();

Хотя был создан новый экземпляр Dog , его ссылка на a объявлена относиться к типу Животное . Следовательно, любые ссылки на a делают новую Собаку как Животное .

Следовательно, если Животное не имеет bark , следующая строка вызовет ошибку компилятора:

a.bark();

Несмотря на то, что a проверяется на предмет того, является ли он экземпляром Dog и ] instanceof Dog фактически вернет true , переменная a по-прежнему имеет тип Animal , поэтому блок внутри оператора if по-прежнему обрабатывает a как Animal .

Это особенность языков со статической типизацией где переменным заранее присваивается тип и проверяется во время компиляции, чтобы убедиться, что типы совпадают. Если бы этот код был выполнен на языке с динамической типизацией , где типы проверяются во время выполнения, могло бы быть разрешено что-то вроде следующего:

var a = new Dog();
if (a instanceof Dog)
    a.bark();

a.bark () гарантированно будет выполняться только если экземпляром является Dog , вызов bark будет работать всегда. Однако Java - язык со статической типизацией, поэтому этот тип кода не допускается.

и проверяется во время компиляции, чтобы убедиться, что типы совпадают. Если бы этот код был выполнен на языке с динамической типизацией , где типы проверяются во время выполнения, могло бы быть разрешено что-то вроде следующего:

var a = new Dog();
if (a instanceof Dog)
    a.bark();

a.bark () гарантированно будет выполняться только если экземпляром является Dog , вызов bark будет работать всегда. Однако Java - язык со статической типизацией, поэтому этот тип кода не допускается.

и проверяется во время компиляции, чтобы убедиться, что типы совпадают. Если бы этот код был выполнен на языке с динамической типизацией , где типы проверяются во время выполнения, могло бы быть разрешено что-то вроде следующего:

var a = new Dog();
if (a instanceof Dog)
    a.bark();

a.bark () гарантированно будет выполняться только если экземпляром является Dog , вызов bark будет работать всегда. Однако Java - язык со статической типизацией, поэтому этот тип кода не допускается.

11
ответ дан 30 November 2019 в 15:04
поделиться

Это 4. Вы не можете попросить обычное животное - как указано в вашем коде - лаять. Потому что вы могли бы так же легко сказать

Animal a = new Cat();

, и линия коры не знает, что вы этого не сделали.

4
ответ дан 30 November 2019 в 15:04
поделиться

"Я сказал 2, когда мы проверяем, является ли объект собакой; поскольку dog - это класс с методом bark в нем, если это так, мы вызываем его, который распечатывает: s "

Ваше объяснение верно, но это не так.

Java - это язык со статической типизацией, что означает, что достоверность методов, на которые объект может отвечать, проверяется во время компиляции .

Вы можете подумать, что проверка:

if( a instanceof Dog ) 

подойдет, но на самом деле это не так. Компилятор проверяет «интерфейс» объявленного типа (в данном случае Animal). «Интерфейс» состоит из методов, объявленных в классе Animal.

Если метод bark () не определен в суперклассе Animal , компилятор говорит: «Привет , это не сработает ".

Это полезно, потому что «иногда» мы допускаем опечатки при кодировании (например, набираем barck ())

Если компилятор не предупреждает нас об этом, вам придется найти его во «время выполнения», а не всегда с четким сообщением (например, javascript в IE говорит что-то вроде «неожиданный объект»)

Тем не менее, язык со статической типизацией, такой как java, позволяет нам принудительно вызывать вызов. В этом случае используется оператор «приведение» ()

Подобно этому

1. Animal a = new Dog();
2.  if (a instanceof Dog){
3.     Dog imADog = ( Dog ) a;
4.     imADog.bark();
5. }

В строке 3 выполняется «приведение» к типу Dog, поэтому компилятор может проверить, является ли сообщение bark допустимым.

Это инструкция компилятору: «Эй, я здесь программист, я знаю, что делаю». И компилятор проверяет, хорошо, собака, может получить сообщение bark (), продолжайте. Но если во время выполнения животное не собака,

1
ответ дан 30 November 2019 в 15:04
поделиться

К вашему сведению, это не очень хороший дизайн.

Практически каждый раз, когда у вас появляется код такой формы:

if (x instanceof SomeClass)
{
   x.SomeMethod();
}

вы злоупотребляете системой типов. Это не способ использования классов, это не способ писать поддерживаемый объектно-ориентированный код. Это хрупкое. Это запутанно. Это плохо.

Вы можете создавать шаблонные методы в базовом классе, но они должны вызывать методы, которые существуют в базовом классе и переопределяются в подклассах.

2
ответ дан 30 November 2019 в 15:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: