Struchkov Mark
953e4534c6
All checks were successful
continuous-integration/drone/push Build is passing
132 lines
7.8 KiB
Markdown
132 lines
7.8 KiB
Markdown
---
|
||
aliases:
|
||
- полиморфизмом
|
||
tags:
|
||
- maturity/🌱
|
||
date: 2024-09-27
|
||
zero-link:
|
||
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
|
||
parents:
|
||
- "[[ООП]]"
|
||
linked:
|
||
---
|
||
Полиморфизм — это один из фундаментальных принципов [[ООП|объектно-ориентированного программирования]] (ООП), который позволяет объектам разных классов обрабатывать одно и то же сообщение (вызов метода) по-разному. Это делает код более гибким и расширяемым, упрощая добавление новых возможностей без изменения существующего кода.
|
||
## Основные виды полиморфизма
|
||
Полиморфизм времени компиляции ([[../other/Статическое связывание|статическое связывание]]): Это форма полиморфизма, которая определяется на этапе компиляции программы. Примеры включают перегрузку методов и перегрузку операторов.
|
||
|
||
Один и тот же метод может иметь несколько версий, которые различаются по количеству или типам параметров.
|
||
|
||
Пример перегрузки метода:
|
||
```java
|
||
public class MathOperations {
|
||
public int add(int a, int b) {
|
||
return a + b;
|
||
}
|
||
|
||
public double add(double a, double b) {
|
||
return a + b;
|
||
}
|
||
}
|
||
```
|
||
|
||
Полиморфизм времени выполнения ([[../other/Динамическое связывание|динамическое связывание]]): Это форма полиморфизма, которая проявляется на этапе выполнения программы. Здесь используется наследование и переопределение методов.
|
||
|
||
Полиморфизм времени выполнения позволяет классу, наследующему методы базового класса, предоставлять свою собственную реализацию этих методов.
|
||
|
||
Пример динамического полиморфизма:
|
||
```java
|
||
public class Animal {
|
||
public void makeSound() {
|
||
System.out.println("Animal makes sound");
|
||
}
|
||
}
|
||
|
||
public class Dog extends Animal {
|
||
@Override
|
||
public void makeSound() {
|
||
System.out.println("Dog barks");
|
||
}
|
||
}
|
||
|
||
public class Cat extends Animal {
|
||
@Override
|
||
public void makeSound() {
|
||
System.out.println("Cat meows");
|
||
}
|
||
}
|
||
|
||
public class Main {
|
||
public static void main(String[] args) {
|
||
Animal myAnimal = new Dog(); // Полиморфизм
|
||
myAnimal.makeSound(); // Вывод: Dog barks
|
||
|
||
myAnimal = new Cat();
|
||
myAnimal.makeSound(); // Вывод: Cat meows
|
||
}
|
||
}
|
||
```
|
||
|
||
## Преимущества полиморфизма
|
||
- **Гибкость кода**: Полиморфизм позволяет работать с объектами через абстракции (интерфейсы или базовые классы), что делает систему гибкой для расширений и изменений. Например, новый класс может быть добавлен без изменения существующих классов или логики.
|
||
- **Упрощённое управление**: Код становится более управляемым и понятным, поскольку можно использовать общие типы данных (например, интерфейсы) для работы с разными реализациями.
|
||
- **Повторное использование кода**: Полиморфизм способствует использованию общих базовых классов, что уменьшает дублирование и увеличивает повторное использование кода.
|
||
|
||
## Частые ошибки при использовании полиморфизма
|
||
- **Избыточное использование полиморфизма**: Когда полиморфизм используется там, где он не нужен, это может усложнить код. Например, создание слишком большого количества наследников для решения простой задачи.
|
||
- **Нарушение принципа подстановки Лисков**: Это принцип гласит, что объект подкласса должен корректно заменять объект родительского класса без изменения поведения программы. Если полиморфизм реализован неправильно, это может привести к неожиданным ошибкам.
|
||
- **Неправильное управление зависимостями**: Если базовые классы слишком зависят от подклассов или знают о специфике их реализации, это может разрушить архитектуру. Полиморфизм должен использоваться вместе с инверсией зависимостей для минимизации связности.
|
||
## Пример полиморфизма
|
||
Представьте, что у вас есть система для обработки платежей, которая поддерживает разные способы оплаты: кредитные карты, PayPal, банковские переводы. В этом случае вы можете создать абстрактный класс или интерфейс `PaymentMethod`, а затем реализовать его для каждого конкретного метода оплаты:
|
||
|
||
```java
|
||
public interface PaymentMethod {
|
||
void pay(double amount);
|
||
}
|
||
|
||
public class CreditCard implements PaymentMethod {
|
||
@Override
|
||
public void pay(double amount) {
|
||
System.out.println("Paid " + amount + " with Credit Card");
|
||
}
|
||
}
|
||
|
||
public class PayPal implements PaymentMethod {
|
||
@Override
|
||
public void pay(double amount) {
|
||
System.out.println("Paid " + amount + " with PayPal");
|
||
}
|
||
}
|
||
|
||
public class PaymentProcessor {
|
||
public void processPayment(PaymentMethod method, double amount) {
|
||
method.pay(amount);
|
||
}
|
||
}
|
||
|
||
public class Main {
|
||
public static void main(String[] args) {
|
||
PaymentProcessor processor = new PaymentProcessor();
|
||
|
||
PaymentMethod card = new CreditCard();
|
||
PaymentMethod paypal = new PayPal();
|
||
|
||
processor.processPayment(card, 100);
|
||
processor.processPayment(paypal, 200);
|
||
}
|
||
}
|
||
```
|
||
|
||
Этот подход делает систему легко расширяемой: если нужно добавить новый способ оплаты, можно просто реализовать новый класс, не изменяя существующий код.
|
||
***
|
||
## Мета информация
|
||
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
|
||
**Родитель**:: [[ООП|ООП]]
|
||
**Источник**::
|
||
**Создана**:: [[2024-09-27]]
|
||
**Автор**::
|
||
### Дополнительные материалы
|
||
-
|
||
|
||
### Дочерние заметки
|
||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|