抽象与接口(七)

抽象类与接口

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.接口于抽象类

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

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

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

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

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

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

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

posted @ 2011-10-14 17:37  放眼世界  阅读(375)  评论(0编辑  收藏  举报