Appearance
多态
多态是什么
多态就是:同一个调用,面对不同真实对象,执行不同版本的行为。
c
Enemy enemy = new BossEnemy();
enemy.Attack();虽然变量类型是 Enemy,但真实对象是 BossEnemy。如果 BossEnemy 重写了 Attack(),运行时就会执行 Boss 的攻击逻辑。
继承版多态
父类写 virtual,表示允许子类改写:
c
public class Enemy
{
public virtual void Attack()
{
Debug.Log("普通攻击");
}
}子类写 override,表示真的改写父类行为:
c
public class BossEnemy : Enemy
{
public override void Attack()
{
Debug.Log("Boss 范围攻击");
}
}然后你就可以统一调用:
c
Enemy[] enemies =
{
new Enemy(),
new BossEnemy(),
new ArcherEnemy()
};
foreach (Enemy e in enemies)
{
e.Attack();
}同样是 e.Attack(),普通敌人执行普通攻击,Boss 执行范围攻击,弓箭手执行远程攻击。
Unity 里怎么用
比如回合管理器不需要知道每个敌人的具体类型:
c
[SerializeField] private EnemyBase[] enemies;
public void RunEnemyTurn()
{
foreach (EnemyBase enemy in enemies)
{
enemy.TakeTurn();
}
}每个敌人自己决定怎么行动:
c
public class BossEnemy : EnemyBase
{
public override void TakeTurn()
{
Debug.Log("Boss 行动");
}
}接口版多态
如果不是同一种父类,但有同一种能力,就用接口。
c
public interface IDamageable
{
void TakeDamage(int damage);
}敌人、箱子、玩家都可以实现它:
c
public class Enemy : MonoBehaviour, IDamageable
{
public void TakeDamage(int damage) { }
}子弹就不用关心打中的是谁:
c
IDamageable target = other.GetComponent<IDamageable>();
if (target != null)
{
target.TakeDamage(10);
}新手重点
virtual:父类允许子类改写。 override:子类改写父类方法。 new:隐藏父类方法,通常不是你想要的多态。 继承多态:适合“它们是同一种大类”。 接口多态:适合“它们有同一种能力”。
参考链接