接口、虚函数使用之个人见解
最近在封装重构太空大战的代码,结合原来C#的知识点发现很多有意思的地方,此文主要介绍下接口和虚函数的使用,但对于接口和虚函数的区别这里不在描述(自行百度、谷歌)。
虚函数的使用:
定义一个Enemy的基类,它具有所有的敌人的共有属性及行为。而它的派生类会有较多的属性及特有/变种行。例如以下代码,Enemy具有生命、速度属性,有死亡、复活的行为,所有派生类也都具有这些属性及行为,把该类中的初始化方法,死亡、复活方法定义为虚方法,方便在派生类中有特殊逻辑可以在相应的重载函数中实现。
代码如下:
public class Enemy : MonoBehaviour {
public Transform m_transform;
///生命属性
public float m_life
{
get;
set;
}
///速度
public float m_speed
{
get;
set;
}
// Use this for initialization
void Start () {
Init();
m_transform = this.transform;
}
//初始化
protected virtual void Init()
{
m_speed = 1;
m_life = 5;
}
//移动轨迹
protected virtual void EnemyMove()
{
Move.Instance.MoveToDir(m_transform, CustomerMoveDirection.line,-m_speed);
}
//死亡
public virtual void Dead()
{
m_transform.position = Move.Instance.HidePosition;
m_transform.gameObject.SetActive(false);
}
//复活
public virtual void Revive(Vector3 position, Quaternion rotation)
{
m_transform.gameObject.SetActive(true);
m_transform.position = position;
m_transform.rotation = rotation;
}
}
派生类:
public class EnemyLevel1 : Enemy {
private float m_timer = 5f;
//生命及速度重写
protected override void Init()
{
m_life = 10;
m_speed = 0.5f;
}
//移动轨迹重写
protected override void EnemyMove()
{
#region 水平方向 z轴 1.5左右来回移动
if (m_timer > 0)
{
m_timer -= Time.deltaTime;
Move.Instance.MoveToDir(m_transform, CustomerMoveDirection.sign, m_speed);
}
else
{
Move.Instance.MoveToDir(m_transform, CustomerMoveDirection.sign,-m_speed);
if (m_transform.position.z > 4)
m_timer = 5f;
}
#endregion
}
public override void Dead()
{
//如果有特殊逻辑,可以在此处完成
base.Dead();
}
public override void Revive(Vector3 position, Quaternion rotation)
{
//如果 有特殊逻辑,可以再此处完成
base.Revive(position, rotation);
}
}
接口的使用:
定义IEnemy接口
public interface IEnemy
{
float m_life { get; set; }
float m_speed{get;set;}
void Dead();
void Revive(Vector3 position, Quaternion rotation);
}
类Enemy和EnemyLevel1 分别继承该接口(别忘了继承MonoBehaviour这个类),并在各自类中按各自的业务逻辑实现(当然公共部分可以抽出封装起来),此部分不贴代码(可以百度、谷歌 “C#接口实现”).
对比以上两种实现方式,个人感觉单就这个游戏的例子而言虚函数的使用要比接口方便,派生类中只需要在有特殊处理的方法中完善代码即可,但接口就需要在每个继承接口的类中去写实现。但如果要实现多继承的话,接口反而是最好的选择。
以上是个人在使用过程中的理解,有不对的地方欢迎大家指正、拍砖。 :)