Course program← Объектно ориентированное программирование
1История ООП
2Объект и Класс
3Базовые концепции ООП
4Принцип проектирования GRASP
5Принцип проектирования SOLID
6Паттерны GOF

Polymorphism (Полиморфизм)

This lesson is not translated yet – the Russian original is below.

TODO: отвалидировать – текст собран автоматически из материалов курса на Google Drive, проверьте формулировки и код.

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

Решать её стоит полиморфными операциями, а не проверкой типа и условной логикой. Тогда систему можно расширять, добавляя новые вариации, а не дописывая ветки в существующий switch.

// Проверка типа: каждый новый формат – правка этого метода
public string Export(Report report, string format)
{
    if (format == "pdf") return ExportPdf(report);
    if (format == "csv") return ExportCsv(report);

    throw new NotSupportedException(format);
}

// Полиморфизм: новый формат – новый класс, старый код не трогаем
public interface IReportExporter
{
    string Export(Report report);
}

public class PdfExporter : IReportExporter { public string Export(Report r) => ""; }
public class CsvExporter : IReportExporter { public string Export(Report r) => ""; }
// Проверка значения: каждый новый формат – правка этой функции
std::string Export(const Report& report, const std::string& format) {
    if (format == "pdf") return ExportPdf(report);
    if (format == "csv") return ExportCsv(report);

    throw std::invalid_argument("формат не поддерживается: " + format);
}

// Полиморфизм: новый формат – новый класс, старый код не трогаем
class IReportExporter {
public:
    virtual std::string Export(const Report& report) const = 0;
    virtual ~IReportExporter() = default;
};

class PdfExporter : public IReportExporter {
public:
    std::string Export(const Report& report) const override { return ""; }
};

class CsvExporter : public IReportExporter {
public:
    std::string Export(const Report& report) const override { return ""; }
};
// Проверка значения: каждый новый формат – правка этой функции
func Export(report Report, format string) (string, error) {
	switch format {
	case "pdf":
		return exportPDF(report), nil
	case "csv":
		return exportCSV(report), nil
	}

	return "", fmt.Errorf("формат не поддерживается: %s", format)
}

// Полиморфизм через интерфейс: новый формат – новый тип
type ReportExporter interface {
	Export(report Report) string
}

type PDFExporter struct{}

func (PDFExporter) Export(r Report) string { return "" }

type CSVExporter struct{}

func (CSVExporter) Export(r Report) string { return "" }
# Проверка типа: каждый новый формат – правка этой функции
def export(report: Report, fmt: str) -> str:
    if fmt == "pdf":
        return export_pdf(report)
    if fmt == "csv":
        return export_csv(report)

    raise ValueError(f"формат не поддерживается: {fmt}")

# Полиморфизм: новый формат – новый класс
from typing import Protocol

class ReportExporter(Protocol):
    def export(self, report: Report) -> str: ...

class PdfExporter:
    def export(self, report: Report) -> str:
        return ""

class CsvExporter:
    def export(self, report: Report) -> str:
        return ""
// Проверка типа: каждый новый формат – правка этой функции
function exportReport(report: Report, format: string): string {
    if (format === "pdf") return exportPdf(report);
    if (format === "csv") return exportCsv(report);

    throw new Error(`формат не поддерживается: ${format}`);
}

// Полиморфизм: новый формат – новый класс
interface ReportExporter {
    export(report: Report): string;
}

class PdfExporter implements ReportExporter {
    export(report: Report): string {
        return "";
    }
}

class CsvExporter implements ReportExporter {
    export(report: Report): string {
        return "";
    }
}
// Проверка типа: каждый новый формат – правка этого метода
public String export(Report report, String format) {
    if (format.equals("pdf")) return exportPdf(report);
    if (format.equals("csv")) return exportCsv(report);

    throw new UnsupportedOperationException(format);
}

// Полиморфизм: новый формат – новый класс
public interface ReportExporter {
    String export(Report report);
}

public class PdfExporter implements ReportExporter {
    public String export(Report report) { return ""; }
}

public class CsvExporter implements ReportExporter {
    public String export(Report report) { return ""; }
}
// Проверка типа: каждый новый формат – правка этой функции
fun export(report: Report, format: String): String = when (format) {
    "pdf" -> exportPdf(report)
    "csv" -> exportCsv(report)
    else -> throw UnsupportedOperationException(format)
}

// Полиморфизм: новый формат – новая реализация
fun interface ReportExporter {
    fun export(report: Report): String
}

class PdfExporter : ReportExporter {
    override fun export(report: Report): String = ""
}

class CsvExporter : ReportExporter {
    override fun export(report: Report): String = ""
}

Тот же принцип лежит в основе паттернов Strategy и State из последнего модуля курса.