Зачем использовать полиморфизм?
У меня есть следующий код, в котором у меня есть родительский класс и его дочерний элемент. Я пытаюсь определить, как код выигрывает от использования полиморфизма.
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