Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Полиморфизм в 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).