C#之美—抽象类与接口孽缘

在很久很久以前我们的祖先将我们大自然所有能动的物体都定义成“动物”。但是后来在动物的群体当中,有一类动物进化的非常快,它们的智商明显高出其他动物,它们就是“人类”,这也许就是人类文明的起源。

所谓的“人类”开始给动物定义级别了,他们认为“人类”是最聪明的,从而将自己和普通的动物划分界限并且人类是主导“动物”世界的头领。[王清培版权所有,转载请给出署名]

可是大自然总是充满杀戮,大鱼吃小鱼,小鱼吃虾米。这个时候有个很聪明的“人类”动物他想统治全世界,他想来想去如何对这些动物进行管理,怎么让他们能服从于我。所以他进行策划,想法设法的对这些动物进行分析,观察他们的生活习惯,主动的去跟他们交流。他认为不管是什么动物都将有着本质的特性,这些特性是生命的延续也是动物特征的延续。时间不知道过去了多少,他终于总结出一个让一般动物都很难理解的“抽象”动物图。

有了这张图,他得意的不得了。天上飞的我让他们专门去巡逻,陆地上跑的我让他们全天候的伺候我,水里的就跟好玩了,没事出去游游泳。

显然他没有将人类在这张图中体现出来,完全是高度的抽象。我们也不晓得那个人类是怎么想的,按照我们现在的理解,这个人类应该是继承自这个“陆地上的动物”。但是我们现在还不知道他是怎么想的。

他觉得自己是统治者,所以他不会在图中体现出“人类”的描述。他又进行分析了,他认为我该通过某种方式对这些动物进行管理,也就是说不同类型的动物应该有着不同的行为。比如小鸟是会飞的,我必须用笼子把它关起来。鱼是会乱游,也必须有适当的鱼池让它们生成。

他又回去捣鼓管理方式的图了。

这个“人类”看来对管理没什么经验,按照这种管理方式要累死他呢。所有东西都想一手掌控,在一旁的下手可能有点管理的料,他跟头讲:“头,你这样管理他们可能有点不妥,你应该成立专门的管理群体,专门用来管理或者说是研究不同种类的动物”。这句话还真是给这个头子开悟了,头子突然发觉我似乎有跟强大的武器管理这些乱七八糟的动物了。他交代这个下属去好好策划策划然后给他一个管理的组织架构图。

每个皇帝手下都会有那么几个能干的将领,这个下手还真是有学问,他画了一个他的思路图:

这张图再一次给领导头子开了悟,人类既然是动物的统治者,那么就应该对人类的管理组织架构进行抽象。所以他又交代这个下手去考虑考虑画个图给他看看。

 

领导很喜欢这个图,很清晰的表达出了管理与被管理者之间的界限。两个都有着自己的继承关系,组织机构是针对管理体系的,属于虚拟的继承。而动物的继承体现比较明显点,跟我们的日常生活很像,所以容易理解。通过这个图,思路彻底打开了,要对不同的事务进行归纳抽象,这样才能使事务很清晰很好控制,所谓站的高看的远。[王清培版权所有,转载请给出署名]

这个领导就好像成吉思汗,喜欢打仗喜欢征服感,他要征服全世界,要不然上面的那些规划都白费了,得有动物让他管理才行。所有他开始策划组织军队,不管是天上飞的、地上走的、河里游的只要能打仗都可以参军。他开始全身心的设计参军的标准,这个时候我不管你是什么动物,不管你长什么样子,只要符合参军标准就行了。他找来那个下手,跟下手谈论这宏伟的战略目标,并且任手下为军事参谋,辅助他的军事设计和战略目标规划。经过讨论他们得出一个大致的参军标准图:

标准一贴出去,参谋每天都要亲自审核参军者。有这个标准还真方便,基本上来的动物都符合参军标准。军队逐渐成形了,头子要求军事参谋开始设计作战方案。参谋觉得最重要的就是团队配合,要将团队的力量往一处使。所以他开始设计作战时的手语动作。就好比特种兵在作战时的作战计划,通过手语的方式表达。[王清培版权所有,转载请给出署名]

参谋真是高人,有开始画图了:

有了这个作战手语后,参谋开始想看看效果了。寻找了一个附近的岛屿开始进攻了,经过数日的作战后,终于成功的拿下了小岛,小岛的所有动物都受他管理,并且人类也参与了他们的军队开始循环的扩大军队力量。[王清培版权所有,转载请给出署名]

其实说了这么多,目的只有一个,抽象类和接口是有着本质的区别。抽象类体现在群族、组织等一些列有着很明显的层次结构关系的。比如:组织结构、种族、群集。

接口体现某种契约,是必须要遵守的规则,它不用来表现具有继承关系的抽象。比如:生产标准、产品验收标准。所以如果你将接口也视为对类型的抽象是不妥的,接口没有任何实现目的就是为了在面向对象的领域能严格的区分对象和行为的区别。在IL层面上,接口也是抽象的类行为也是虚方法。目的是让我们站在面向对象的角度使用语言,而语言的特性是为了面向对象的概念做支撑。

下面我们来用代码模拟上述的模型,首先是对动物世界的高度抽象,所以我们当然是需要一个抽象类,表示所有动物的基类。

View Code

/**
 * author:深度训练
 * blog:http://wangqingpei557.blog.51cto.com/
 **/
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace ConsoleApplication1
{
    /// <summary>
    /// 动物的顶层抽象
    /// </summary>
    public abstract class AnimalBase
    {
        /// <summary>
        /// 动物的肤色
        /// </summary>
        public abstract Color Complexion { get; set; }
        /// <summary>
        /// 动物的身高
        /// </summary>
        public abstract int Stature { get; set; }
        /// <summary>
        /// 动物的体重
        /// </summary>
        public abstract int Avoirdupois { get; set; }
        /// <summary>
        /// 吃饭的动作
        /// </summary>
        /// <param name="food">食物对象</param>
        public abstract void Dining(object food);
    }
}

我定义了两个基本的属性,Complexion肤色、Stature身高,还有一个动作Dining就是吃饭。为什么都是抽象的呢?因为我们的抽象层次很高,不同的动物有着不同的身高、不同的肤色、不同的吃饭习惯。所以都是抽象的,表示后面的派生对象能对基类的成员进行具体化。[王清培版权所有,转载请给出署名]

我们派生一个会飞的动物类:

View Code

/**
 * author:深度训练
 * blog:http://wangqingpei557.blog.51cto.com/
 **/
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    /// <summary>
    /// 会飞的动物基类,但是它的祖先是动物类:AnimalBase
    /// </summary>
    public abstract class FlyAnimal : AnimalBase
    {
        /// <summary>
        /// 飞行高度
        /// </summary>
        public abstract int FlyHeight { get; set; }
        /// <summary>
        /// 飞行速度(KM/h)
        /// </summary>
        public abstract float FlySpeed { get; set; }
        /// <summary>
        /// 飞行的行为
        /// </summary>
        public void FlyFun()
        {
            Console.WriteLine("起飞吧.......");
        }
    }
}

在继承了AnimalBase之后,FlyAnimal也就是动物了,但是它增添了很多其他的动物色彩,它是一个会飞动物的基类,只要谁继承它了就会飞了,因为它已经具备飞的能力,至于能飞多高要看孕育的怎么样了呵呵,老鹰一定比麻雀飞的高。[王清培版权所有,转载请给出署名]

我们孕育一只老鹰吧,希望我们都飞的更高:

View Code

/**
 * author:深度训练
 * blog:http://wangqingpei557.blog.51cto.com/
 **/
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    /// <summary>
    /// 老鹰,会飞的。
    /// </summary>
    public class GledeAnimal : FlyAnimal, JoinArmycorps
    {
        private int _flyheight = 1000;
        /// <summary>
        /// 飞的高度,最高为1000米
        /// </summary>
        public override int FlyHeight
        {
            get
            {
                return _flyheight;//能飞1000米高
            }
            set
            {
                _flyheight = value; //完全可以控制它飞多高的,要不然后面的仗怎么打啊;
            }
        }
        private float _flyspeed = 100;
        /// <summary>
        /// 飞行速度,最快为100KM/h
        /// </summary>
        public override float FlySpeed
        {
            get
            {
                return _flyspeed;
            }
            set
            {
                _flyspeed = value; //当然也是可以控制的
            }
        }
        /// <summary>
        /// 肤色,我们定义为羽毛颜色
        /// </summary>
        public override System.Drawing.Color Complexion
        {
            get
            {
                return System.Drawing.Color.Black;
            }
            set
            {
                //颜色哪能换啊
            }
        }
        /// <summary>
        /// 身高,估计也就50CM差不多了
        /// </summary>
        public override int Stature
        {
            get
            {
                return 50;
            }
            set
            {
                //身高似乎可以设置,这里就不支持了。
            }
        }
        /// <summary>
        /// 体重,估计也就50斤左右吧。
        /// </summary>
        public override int Avoirdupois
        {
            get
            {
                return 50;
            }
            set
            {
                //不会是100斤的。
            }
        }

        public override void Dining(object food)
        {
            Console.WriteLine("比较喜欢吃:" + food.ToString());
        }

        public bool Take300KgPoleaxe()
        {
            return true;
        }

        public bool Run60MinuteStanding()
        {
            return true;
        }
    }
}

老鹰作为具体的动物,需要实现所有继承下来的抽象成员,唯独一个会飞的行为不需要实现。

继承真是伟大,一生下来就具备了飞行的能力,但是也得多加练习才行。

老鹰听说现在可以参军了,它觉得自己不去参军简直是浪费,老鹰去看看参军要求,觉得可以实现。

军事参谋的参军要求:

View Code

/**
 * author:深度训练
 * blog:http://wangqingpei557.blog.51cto.com/
 **/
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    /// <summary>
    /// 军事参谋贴出来的参军要求
    /// </summary>
    public interface JoinArmycorps
    {
        /// <summary>
        /// 身高CM
        /// </summary>
        int Stature { get; set; }
        /// <summary>
        /// 体重KM
        /// </summary>
        int Avoirdupois { get; set; }
        /// <summary>
        /// 是否能拿起300KG中的战斧
        /// </summary>
        /// <returns>true:能拿起,false拿不起来</returns>
        bool Take300KgPoleaxe();
        /// <summary>
        /// 快速奔跑持续一小时
        /// </summary>
        /// <returns>true:没问题,false歇菜了</returns>
        bool Run60MinuteStanding();
    }
}

老鹰应该没问题的,它那么厉害;去参谋哪里审核了:

View Code

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //构造老鹰
            FlyAnimal flyanimal = new GledeAnimal();
            flyanimal.FlyFun();
            flyanimal.Dining("兔子肉");//给点兔子肉给你吃

            JoinArmycorps joinarmycorps = flyanimal as JoinArmycorps;
            if (joinarmycorps.Run60MinuteStanding())
            {
                if (joinarmycorps.Take300KgPoleaxe())
                {
                    if (joinarmycorps.Stature > 170)
                    {
                        if (joinarmycorps.Avoirdupois > 80)
                        {
                            Console.WriteLine("合格的军人!");
                        }
                        else
                        {
                            Console.WriteLine("体重不过关!");
                        }
                    }
                    else
                    {
                        Console.WriteLine("身高不过关!");
                    }
                }
            }

            Console.ReadLine();
        }
    }
}

唉 貌似它体重和身高不够啊 呵呵 不过没关系,我们可以孕育大型的老鹰,完全是为了战争而生的,只需要对老鹰的基因进行培养修改。

总结:其实文章要说明的东西基本上也很清楚了,虽然接口也具备属性和行为,但是它和抽象类是有区别的,这里的参军接口就是一种约定一种规范,老鹰必须必须具备这些因素才行。[王清培版权所有,转载请给出署名]

时间: 2024-09-29 09:47:37

C#之美—抽象类与接口孽缘的相关文章

php中抽象类和接口的概念以及区别

本篇文章是对php中抽象类和接口的概念以及区别进行了详细的分析介绍,需要的朋友参考下   复制代码 代码如下: //抽象类的定义: abstract class ku{ //定义一个抽象类 abstract function kx(); ...... } function aa extends ku{ //实现抽象类的方法 function kx(){ echo 'sdsf'; } } //使用方法 $aa=new aa; $aa->kx(); //1.定义一些方法,子类必须完全实现这个抽象中所

Java编程那些事儿68——抽象类和接口(一)

在实际的项目中,整个项目的代码一般可以分为结构代码和逻辑的代码.就像建造房屋时,需要首先搭建整个房屋的结构,然后再细化房屋相关的其它的结构,也像制造汽车时,需要首先制作汽车的框架,然后才是安装配件以及美化等工作.程序项目的实现也遵循同样的道理. 在项目设计时,一个基本的原则就是--"设计和实现相分离".也就是说结构代码和逻辑代码的分离,就像设计汽车时只需要关注汽车的相关参数,而不必过于关心如何实现这些要求的制作.程序设计时也是首先设计项目的结构,而不用过多的关系每个逻辑的代码如何进行实

Java中抽象类与接口的区别

  接口和抽象类有好多相同点和类似点,很多人有过这样的疑问:为什么有的地方必须使用接口而不是抽象类,而在另一些地方,又必须使用抽象类而不是接口呢?或者说,在考虑Java类的一般化问题时,很多人会在接口和抽象类之间犹豫不决,甚至随便选择一种. 理解抽象类 abstract class和interface在Java语言中都是用来进行抽象类(本文 中的抽象类并非从abstract class翻译而来,它表示的是一个抽象体,而abstract class为Java语言中用于定义抽象类的一种方法, 请读者

《java与模式》笔记-----抽象类和接口

笔记 抽象类和接口 什么是接口:接口就是一些方法特征的集合------接口是对抽象的抽象. 什么是抽象类:抽象类对某具体类型的部分实现------抽象类是对具体的抽象. 方法特征包括:方法的名字.参数的数目.参数的类型.不包括:返回类型.参数名字.和抛出的异常. 接口是类型转换的前提.是动态调用的保证.实现某一接口就完成了类型的转换(多重继承):动态调用只关心类型,不关心具体类.          -------------------------------------------------

深入继承之抽象类和接口综合分析及完整案列解说(二)

通过深入继承之抽象类和接口综合分析及完整案列解说(一),我想大家已经认识到了知识共享的巨大力量了.我门上面看到的这些东西不 是我们任何一个人在短时间内就能够总结出来的,但是大家一起总结,那结果就是这样爽的. 我希望大家都能够大方一点,别做得那么 小气,生怕自己知道的那点知识被别人知道了.饭碗就被别人抢了,事实上在跟人分享的过程中并不是一味的在付出,你同样也会有收获,无 论是帮别人解答疑问还是跟别人交流,就好象我在写(或着说我是在复制别人的心得)一样,看起来我是在无偿的为大家做,事实上呢我同样 的

抽象类与接口

和非抽象类一样,抽象类也必须提供在基类列表中出现的所有接口成员的实现.不同的是,抽象类允许将接口的方法映射到抽象的成员方法. interface IMethods { void F(); void G(); } abstract class C:IMethods { public abstract void F(); public abstract void G(); } 上例中,所有C的非抽象的派生类必须重载C中的抽象方法来提供对接口的实现. 注意:显式说明的接口成员不能是抽象的,但它允许调用

Java编程那些事儿70——抽象类和接口(三)

8.9.3 抽象类和接口的比较 抽象类和接口都是进行面向对象设计时专用的设计结构,在实际进行项目设计时,经常需要考虑的问题就是--"使用抽象类还是接口"?下面通过对于抽象类和接口进行简单的比较,熟悉两者之间的区别和联系,从而在实际设计时使用恰当的结构. 1.什么时候使用抽象类或接口? 当设计中为了规范类中方法声明的结构(即类的行为)时,使用抽象类或接口.也就是强制子类对外部提供统一的方法声明时,使用抽象类或接口. 2.抽象类和接口的区别(不同点) a)抽象类是类,而接口是接口. 因为抽

C#中抽象类和接口的区别

一.抽象类: 抽象类是特殊的类,只是不能被实例化:除此以外,具有类的其他特性:重要的是抽象类可以包括抽象方法,这是普通类所不能的.抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们.另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们. 二.接口: 接口是引用类型的,类似于类,和抽象类的相似之处有三点: 1.不能实例化: 2.包含未实现的方法声明: 3.派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括

深入理解抽象类和接口

抽象类和接口是对于面向对象中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才具有了强大的面向对象能力.abstract class和interface之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于abstract class和interface的选择显得比较随意.其实,两者之间还是有很大的区别的,对于它们的选择甚至反映出对于问题领域本质的理解.对于设计意图的理解是否正确.合理.本文将对它们之间的区别进行一番剖析,试图给开发者提