← Назад к вопросам

Как реализуется Полиморфизм?

2.0 Middle🔥 181 комментариев
#C# и ООП

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Полиморфизм в C# и Unity

Полиморфизм — один из четырёх столпов объектно-ориентированного программирования, который позволяет объектам разных типов использоваться через единый интерфейс. Это мощный механизм для написания гибкого и расширяемого кода.

Основные типы полиморфизма

1. Полиморфизм подтипов (Наследование)

Это самый распространённый тип полиморфизма. Благодаря наследованию, производные классы переопределяют методы базового класса с использованием ключевого слова virtual в базовом классе и override в производном.

public class Character
{
    public virtual void TakeDamage(float damage)
    {
        Debug.Log($"Character takes {damage} damage");
    }
}

public class Knight : Character
{
    public override void TakeDamage(float damage)
    {
        // Рыцарь получает 20% меньше урона благодаря броне
        float reducedDamage = damage * 0.8f;
        Debug.Log($"Knight takes {reducedDamage} damage (reduced by armor)");
    }
}

public class Mage : Character
{
    public override void TakeDamage(float damage)
    {
        // Маг может использовать магический щит
        float shieldedDamage = damage * 0.5f;
        Debug.Log($"Mage takes {shieldedDamage} damage (protected by shield)");
    }
}

Использование:

Character[] characters = new Character[]
{
    new Knight(),
    new Mage(),
    new Character()
};

foreach (Character character in characters)
{
    character.TakeDamage(50); // Каждый обрабатывает по-своему
}

2. Полиморфизм интерфейсов

Интерфейсы позволяют реализовать полиморфизм без жёсткой иерархии наследования. Это очень полезно в Unity для создания гибких систем.

public interface IDamageable
{
    void TakeDamage(float damage);
    float GetHealth();
}

public interface IHealable
{
    void Heal(float amount);
}

public class Player : MonoBehaviour, IDamageable, IHealable
{
    private float health = 100f;

    public void TakeDamage(float damage)
    {
        health -= damage;
        Debug.Log($"Player health: {health}");
    }

    public float GetHealth() => health;
    public void Heal(float amount) => health += amount;
}

public class Enemy : MonoBehaviour, IDamageable
{
    private float health = 50f;

    public void TakeDamage(float damage)
    {
        health -= damage;
        if (health <= 0) Destroy(gameObject);
    }

    public float GetHealth() => health;
}

Использование интерфейсов позволяет работать с любыми объектами единообразно:

public class Weapon : MonoBehaviour
{
    public void Attack(IDamageable target)
    {
        target.TakeDamage(10);
    }
}

3. Параметрический полиморфизм (Generics)

Обобщённое программирование позволяет писать типобезопасный код, который работает с любыми типами.

public class Inventory<T> where T : Item
{
    private List<T> items = new List<T>();

    public void AddItem(T item) => items.Add(item);
    public T GetItem(int index) => items[index];
    public void DisplayItems()
    {
        foreach (var item in items)
            Debug.Log(item.Name);
    }
}

// Использование
var swordInventory = new Inventory<Sword>();
swordInventory.AddItem(new Sword());

4. Полиморфизм утиной типизации (через отражение)

Хотя C# — язык со статической типизацией, иногда используется динамическая типизация через dynamic или отражение для большей гибкости.

public void InvokeAction(dynamic obj)
{
    obj.Execute(); // Сработает для любого объекта, у которого есть метод Execute
}

Практическое применение в Unity

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

Ключевое правило: выбирай наследование для отношений "есть" (is-a), интерфейсы для отношений "может" (can-do).