digital-garden/dev/architecture/Полиморфизм.md
Struchkov Mark 953e4534c6
All checks were successful
continuous-integration/drone/push Build is passing
Динамическое и статическое связывание
2024-10-05 07:28:51 +03:00

132 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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) -->