zoukankan      html  css  js  c++  java
  • 抽象基类与接口

    5.1抽象类与抽象方法

          在一个类前面加上abstract”关键字,此类就成为了抽象类。

          对应地,一个方法类前面加上abstract”关键字,此方法就成为了抽象方法。

          注意抽象方法不能有实现代码,在函数名后直接跟一个分号。

          抽象类专用于派生出子类,子类必须实现抽象类所声明的抽象方法,否则,子类仍是抽

    象类。

          抽象类一般用于表达一种比较抽象的事物,比如前面所说的水果,而抽象方法则说

    明此抽象类应该具有的某种性质,比如 Fruit类中有一个抽象方法  GrowInArea(),说明水果

    一定有一个最适合其生长的地区,但不同的水果生长地是不同的。

          从同一抽象类中继承的子类拥有相同的方法(即抽象类所定义的抽象方法),但这些方

    法的具体代码每个类都可以不一样,如以下两个类分别代表苹果(Apple)和菠萝(Pineapple):

    class Apple : Fruit //苹果

    {

            public  override void  GrowInArea()

         {

              Console.WriteLine("南方北方都可以种植我。");

         }

    }

    class Pineapple : Fruit //菠萝

    {

          public  override void  GrowInArea()

       {

           Console.WriteLine("我喜欢温暖,只能在南方看到我。");

        }

    }

          注意上述代码中的 override关键字,这说明子类重写了基类的抽象方法。抽象类不能创

    建对象,一般用它来引用子类对象。

    Fruit f;

    f = new  Apple();

    f.GrowInArea();

    f = new  Pineapple();

    f.GrowInArea();

          运行结果:

    南方北方都可以种植我。

    我喜欢温暖,只能在南方看到我。

          注意同一句代码f.GrowInArea();”会由于 f所引用的对象不同而输出不同的结果。可

    以看到,代码运行结果类似于上一节介绍的虚方法调用,两者没有本质差别。

          可以按照以下公式编写代码:

                 抽象类 抽象类变量名=new 继承自此抽象类的具体子类名();

          一个抽象类中可以包含非抽象的方法和字段。因此:

          包含抽象方法的类一定是抽象类,但抽象类中的方法不一定是抽象方法。

    5.2抽象属性

          除了方法可以是抽象的之外,属性也可以是抽象的,请看以下代码:

    abstract class  Parent

    {

            public abstract String Message   //抽象属性

       {

              get;

              set;

        }

    }

    class Child :  Parent

    {

              private String  _msg;

              public override  String  Message

          {

                get

          {

               return _msg;

           } 

          set

       {

             _msg=value;

        }

      }

    }

    5.3接口

          来看以下这句话:

          鸭子是一种鸟,会游泳,同时又是一种食物。

          如何在面向对象的程序中表达这种关系?

          如果使用 C++,可以设计成让鸭子(Duck)类继承自两个父类(鸟 Bird和食物  Food)。

    但在 C#中所有的类都只能有一个父类,此方法不可行。

          为了解决这一问题,C#引入了接口(interface)这一概念,并规定一个类可以实现多

    个接口”

    (1)接口的定义与使用

          关键字 interface用于定义接口(示例项目  InterfaceExamples):

     

     

          请读者仔细地阅读上述代码的注释,由于 Duck类继承自抽象基类  Bird,又实现了  ISwim

    和 IFood两个接口,所以,Duck对象拥有这三者所定义的所有方法,并且可以赋值给这三

    种类型的变量。

          需要注意的是,虽然程序中始终都只有一个 Duck对象,但将其赋值给不同类型的变量

    后,其可以使用的方法是不一样的。

    (2)显式实现接口

          上面讲到,某个类可以实现多个接口,当创建一个此类的对象之后,通过引用这个对象

    的对象变量可以访问其所有的公有方法(包括自身的公有方法以及由接口定义的公有方法

    以)。在这种情况下,根本分不清哪些方法是由接口定义的,哪些是由类自己定义的。C#提

    供了一种显式接口实现机制,可以区分开这两种情况,一个示例代码如下:

    interface  IMyInterface

    {

           void func();

     }

    public class  A:IMyInterface

    {

             void IMyInterface.func()

          {

                       //……

           }

    public void func2()

    {

            //……

     }

    }

          请注意在方法 func前以粗体突出显示的接口名称,这就是  C#对接口 IMyInterface的显

    式实现方式。

          当类 A显式实现接口  IMyInterface之后,只能以下面这种方式访问接口定义的方法:

    IMyInterface  a = new  A();

    a.func();

          以下代码将不能通过编译:

    A  a = new  A();

    a.func();

          由此得到一个结论:

          如果一个类显式实现某个接口,则只能以此接口类型的变量为媒介调用此接口所定义

    的方法,而不允许通过类的对象变量直接调用。

          或者这样说:

          被显式实现的接口方法只能通过接口实例访问,而不能通过类实例直接访问。

  • 相关阅读:
    函数和常用模块【day06】:shutil模块(四)
    函数和常用模块【day06】:time模块 (一)
    函数和常用模块【day05】:生成器并行计算(五)
    函数和常用模块【day05】:装饰器前奏(一)
    函数和常用模块【day04】:内置函数(八)
    函数和常用模块【day04】:作用域、局部和全局变量(四)
    函数和常用模块【day04】:函数的非固定参数(三)
    Python基础【day02】:元组和购物车练习的知识点
    Python基础【day02】:字符串(四)
    Python基础【day03】:入门知识拾遗(八)
  • 原文地址:https://www.cnblogs.com/LCL390/p/4300925.html
Copyright © 2011-2022 走看看