黑马程序员:C#基础篇(四)抽象类、接口、继承与多态

来源:互联网 发布:扎古2.0知乎 编辑:程序博客网 时间:2024/05/01 02:21

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------


抽象类

抽象类与接口主要都是为了实现多态,使用abstract关键字可以创建仅用于继承用途的类和成员。对于接口,从定义就可以发现是对方法的抽象,也可描述成对能力的抽象;而抽象类是 对以事物的抽象,与具体的对象有关。
抽象类的成员与一般类无异,只不过一般定义成抽象的,给派生类重写,从而实现多态,一般定义的抽象成员有方法,事件,属性,索引器。抽象类的构造函数主要是为了对非抽象成员的初始化”抽象类是不能实例化的“,派生类会默认调用父类的无参构造函数,因此其也不能是私有的。例子:

    delegate void MyDelegate();    abstract class MyClass    {        public abstract void Func();//抽象成员必须是公共的        public abstract string AttriBute        {            get;//可以只有一个访问器            set;        }        public abstract string this[int num]        {            get;//与属性类似            set;        }        public abstract event MyDelegate BaseEvent;    }    class MyClass1:MyClass    {        public override string AttriBute        {            get            {                return "123";            }            set            {                Console.WriteLine(value);            }        }        public override string this[int num]        {            get            {                return num.ToString();            }            set            {                Console.WriteLine(value);            }        }        public override void Func()        {            Console.WriteLine("123");        }        public override event MyDelegate BaseEvent;//自动补全add,remove访问器   }
抽象类的抽象成员可以自定义的,也可以来自接口,也可以来自某个基类。将基类的虚方法用abstract修饰,例子:

    interface IMyInterface    {        string Attribute        {            get;        }    }    class TestClass    {        public virtual void Func()        {             //...        }    }    abstract class BaseClass : TestClass, IMyInterface    {        public abstract string Attribute        {            get;//实现接口成员             set; //自定义抽象成员        }        public abstract new void Func();//隐藏父类成员    }

接口

接口主要为了实现多态和多继承。接口的特点:

(1)类或结构可继承多个接口

(2)当类或接口继承接口时继承成员定义,但不继承实现

(3)类似抽象基类,继承接口的任何非抽象类型都必须实现接口的所有成员

(4)不能直接实例化

(5)可以包含事件、索引器、属性和方法

(6)不包含方法的实现

(7)类和接口可从多个接口继承

(8)自身可从多个接口继承

若要实现接口,类中的对应成员必须是公共的且非静态的,并且与接口成员具有相同的签名和名称。
实现接口的类分三种,一是抽象类,二是一般的类,再就是结构. 而实现方式又分为实 现接口和显式实现接口。

    interface IMyInterface    {        void Func();        string this[int index] { get; set; }        string Value { get; set; }        event EventHandler MyEventHandler;    }    public abstract class MyClass : IMyInterface     {          public void Func()         {         // 实现代码         }         public string Value {  get;  set; }         public event EventHandler MyEventHandler;         public string this[int index]         {              get             {                // 实现代码             }             set             {                 // 实现代码             }         }    } 
此处的属性与接口中的属性意义是不同的,此处为自动属性,在代码的后台编译器 会自动生成一个字段,并填补 get 和 set 读取器. 。此处的事件也与接口中的事件意义不同(从代码角度看几乎一样),这里的事件,编 译器会自动生成一个同名的私有委托,并将 add 方法与 remove 方法补全。 

如果不希望具体实现接口成员,只要前面加abstract就行。

    public abstract class MyClass : IMyInterface     {        public abstract void Func();        public abstract string Value {  get;  set; }         public abstract event EventHandler MyEventHandler;        public abstract string this[int index] { get; set; }    } 

显示实现的话(1)显示实现的接口,不允许有访问修饰符 (2)事件不允许使用默认系统自定义的方式,需要自己添加 add 方法和 remove 方法(3)另外显示实现接口的成员不允许使用 abstract 进行修饰.。

    public abstract class MyClass : IMyInterface     {        void IMyInterface.Func()          {              // 方法体        }          string IMyInterface.Value  {   get;   set;  }          event EventHandler IMyInterface.MyEventHandler          {              add             {                   // 实现代码             }             remove             {                // 实现代码             }         }        string IMyInterface.this[int index]        {            get            {                // 实现代码             }            set            {                // 实现代码            }        }    } 

封装继承多态

封装

封装就是指将数据和基于数据的操作封装在一起,数据被保护在类型的内部,系统的其他部分只有通过包裹在数据外面的被授权的操作,才能够与这个数据类型交流与交互。

sealed关键字可以防止派生。用在类上可以防止类的派生,用在成员上可以中断成员的继承。

继承

继承会继承父类的所有公共成员,子类中可以隐藏,可以重写,例子:

    class A    {        public string str = "A";        public void Show()        { Console.WriteLine("Show A"); }    }    class B:A    {        public string str = "B";        public virtual void Show()        { Console.WriteLine("Show B"); }    }    abstract class C:B    {        public abstract void Show();//这叫隐藏        //public override void Show()//这叫重写        //{ Console.WriteLine("Show C"); }//抽象类可以继承类或接口,可以重写虚方法也可以不重写,但是抽象成员如果继承了则必须被重写    }    class D:C    {        public string str = "D";        public override void Show()//必须重写抽象成员,虚方法就可以不重写        { Console.WriteLine("Show D"); }    }    class MyClass    {        static void Main(string[] args)        {            D d = new D();            C c = d;            B b = d;            A a = d;            Console.WriteLine(d.str);//D            Console.WriteLine(c.str);//B            Console.WriteLine(b.str);//B            Console.WriteLine(a.str);//A            Console.WriteLine();                        d.Show();//D            c.Show();//D            b.Show();//B            a.Show();//A            Console.ReadKey();        }

多态

多态,通过继承一个类或接口可以用做多种类型,如可以用做自己的类型、任何基类型、或者在实现接口时用做接口类型,这称为多态性,例子:

    abstract class Myclass    {        public abstract void Func();    }    class A : Myclass    {        public override void Func()        {            Console.WriteLine("我是A");        }    }    class B : Myclass    {        public override void Func()        {            Console.WriteLine("我是B");        }    }    class C : Myclass    {        public override void Func()        {            Console.WriteLine("我是C");        }        static void Main(string[] args)        {            List<Myclass> list = new List<Myclass>();            list.Add(new A());            list.Add(new B());            list.Add(new C());            foreach (Myclass item in list)            {                item.Func();            }            Console.ReadKey();        }    }


---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

原创粉丝点击