Зачем использовать полиморфизм?

У меня есть следующий код, в котором у меня есть родительский класс и его дочерний элемент. Я пытаюсь определить, как код выигрывает от использования полиморфизма.

class FlyingMachines {
    public void fly() {
        System.out.println("No implementation");
    }
}

class Jet extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Taxi, Fly");
    }

    public void bombardment() {
        System.out.println("Throw Missile");
    }
}

public class PolymorphicTest {
    public static void main(String[] args) {
        FlyingMachines flm = new Jet();
        flm.fly();

        Jet j = new Jet();
        j.bombardment();
        j.fly();
    }
}

В чем преимущество полиморфизма, когда оба flm.fly() и j.fly() дают мне тот же ответ?

Ответ 1

Сначала рассмотрим дизайн OO, наследование представляет собой отношение IS-A, как правило, мы можем сказать что-то вроде "let our FlyingMachines fly". каждый конкретный FlyingMachines (подкласс) IS-A FlyingMachines (родительский класс), скажем, Jet, подходит для этого "пусть наш FlyingMachines летает", в то время как мы хотим, чтобы этот полет фактически был функцией мух конкретного один (подкласс), который использует полиморфизм.

поэтому мы делаем вещи абстрактно, ориентированные интерфейсы и базовый класс, на самом деле не зависим от реализации деталей, полиморфизм пойдет правильно!

Ответ 2

В вашем примере использование полиморфизма не очень полезно, поскольку у вас есть только один подкласс FlyingMachine. Полиморфизм становится полезным, если у вас есть несколько типов FlyingMachine. Тогда у вас может быть метод, который принимает любой тип FlyingMachine и использует его метод fly(). Пример может быть testMaxAltitude(FlyingMachine).

Другая функция, доступная только при полиморфизме, - это возможность иметь List<FlyingMachine> и использовать ее для хранения Jet, Kite или VerySmallPebbles.

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

Например, лучше иметь метод, который возвращается как List<FlyingMachine>, а не ArrayList<FlyingMachine>. Таким образом, я могу изменить свою реализацию в методе на LinkedList или Stack без нарушения кода, использующего мой метод.

Ответ 3

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

Итак, в вашем случае более полезным примером является создание типа объекта "Аэропорт", который принимает различные типы FlyingMachines. Аэропорт определит функцию "AllowPlaneToLand", аналогичную:

//pseudocode
void AllowPlaneToLand(FlyingMachine fm)
{
    fm.LandPlane();
}

Пока каждый тип FlyingMachine определяет правильный метод LandPlane, он может нормально приземляться. Аэропорту не нужно ничего знать о FlyingMachine, за исключением того, что для посадки самолета он должен вызвать LandPlane на FlyingMachine. Таким образом, Аэропорт больше не нуждается в изменении, и он может продолжать принимать новые типы FlyingMachines, будь то handglider, НЛО, парашют и т.д.

Таким образом, полиморфизм полезен для фреймворков, которые построены вокруг этих объектов, которые могут получить общий доступ к этим методам без изменения.

Ответ 4

В чем преимущество полиморфизма, когда flm.fly() и j.fly()дайте мне тот же ответ?

Преимущество состоит в том, что

FlyingMachines flm = new Jet();
flm.fly();

возвращает

"Start, Taxi, Fly"

вместо

"No implementation"

Этот полиморфизм. Вы вызываете fly() на объект типа FlyingMachine, и он все еще знает, что он фактически является Jet и вызывает соответствующий метод fly() вместо неправильного, который выводит "No implementation".

Это означает, что вы можете писать методы, которые работают с объектами типа FlyingMachine, и передавать его всеми типами подтипов типа Jet или Helicopter, и эти методы всегда будут поступать правильно, т.е. называть fly() метод соответствующего типа вместо того, чтобы всегда делать то же самое, то есть вывод "No implementation".

Полиморфизм

Полиморфизм не полезен в вашем примере.

  • a) Он становится полезным, когда у вас есть разные типы объектов, и может писать классы, которые могут работать со всеми этими разными типами, потому что все они придерживаются одного и того же API.

  • b) Он также полезен, когда вы можете добавить новый FlyingMachine в ваше приложение, не изменяя ни одну из существующих логических схем.

a) и b) являются двумя сторонами одной и той же монеты.

Позвольте мне показать, как.

Пример кода

import java.util.ArrayList;
import java.util.List;

import static java.lang.System.out;

public class PolymorphismDemo {

    public static void main(String[] args) {
        List<FlyingMachine> machines = new ArrayList<FlyingMachine>();
        machines.add(new FlyingMachine());
        machines.add(new Jet());
        machines.add(new Helicopter());
        machines.add(new Jet());

        new MakeThingsFly().letTheMachinesFly(machines);
    }
}

class MakeThingsFly {
    public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
        for (FlyingMachine flyingMachine : flyingMachines) {
            flyingMachine.fly();
        }
    }
}

class FlyingMachine {
    public void fly() {
        out.println("No implementation");
    }
}

class Jet extends FlyingMachine {
    @Override
    public void fly() {
        out.println("Start, taxi, fly");
    }

    public void bombardment() {
        out.println("Fire missile");
    }
}

class Helicopter extends FlyingMachine {
    @Override
    public void fly() {
        out.println("Start vertically, hover, fly");
    }
}

Объяснение

a) Класс MakeThingsFly может работать со всем, что имеет тип FlyingMachine.

b) Метод letTheMachinesFly также работает без каких-либо изменений (!) при добавлении нового класса, например PropellerPlane:

public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
        for (FlyingMachine flyingMachine : flyingMachines) {
            flyingMachine.fly();
        }
    }
}

Это сила полиморфизма. Вы можете реализовать открытый закрытый принцип.

Ответ 5

Это не добавляет много, если у вас будет только Jets, преимущество придет, когда у вас будут разные FlyingMachines, например. Самолет

Теперь, когда вы модифицировали, чтобы включить больше классов, преимущество полиморфизма заключается в том, что абстракция от конкретного типа (и бизнес-концепции) экземпляра, который вы получаете, вам просто нужно, чтобы он мог летать

Ответ 6

Оба flm.fly() и j.fly() дают вам один и тот же ответ из-за того, что тип экземпляра на самом деле тот же, что и Jet, поэтому они ведут себя одинаково.

Вы можете видеть разницу, когда вы:

FlyingMachines flm = new FlyingMachines();
flm.fly();

Jet j = new Jet();
j.bombarment();
j.fly();

Полиморфизм определяется как одна и та же сигнатура метода с разностным поведением. Как вы можете видеть, оба FlyingMachines и Jet имеют метод fly(), но метод реализован по-разному, которые считают, что ведут себя по-другому.

См аа

Ответ 7

Polymorphism (как время выполнения, так и время компиляции) необходимо в Java по нескольким причинам.

Переопределение метода - это полиморфизм времени выполнения, а перегрузка - это полиморфизм времени компиляции.

Немногие из них (некоторые из них уже обсуждались):

  • Коллекции. Предположим, у вас есть несколько типов летательных аппаратов, и вы хотите, чтобы все они были в одной коллекции. Вы можете просто определить список типов FlyingMachines и добавить их все.

    List<FlyingMachine> fmList = new ArrayList<>();
    fmList.add(new new JetPlaneExtendingFlyingMachine());
    fmList.add(new PassengerPlanePlaneExtendingFlyingMachine());
    

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

  • Кастовый тип одного типа для другого. Объявите объекты как:

    FlyingMachine fm1 = new JetPlaneExtendingFlyingMachine();
    FlyingMachine fm2 = new PassengerPlanePlaneExtendingFlyingMachine();
    fm1 = fm2; //can be done
    
  • Перегрузка: не связана с кодом, который вы указали, но перегрузка - это еще один тип полиморфизма, называемый полиморфизмом времени компиляции.

  • Может иметь единственный метод, который принимает тип FlyingMachine обрабатывать все типы, т.е. подклассы FlyingMachine. Может быть достигнуто только с помощью Polymorphism.

Ответ 8

полиморфизм, как указано ясно сам по себе, тот, который отображается для многих.

java - это язык oops, поэтому он имеет реализацию для него путем абстрактного, перегрузки и переопределения

помните, что java не будет иметь спецификацию для полиморфизма времени выполнения.

у него есть и лучший пример для него.

public abstract class Human {

    public abstract String getGender();

}

class Male extends Human
{
    @Override
    public String getGender() {
        return "male";
    }
}

class Female extends Human
{
    @Override
    public String getGender() {
        return "female";
    }
}

Перекрытие

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

Перегрузки

может иметь поведение с тем же именем с другой подписью. например, конкретный президент говорит громко, но другой говорит только громко.

Ответ 9

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

Ответ 10

Полиморфизм дает вам преимущества только в том случае, если вам нужен полиморфизм. Он использовался, когда объект вашего концептуального проекта можно рассматривать как специализацию другого объекта. Основная идея - "специализация". Отличный пример стоит в так называемой таксономии, например, применительно к живым существам. Собаки и люди - это млекопитающие. Это означает, что класс Mammals группирует все сущности, которые имеют некоторые свойства и поведение в целом.

Кроме того, ElectricCar и DieselCar являются специализацией автомобиля. Итак, у обоих есть isThereFuel(), потому что, когда вы водите автомобиль, вы ожидаете узнать, достаточно ли топлива для его вождения. Еще одна отличная концепция - "ожидание".

Всегда начинайте рисовать диаграмму ER (сущность) диаграммы домена вашего программного обеспечения перед ее запуском. Это потому, что вы вынуждены представить, какие типы сущностей будут созданы, и если вы в состоянии достаточно, вы можете сэкономить много кода, обнаруживая общее поведение между объектами. Но сохранение кода - не единственное преимущество хорошего проекта.

Вам может быть интересно узнать о так называемой "программной инженерии", что он представляет собой набор техник и концепций, который позволяет вам писать "чистый код" (там также есть замечательная книга под названием "Чистый код", -grammes).

Ответ 11

Полиморфизм может помочь нашему коду удалить условные условия "if", которые предназначены для создания кода уровня продукции, поскольку удаление условных выражений увеличит читаемость кода и поможет нам лучше писать unit test случаи, которые мы знаем для "n", если случаи появляются n! (n факториальные) возможности.

Посмотрим, как

если у вас есть класс FlyingMachine и который берет строку в конструкторе, определяющем тип FlyMachine, как показано ниже

class FlyingMachine{

    private type;

    public FlyingMachine(String type){
             this.type = type;
    }

    public int getFlyingSpeedInMph {
         if(type.equals("Jet"))
              return 600;
         if(type.equals("AirPlane"))
              return 300;
    }

 }

Мы можем создать два экземпляра FlyingMachine как

 FlyingMachine jet = new FlyingMachine("Jet");
 FlyingMachine airPlane = new FlyingMachine("AirPlane");

и получить скорость, используя

 jet.fylingSpeedInMph();
 airPlane.flyingSpeedInMph();

Но если вы используете полиморфизм, вы собираетесь удалить условия if, расширив общий класс FlyMachine и переопределив getFlyingSpeedInMph, как показано ниже

class interface FlyingMachine {

     public int abstract getFlyingSpeedInMph;
}


class Jet extends FlyingMachine {
    @Override
    public int getFlyingSpeedInMph(){
          return 600;
    }
}

class Airplane extends FlyingMachine {
    @Override
    public int getFlyingSpeedInMph(){
          return 600;
    }
}

Теперь вы можете получить скорость полета ниже

 FlyingMachine jet = new Jet();
 jet.flyingSpeed();

 FlyingMachine airPlane = new AirPlane();
 airPlane.flyingSpeed();

Ответ 12

Добавьте еще один класс в это, он поможет вам понять использование полиморфизма.

class FlyingMachines {
    public void fly() {
        System.out.println("No implementation");
    }
}

class Jet extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Jet, Fly");
    }
}

class FighterPlan extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Fighter, Fight");
    }
}

public class PolymorphicTest {
    public static void main(String[] args) {
        FlyingMachines flm = new Jet();
        flm.fly();

        FlyingMachines flm2 = new FighterPlan();
        flm2.fly();
    }
}

Вывод:

Start, Jet, Fly
Start, Fighter, Fight