Unity 接口、抽象类、具体类对象的配合使用案例

文章目录

      • 示例1:接口(Interface)
      • 示例2:抽象类(Abstract Class)
      • 示例3:结合使用接口与抽象类
      • 示例4:多接口实现
      • 示例5:抽象类与接口结合

在Unity中使用C#编程时,接口、抽象类与具体类是面向对象设计中的重要概念。以下通过三个代码实例来讲解它们的设计与使用场景:

示例1:接口(Interface)

场景
假设我们正在开发一个游戏,需要定义一个“可移动”(IMovable)的接口,以便于所有角色、敌人和道具等都可以实现这个接口,从而具备移动的能力。

// 定义接口IMovable
public interface IMovable
{
    void Move(Vector3 direction);
    float Speed { get; set; }
}

// 具体类Player实现IMovable接口
public class Player : MonoBehaviour, IMovable
{
    public float speed;

    public float Speed
    {
        get => speed;
        set => speed = value;
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.W))
        {
            Move(Vector3.forward * Time.deltaTime * Speed);
        }
    }

    void Move(Vector3 direction)
    {
        transform.position += direction;
    }
}

// 同样,Enemy类也可以实现IMovable接口
public class Enemy : MonoBehaviour, IMovable
{
    // 实现Move方法和Speed属性...
}

示例2:抽象类(Abstract Class)

场景
考虑一个更为复杂的场景,我们有一个基础的实体基类,其中包含一些通用功能,同时希望某些实体具有攻击能力,但不直接提供具体的攻击逻辑,这时可以定义一个抽象的Actor类,并包含一个抽象的Attack方法。

// 抽象类Actor
public abstract class Actor : MonoBehaviour
{
    public int Health { get; protected set; }

    protected Actor(int initialHealth)
    {
        Health = initialHealth;
    }

    // 抽象方法,由子类实现具体的攻击行为
    public abstract void Attack(Actor target);

    // 通用功能,例如显示血量
    public void DisplayHealthUI()
    {
        // 假设此处有UI更新代码
    }
}

// 具体类Knight继承自Actor并实现Attack方法
public class Knight : Actor
{
    public Knight(int health) : base(health)
    {
    }

    public override void Attack(Actor target)
    {
        if (target is not null)
        {
            target.Health -= 10; // 假设每次攻击造成10点伤害
        }
    }
}

// 另一个具体类Mage同样继承自Actor并实现Attack方法
public class Mage : Actor
{
    public Mage(int health) : base(health)
    {
    }

    public override void Attack(Actor target)
    {
        if (target is not null)
        {
            target.Health -= 20; // 假设每次攻击造成20点伤害
        }
    }
}

示例3:结合使用接口与抽象类

场景
假设我们的游戏包含不同类型的NPC,有些NPC会说话,有些则不会。我们可以先定义一个抽象的NPC类,然后用一个ISpeakable接口来表示那些能说话的NPC。

// 抽象类NPC
public abstract class NPC : MonoBehaviour
{
    public string Name { get; set; }

    public abstract void Interact();
}

// ISpeakable接口
public interface ISpeakable
{
    string Speak();
}

// 具体类Merchant继承自NPC并实现ISpeakable接口
public class Merchant : NPC, ISpeakable
{
    public Merchant(string name) 
    {
        Name = name;
    }

    public override void Interact()
    {
        Debug.Log($"你与{Name}交谈...");
        if (this is ISpeakable speakable)
        {
            Debug.Log(speakable.Speak());
        }
    }

    public string Speak()
    {
        return $"欢迎光临,我这里有各种商品出售!";
    }
}

// 具体类Guard类也继承自NPC,但并不实现ISpeakable接口
public class Guard : NPC
{
    public Guard(string name) 
    {
        Name = name;
    }

    public override void Interact()
    {
        Debug.Log($"你尝试与{Name}交谈,但他只是坚守岗位并未回应...");
    }
}

示例4:多接口实现

场景
在Unity中,我们可能需要设计一些对象既可以被玩家控制也可以被AI控制。这时可以定义IControllable(可控制)和IAIControlled(AI控制)两个接口。

// 定义可控制接口
public interface IControllable
{
    void TakePlayerInput();
}

// 定义AI控制接口
public interface IAIControlled
{
    void UpdateAI();
}

// 具体类Character同时实现两个接口
public class Character : MonoBehaviour, IControllable, IAIControlled
{
    public void TakePlayerInput()
    {
        // 处理玩家输入,例如移动、攻击等
        Debug.Log("处理玩家输入...");
    }

    public void UpdateAI()
    {
        // 更新AI逻辑,例如自动寻路、决策等
        Debug.Log("执行AI逻辑...");
    }
    
    void Update()
    {
        if (isPlayerControlled)
        {
            TakePlayerInput();
        }
        else if (isAIControlled)
        {
            UpdateAI();
        }
    }
}

在这个例子中,Character类可以根据游戏运行时的状态,选择使用玩家输入还是AI逻辑进行操作,体现了接口的灵活性和解耦性。

示例5:抽象类与接口结合

场景
考虑一个角色系统,角色分为基础角色和英雄角色,基础角色有基本属性如生命值和攻击力,而英雄角色除了基础属性外还有特殊技能。我们可以创建一个抽象角色类,并使用接口来表示具有特定技能的角色。

// 抽象角色类
public abstract class BaseCharacter : MonoBehaviour
{
    public int Health { get; protected set; }
    public int AttackPower { get; set; }

    protected BaseCharacter(int health, int attackPower)
    {
        Health = health;
        AttackPower = attackPower;
    }

    // 基础攻击方法
    public virtual void Attack(BaseCharacter target)
    {
        target.Health -= AttackPower;
    }
}

// 特殊技能接口
public interface ISpecialAbility
{
    void UseSpecialAbility();
}

// 英雄角色类继承自BaseCharacter并实现ISpecialAbility接口
public class Hero : BaseCharacter, ISpecialAbility
{
    public Hero(int health, int attackPower, string specialSkillDescription) 
        : base(health, attackPower)
    {
        SpecialSkillDescription = specialSkillDescription;
    }

    public string SpecialSkillDescription { get; private set; }

    // 实现特殊技能
    public override void Attack(BaseCharacter target)
    {
        base.Attack(target);
        UseSpecialAbility();
    }

    public void UseSpecialAbility()
    {
        Debug.Log($"英雄施展{SpecialSkillDescription},对目标造成额外伤害...");
    }
}

这个示例展示了如何通过抽象类来封装共享的基础功能,并通过接口让某些具体类具备额外的能力,从而构建出丰富且灵活的角色系统。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

你可能感兴趣的:(unity,游戏引擎,c#)