Unity框架一个比较重要的一个技术:面向接口编程
接口原理:首先接口在表面上是由几个没有主体代码的方法定义组成的集合体,有唯一的名称,可以被类或其他接口所实现(或者也可以说继承)。接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。*
eg;在自然界中,人都能吃饭,即“如果你是人,则必须能吃饭”。那么模拟到计算机程序中,就应该有一个IPerson(习惯上,接口名由“I”开头)接口,并有一个方法叫Eat(),然后我们规定,每一个表示“人”的类,必须实现IPerson接口,这就模拟了自然界“如果你是人,则必须能吃饭”这条规则。
思想:基于设计模式以及架构中的一个重点,面向接口编程和面向对象编程并不是平级的,它并不是比面向对象编程更先进的一种独立的编程思想,而是附属于面向对象思想体系,属于其一部分。或者说,它是面向对象编程体系中的思想精髓之一。
那么到底神马是面向接口编程呢?
在系统分析和架构中,分清层次和依赖关系,每个层次不是直接向其上层提供服务(即不是直接实例化在上层中),而是通过定义一组接口,**仅向上层暴露其接口功能,上层对于下层仅仅是接口依赖,而不依赖具体类。**这样做的好处是显而易见的,首先对系统灵活性大有好处。当下层需要改变时,只要接口及接口功能不变,则上层不用做任何修改。甚至可以在不改动上层代码时将下层整个替换掉,所以这就是面向接口编程好处。接下来看一下接口编程的eg:
//==========================
// - FileName: Iinterface.cs
// - Created: true.
// - CreateTime: 2020/02/29 16:36:57
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IHero
{
//英雄技能
void SkillisE();
}
//==========================
// - FileName: Leblanc.cs
// - Created: true.
// - CreateTime: 2020/02/29 17:47:44
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Leblanc : IHero
{
public void SkillisE()
{
Debug.Log("Leblanc技能 E");
}
}
//==========================
// - FileName: IOP.cs
// - Created: true.
// - CreateTime: 2020/02/29 18:31:10
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IOP : MonoBehaviour
{
private void Start()
{
//向上转型
IHero hero = new Leblanc();
hero.SkillisE();
}
}
这里设计到一个向上转型,向上转型是自由的;向下转型是有约束条件的。
非抽象继承,子类对象、父类对象的方法都能调到(用子类对象能调到子类对象的方法,用父类对象能调用父类对象的方法)。
那么这里会输出:
Leblanc技能 E
再往下面走:
假如我们的英雄需要一个 Hp或者是 Mp的话,那么我们的接口就无法进行定义属性的、那么我们还是想进行添加该怎么办呢?所以这里需要提供一个基类,把英雄的属性放在这个基类中,让这个基类继承自接口
//==========================
// - FileName: Iinterface.cs
// - Created: true.
// - CreateTime: 2020/02/29 16:36:57
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface IHero
{
//英雄技能
void SkillisE();
}
抽象出一个基类进行管理
//==========================
// - FileName: BaseHero.cs
// - Created: true.
// - CreateTime: 2020/02/29 18:54:58
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseHero : IHero
{
//考虑到数据的安全性,所以这里写成只能读。不能取(改)
public int Hp { get; private set; }
public virtual void SkillisE()
{
Debug.Log("玩家按下了 E");
}
}
//==========================
// - FileName: Leblanc.cs
// - Created: true.
// - CreateTime: 2020/02/29 17:47:44
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Leblanc : BaseHero
{
public override void SkillisE()
{
//base.SkillisE();
Debug.Log("Leblanc技能 E");
}
}
//==========================
// - FileName: IOP.cs
// - Created: true.
// - CreateTime: 2020/02/29 18:31:10
// - Email: [email protected]
// - Region: China WUHAN
// - Description:
//==========================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IOP : MonoBehaviour
{
private void Start()
{
//向上转型
BaseHero = new Leblanc();
hero.SkillisE();
//考虑到上面的数据加密所以这里只能读并不能获取
Debug.Log(hero.Hp);
}
}
所以这里的话最后就会输出:
玩家按下了 E,
0
反之如果不把 base.SkillisE();进行注释的话
玩家按下了 E,
Leblanc技能 E,
0
最后说白了一大堆就是体现出一个道理,面向接口编程会给我们 的程序更加具有规范性和灵活性。
最后可以看一看这边文章:很精辟
https://www.cnblogs.com/leoo2sk/archive/2008/04/10/1146447.html