博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理
抽象类:又叫抽象基类(之所以说是抽象基类,是因为它仅用于继承用途):它在定义的时候使用 abstract 关键字标记的一般类.他可包含一般类所包含的所有特性,例如,字段,属性,方法,另外他还包含一个很特殊的方法,叫抽象方法(这些方法基本上是没有执行代码的签名,而派生于该类的的类就必须提供执行的代码).同时,抽象类不能被实例化,他主要用在类的定义和部分实现这方面,所以它需要在扩充类中完整的扩充并实现功能.          抽象方法: 当类中的方法在声明的时候加上 abstract 关键字的时候,他就被我们称为抽象方法(abstract method)          小天:等等,按照你这种说法,我没觉得有学习这个东西的必要。反正不就是用来做基类嘛,方法还不实现,我看这压根就是个鸡肋。          老田:话不是你这样说的。在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是反过来却不是这样。并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表现我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。正是因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。

 

在面向对象编程的过程中,抽象类主要用来进行类型隐藏。我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。熟悉OCP的读者一定知道,为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

抽象类不能实例化。抽象类的用途是为多个派生类提供可共享的基类的公共定义。例如,类库可以定义一个作为其多个函数的参数的抽象类,并要求程序员使用该库通过创建派生类来提供自己的类实现。

       小天:好了,打住,我明白了。直接告诉我怎么用和注意事项就行了,太过理论的,我现在的水平也听不懂。

       老田:好吧,下面代码说明了申明抽象类和抽象方法的语法

    public abstract class A         //用修饰符abstract将类修饰为抽象类

{

    //用修饰符abstract将类成员修饰为抽象成员

    //注意,抽象方法没有实现体(就是没有方法体)

        public abstract void GoTo();//用修饰符abstract将类成员修饰为抽象成员

    }

    //继承并实现上面抽象类的派生类

    public class B : A

    {

        public override void GoTo() //也使用override关键字来实现抽象基类中的抽象方法

        {

            //实现上面抽象方法

        }

    }

抽象方法没有实现,所以方法定义后面是分号,而不是常规的方法块。抽象类的派生类必须实现所有抽象方法。当抽象类从基类继承虚方法时,抽象类可以使用抽象方法重写该虚方法。例如:

    public class D

    {

        public virtual void DoWork(int i)

        {

            // 这是一个虚方法

        }

    }

    //用抽象类 E 来继承类 D

    public abstract class E : D

    {

        //下面的抽象方法用重写关键字override来重写基类的虚方法

        public abstract override void DoWork(int i);

    }

    //普通类 F ,继承抽象类 E

    public class F : E

    {

        public override void DoWork(int i)

        {

            //再一次用重写来实现抽象类 E 中的虚方法

        }

    }

    小天:还可以将abstractoverride组合起来用啊?那能不能把abstractvirtual组合起来做一个抽象虚方法呢?

老田:第一次听见抽象虚方法这个说法,有创意。不过在抽象方法声明中使用 static virtual 修饰符是错误的。

继承抽象方法的类无法访问该方法的原始实现。在上个示例中,类 F 上的 DoWork 无法调用类 D 上的 DoWork。在此情况下,抽象类可以强制派生类为虚方法提供新的方法实现。

抽象类具有以下特性:

·         抽象类不能实例化。

·         抽象类可以包含抽象方法和抽象属性,也可以包含普通的类成员。

·         只要一个类中有一个抽象方法,那么这个类就必须是抽象类。

·         不能用 sealed修饰符修改抽象类,这意味着抽象类不能被密封。

·         从抽象类派生的非抽象类必须实现全部的抽象方法和抽象属性,包括继承来的。

 

在方法或属性声明中使用 abstract修饰符以指示方法或属性不包含实现。抽象方法具有以下特性:

·         抽象方法是隐式的虚方法。

·         只允许在抽象类中使用抽象方法声明。

·         因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })

·         实现由一个派生类中的方法来实现,重写的方法用override关键字,此重写方法是非抽象类的一个成员。

·         子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。也可以不实现抽象方法,留给后代实现,这时子类仍旧是一个抽象类,必须声明为abstract

·         继承的抽象方法不可以被隐藏。

·         在抽象方法声明中使用 static virtual 修饰符是错误的。

 

 

     除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。

·         在静态属性上使用 abstract修饰符是错误的。

·         在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。

 

最后一个很有必要单独提醒的是,实现抽象方法(在派生类中重写基类的抽象方法)必须与被实现的抽象方法的返回类型、方法名、参数(顺序和类型)都完全相同,不同的是使用的abstractoverride这两个关键字的不同。


本文章为天轰穿原创作品,转载请注明出处及作者。
课程地址链接:http://www.ixueyun.com/kcb/02/