• 抽象与接口(七)


    抽象类与接口

    1.抽象类

    举个例子:去书店买书。这句话描述的就是一个抽象行为,但底是去哪家书店,买什么数。“去书店买书”这句话中,并没有买书行为必须包含的确定信息,如果将去书店买书这个动作封装为一个行为类,那么这个类就应该是一个抽象类。

    注:1.C#中规定,类中只要有一个方法声明为抽象方法,这个类也必须声明为抽象类。

    2.抽象类中不一定所有方法都是抽象方法或抽象属性。

    抽象类具有以下特性:     

    l  抽象类不能被实例化。

    l  抽象类可以包含抽象方法和抽象的访问器。

    l  不能用sealed修饰符修饰该抽象类,这意味着抽象类不能被继承。

    l  从抽象类派生的非抽象类,必须包括继承的所有抽象方法和抽象访问器的实现。

    l  在方法或属性声明中用abstract修饰符,以指示方法或属性为抽象方法或抽象属性。

    抽象方法具有下列特性:

    l  抽象方法是隐式的虚方法(virtual),所以在实现抽象方法或抽象属性时需要用override来修饰实现方法或实现属性。

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

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

    l  实现由一个重载方法提供,此重载方法是非抽象类的成员。

    l  在抽象方法声明中使用staticvirtual修饰符是错误的。

    l  抽象属性必须写访问器。

    l  如果继承了某个抽象类,那么就要实现抽象类里面所有的抽象方法和属性(除非继承类也是抽象类)。

    注:如果一个没有用Abstract修饰的类继承了一个抽象类,但是并没有全部实现抽象类里面所有的抽象方法和属性,那么这个类就会被默认为抽象类(尽管没有用Abstract修饰)。

    在设计和声明一个抽象类时,注意:不要在抽象类中定义公共或内部受保护的构造函数。如果需要构造函数,应该在抽象类中声明为受保护的或内部构造函数。应该至少提供一个该抽象类的具体实现。

    定义了抽象方法或抽象属性,那么在继承类中就必须为抽象类

    //定义一个抽象类

    public abstract class Shape

        {

          public abstract float area();

          public abstract string Why//抽象属性必须写访问器,不然会报错,不能实现抽象属性。

          {

              get;

              set;

          }

          public void pring()

          {

              Console.WriteLine(Why);

          }     

        }

    //继承抽象类,并实现抽象里面所有的抽象方法和属性。

    public class Rectangle : Shape

        {

            private int length;

            private int width;

            private string why;

     

            public override string Why

            {

                get

                {

                    return why;

                }

                set

                {

                    why = value;

                }

            }

            public Rectangle(int length, int width)       //构造器

            {

                this.length = length;

                this.width = width;

            }

            public override float area()                   //计算面积

            {

                return (float)(length * width);

            }

            public void showArea()

            {

                Console.WriteLine(Why);

                Console.WriteLine("正方形面积为:" + area() + "\n");

            }

    }

    //主类

    class Program

        {

            static void Main(string[] args)

            {

                Rectangle rectangle = new Rectangle(1, 2);          

                rectangle.Why = "这是什么啊?";

                rectangle.showArea();           

                Console.Read();

            }

        }

    2.接口

    接口提供了一种契约,让使用接口的用户必须严格遵守接口提供的约定。

    接口具有下列属性:

    l  接口类类似于抽象类,继承接口的然后非抽象类型都必须实现接口的所有成员

    l  不能直接实例化接口。

    l  接口可以包含事件、索引器、方法和属性。

    l  接口不包含方法的实现,而抽象类可以包含方法的实现。

    l  类和结构可以多个接口继承。

    l  接口自身也可以从多个接口继承。

    l  接口的成员必须是方法、属性、事件或索引器

    l  接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型,也不能包含任何种类的静态成员。

    l  接口成员声明包含任何修饰符都十余编译时错误。集体来说就是不能用任何修饰符来修饰接口中的成员。

    l  所有接口成员都隐式地具有public访问属性。

    l  关键字Abstractsealedvirtualstatic不能在接口中使用,因为这两个修饰符在接口定义中是没有意义的(它们不包含执行代码,所以不能直接实例化,且必须是可以继承的)

     注:在定义接口中不能用virtual Abstractsealed关键字来修饰接口中的属性或方法,但是可以在实现接口的类中使用。在实现接口的类中使用virtual的作用就在于将该类为基类时,子类对实现重写(父类实现了接口,子类自然拥有接口中的方法,而通过重载父类中的方法来表现自己的方法)

    接口不能单独存在,不能像实例化一个类那样实例化接口。

     

    如:

    public  interface Shap

        {

           float area();      接口中不能用关键字virtual来修饰。

        }

    public  class Rectangle:Shap //继承接口

        {

           public virtual float area()   //实现接口可以用virtual关键字来修饰,

            {

                return (float)(2 * 3);

            }

    }

    //一个接口

    public  interface Shap

        {

           float area();     

        }

    public  class Rectangle:Shap //继承接口

        {

            public int length;

            public int width;

     

            public Rectangle(int length, int width)       //构造器

            {

                this.length = length;

                this.width = width;

            }

            public float area()          //实现接口

            {

                return (float)(length * width);

            }

            public void showArea()

            {

                Console.WriteLine("面积为:" + area() + "\n");

            }      

        }

    //主类

    class Program

        {

            static void Main(string[] args)

            {

                Rectangle rectangle = new Rectangle(1, 2);          

                rectangle.showArea();           

                Console.Read();

            }

        }

    3.接口于抽象类

    抽象类可以拥有抽象成员(没有代码体)和非抽象成员(它们拥有代码体,也可以是虚拟的,这样就就可以在派生类里面重写)。接口成员必须都在使用接口的类上实现——它们没有代码体。

    接口成员是公共的(因为它们倾向于外部使用),但抽象类的成员可以是私有的(只要它们不是抽象的)、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。此外,接口不能包含字段、构造函数、析构函数、静态成员或常量。

    抽象类用于部分实现一个类,再由用户按需求对其进行不同的扩展和完善;接口是定义一个行为的规范或规定。

    抽象类在组建的所有实现间提供通用的已实现功能;接口创建在大范围全异对象间使用的功能。

    抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。

    抽象类主要用于设计大的功能单元;而接口用于设计小而简练的功能块。

    说明:抽象类主要用作对象系列的基类,共享某些主要特性,例如共同的目的或结构,接口则主要用于类,这些类的基础水平上有所不同,但仍可以完成某些相同的任务。

  • 相关阅读:
    C#多线程操作界面控件的解决方案
    InvokeHelper,让跨线程访问/修改主界面控件不再麻烦
    .netCF中后台多线程与UI界面交互的冻结问题
    c#设计模式第一天
    C#代理
    界面
    第一章面向对象涉及原则
    C# 为webBrowser设置代理
    设计模式等
    下载: Intel® 64 and IA32 Architectures Software Developer Manuals
  • 原文地址:https://www.cnblogs.com/wenwei/p/2212459.html
Copyright © 2020-2023  润新知