Каковы преимущества объявления типа, отличного от объекта инициализации, из-за полиморфизма? - PullRequest
1 голос
/ 06 апреля 2020

Учитывая следующий код:

class Vehicle{
    public void operate(){
        System.out.println("The vehicle is being operated.");
    }
}

class Car extends Vehicle{
    public void operate(){
        System.out.println("The car is being operated.");
    }
}

public class Simulation{
    public static void main(String[] args){
        Vehicle vehicle1 = new Car();
        Vehicle vehicle2 = new Vehicle();
        vehicle1.operate();
        vehicle2.operate();
    }
}

Какая польза от объявления транспортного средства 1 как транспортного средства, когда мы в конечном итоге инициализируем его как автомобиль? Разве мы не должны просто объявить это как Автомобиль?

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

В этом примере неочевидно увидеть выгоду. Однако это дает следующие преимущества:

  1. Обычно вы будете вызывать методы с вашим объектом. Таким образом, у нас есть два варианта ...myFunction(Vehicle vehicle) или myFunction(Car car). Если вы решите использовать Car, вы ограничиваете тип, который можно передать этому методу. Это очень важно. Имейте в виду, что программное обеспечение сильно меняется, меняются требования, вносятся улучшения. Давайте предположим, что теперь у вас есть новый блестящий объект Ferrari, который расширяет Автомобиль, вы не можете позвонить myFunction(Car car), но вы сможете позвонить myFunction(Vehicle vehicle), минуя Ferrari. Таким образом, чтобы сделать вызов с помощью myFunction, вам нужно изменить сигнатуру функции. Иногда вы не можете изменить сигнатуру функции, потому что, ну, это библиотека, и у вас нет исходного кода. Или, может быть, вы можете изменить это, но если вы это сделаете, вы будете ломать людей, используя ваш код При разработке более крупного программного обеспечения команды делятся, и вам необходимо создать некоторые классы, которые другие будут использовать для завершения всего проекта. Или вы будете создавать библиотеки и отправлять клиентам. В этом основная причина полиморфизма: упростить совместную работу многих команд, не нарушая код друг друга, а также улучшить код, используя подклассы, не нарушая ничего. Когда вы пишете только небольшой фрагмент кода, которым вы не собираетесь делиться с кем-либо, и не планируете расширять эту кодовую базу, это не приносит особой выгоды. Однако это хорошая привычка иметь.

  2. Намерение: объявив его как Автомобиль, вы показываете в своем коде, что вы заботитесь только о том, что имеет поведение Транспортного средства .ie Вы можете позвонить работать (). Когда вы расширяете класс, вы можете добавить к нему дополнительные поведения / методы. Объявив его как Автомобиль, вы не сможете вызывать какие-либо новые методы в автомобиле. Помните, что ваш код, скорее всего, будет прочитан другими (если это не ваша личная собственность), поэтому использование Vehicle делает очевидным, что вы заботитесь только о том, что может работать ().

  3. Коллекции: очень часто вам нужно создавать объекты и использовать их как коллекцию. Давайте представим, что у вас есть гонка транспортных средств. Чтобы запустить все Транспортные средства, вы можете легко использовать Vehicle[] и заполнить их всех, если используете Автомобиль. Если бы вы использовали Car, Ferrari, Van ... вы могли бы заполнить их, только если вы используете Object[], и тогда вам придется привести к ((Vehicle)arrayElement).operate() вместо просто arrayElement.operate(). Я даю упрощенный пример c, но я думаю, что вы поймете идею.

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

0 голосов
/ 07 апреля 2020

Объявляя это локально в таком методе, нет большой разницы. Вообще говоря, вы получаете больше гибкости, работая над ссылками наиболее абстрактного типа, который может работать. Вы можете увидеть это в коде типа List<String> foo = new ArrayList<>();, потому что List достаточно.

Например, посмотрите на Collections.sort (). Требуется List, потому что элементы списка упорядочены. Это не может просто занять Collection, потому что коллекции не гарантированно заказаны, как Set. Но он может использовать любую реализацию List, например, ArrayList, LinkedList, и т. Д. c, потому что упорядочение является единственным свойством, которое заботит sort ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...