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

Какие знаешь механизмы полиморфизма?

2.0 Middle🔥 221 комментариев
#C# и ООП#Паттерны проектирования

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

Полиморфизм в контексте разработки на C# и Unity

Полиморфизм — это один из четырёх основных принципов объектно-ориентированного программирования (ООП), который позволяет объектам разных типов обрабатываться через общий интерфейс. В C# (основном языке Unity) реализуется через несколько ключевых механизмов.

1. Переопределение методов (Наследование и виртуальные методы)

Это классический подход через наследование классов. Базовый класс определяет виртуальный метод (virtual), который может быть переопределён (override) в производном классе.

public class Enemy
{
    public virtual void Attack()
    {
        Debug.Log("Enemy attacks generically.");
    }
}

public class Orc : Enemy
{
    public override void Attack()
    {
        Debug.Log("Orc swings a massive club!");
    }
}

public class Mage : Enemy
{
    public override void Attack()
    {
        Debug.Log("Mage casts a fireball!");
    }
}

// Использование
Enemy[] enemies = { new Enemy(), new Orc(), new Mage() };
foreach (var enemy in enemies)
{
    enemy.Attack(); // Вызовется разная реализация для каждого типа
}

2. Абстрактные классы и методы

Абстрактный класс не может быть инстанциирован и часто содержит абстрактные методы (без реализации), которые обязаны быть реализованы в производных классах.

public abstract class Weapon
{
    public abstract void Fire(); // Абстрактный метод
    
    public void Reload() // Обычный метод с реализацией
    {
        Debug.Log("Reloading weapon...");
    }
}

public class Rifle : Weapon
{
    public override void Fire()
    {
        Debug.Log("Rifle: Single shot!");
    }
}

public class Shotgun : Weapon
{
    public override void Fire()
    {
        Debug.Log("Shotgun: Wide spread shot!");
    }
}

3. Интерфейсы

Интерфейс определяет контракт (набор методов, свойств, событий) без реализации. Класс может реализовывать несколько интерфейсов, что обеспечивает гибкость, особенно важную в архитектуре Unity.

public interface IDamageable
{
    void TakeDamage(float amount);
    float Health { get; }
}

public interface ICollectible
{
    void Collect();
}

public class Player : MonoBehaviour, IDamageable
{
    public float Health { get; private set; } = 100f;
    
    public void TakeDamage(float amount)
    {
        Health -= amount;
        Debug.Log($"Player health: {Health}");
    }
}

public class HealthPack : MonoBehaviour, ICollectible
{
    public void Collect()
    {
        Debug.Log("Health pack collected!");
        Destroy(gameObject);
    }
}

4. Полиморфизм через делегаты и события

В Unity часто используется полиморфное поведение через систему событий и делегаты, такие как UnityAction или System.Action. Это позволяет разным объектам реагировать на одни и те же события по-своему.

public class GameEvents : MonoBehaviour
{
    public static event System.Action<Vector3> OnSpawnPointSelected;
    
    public static void TriggerSpawn(Vector3 point)
    {
        OnSpawnPointSelected?.Invoke(point);
    }
}

public class PlayerSpawner : MonoBehaviour
{
    void OnEnable() => GameEvents.OnSpawnPointSelected += SpawnPlayer;
    void OnDisable() => GameEvents.OnSpawnPointSelected -= SpawnPlayer;
    
    void SpawnPlayer(Vector3 point)
    {
        transform.position = point;
        Debug.Log("Player spawned at: " + point);
    }
}

5. Полиморфизм в универсальных (generic) методах и классах

Дженерики позволяют создавать типы и методы, которые работают с разными типами данных, сохраняя безопасность типов.

public class ObjectPool<T> where T : Component
{
    private Queue<T> pool = new Queue<T>();
    
    public T GetObject()
    {
        if (pool.Count > 0)
            return pool.Dequeue();
        return new GameObject().AddComponent<T>();
    }
}

// Использование для разных типов
ObjectPool<Bullet> bulletPool = new ObjectPool<Bullet>();
ObjectPool<Enemy> enemyPool = new ObjectPool<Enemy>();

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

  • Компонентная архитектура: Каждый MonoBehaviour — пример полиморфизма. Мы работаем с компонентами через базовый тип, но вызываем специфичные для каждого компонента методы Start(), Update().
  • Обработка взаимодействий: Использование интерфейсов, например IDamageable, для единообразной обработки урона для игрока, врагов, разрушаемых объектов.
  • Система событий: UnityEvent позволяет присоединять различные методы-обработчики к одному событию, что тоже является формой полиморфизма.
  • Реализация State Machines: Состояния в паттерне "состояние" часто реализуются через полиморфизм, где каждое состояние — отдельный класс с общей базой.

Полиморфизм в Unity повышает гибкость кода, упрощает добавление новых сущностей, уменьшает связность компонентов и является основой для создания расширяемых архитектур, таких как системы способностей, диалогов, инвентаря или ИИ. Ключ — выбирать подходящий механизм (интерфейс, абстрактный класс, виртуальные методы) под конкретную задачу, учитывая необходимость множественного наследования, наличие базовой реализации и требования к производительности.

Какие знаешь механизмы полиморфизма? | PrepBro