C#学习☞接口
作为一个在学校学习C++, 出了校门想要找一份C++程序员的工作结果被公司要求搞C#工程的苦逼. 我终于走上了一条倚靠微软的不归路...
不过我对学东西是不排斥的. 所以买了本C#与.NET4高级程序设计开始入门.
本来打算一天看100页, 8天内搞定语法部分, 然后投身WPF的. 谁知道客户各种翔一样的要求和突如其来的大量日语夜间培训课程让我的自由时间一下子从东北大馒头缩到了压缩饼干级别.
一周过去了, 我步履缓慢地来到了接口.
--------------华丽丽的分割线-----------------
昨晚上部门长从代理部门长升到了部门长, 请客去吃饭, 吃饭的时候有个朋友闹了个笑话. 因为鸟和蝙蝠都是会飞的, 所以他竟然把鸟也当成有雷达功能的了.
于是我想到一个问题: 鸟真的会飞吗?
首先, 创建一个类"鸟"
public class 鸟 { public string Name { get; set; } public virtual void Show() { Console.WriteLine("我是一只鸟"); } }
接着, 创建"鸟"的子类, "乌鸦", "麻雀", "鸡"(有人说鸡不会飞不是鸟, 鸵鸟笑了), "鸵鸟"(于是他改口说鸡和鸵鸟都不是鸟, 好吧, 请找出他们的膀胱来)
class 乌鸦:鸟 { public override void Show() { Console.WriteLine("我是一只乌鸦"); }
public void fly() { Console.WriteLine("我是一只乌鸦, 我能飞"); } } class 鸽子 : 鸟 { public override void Show() { Console.WriteLine("我是一只鸽子"); }
public void fly() { Console.WriteLine("我是一只鸽子, 我能飞"); } } class 鸡 : 鸟 { public override void Show() { Console.WriteLine("我是一只鸡"); } } class 鸵鸟 : 鸟 { public override void Show() { Console.WriteLine("我是一只鸵鸟"); } }
于是我们有了五个类, 创建一个鸟的数组, 里面分别放入四个子类的对象.
鸟[] birds = new 鸟[] { new 乌鸦(), new 鸵鸟(), new 鸽子(), new 鸡()};
问题, 请问如何取得数组中所有会飞的鸟?
看上面的代码, 是有fly方法的就是会飞的, 那怎么判断一个类是否含有fly方法呢?
办法总是有的, 除了某种高深的能够判断类方法是否存在的方法外, 我们可以先把鸟类分成两类, 一类叫"会飞的鸟", 一类叫"不会飞的鸟".
没办法, 学校学的C++, 想出此种拙计...
可是, 问题拓展了, 因为并不只有鸟才会飞, 飞机也会飞, 蝙蝠也会飞. 新问题: 找出object数组中所有会飞的object.
肿么办?
反射是什么东西? 还没学到, 不清楚.
这个时候该引入接口了.
在C++学习的时候, 暴露给外界的接口就是大家共通的一个纯虚函数, 通常定义在一个由纯虚函数构成的类中, 叫做抽象类.
C#中不支持多个父类, 因为逻辑上程序员对OO的理解就是一棵大树, 树往下走可以有很多分支, 往上走, 只有一条路. 这个也符合生物学等等的门纲目科属的划分规则.
而对于多个类都能实现的动作, C#中就交给了接口去处理. 接口就相当于C++中一个由纯虚函数构成的抽象类. 我就这么去理解了.
定义一个Fly的接口
public interface IFly { void Fly(); }
然后让上面的几个能飞的继承这个接口, 把fly方法改为Fly方法就可以了.
测试Main函数
static void Main(string[] args) { 鸟[] birds = new 鸟[] { new 乌鸦(), new 鸵鸟(), new 鸽子(), new 鸡()}; foreach(鸟 bird in birds) { if (bird is IFly) { (bird as IFly).Fly(); } } Console.ReadLine(); }
如果有其他的类也能飞的话, 只要继承IFly接口, 然后实现飞行Fly方法, 就能通过as或是is关键字判断出来了, 很方便不是.
当然也可以直接强转(IFly)bird, 不会fly的就会抛出一个InvalidCastException异常.