黑马程序员: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培训、期待与您交流! ----------------------
- 黑马程序员:C#基础篇(四)抽象类、接口、继承与多态
- 黑马程序员-java基础 继承、抽象、接口
- Java基础---继承、抽象、接口 (黑马程序员)
- 【黑马程序员】----java基础---继承、抽象、接口
- 黑马程序员-JAVA基础-继承、抽象、接口
- 黑马程序员—JAVA基础之继承、抽象类、接口
- 黑马程序员---Java基础---面向对象:继承、抽象类、接口
- 黑马程序员--java基础复习继承之抽象类与接口
- 黑马程序员————java基础————继承与多态以及抽象类和接口
- 黑马程序员——基础学习(五)继承、多态、抽象类和接口
- 黑马程序员----Java基础第7天(抽象类,继承,final,接口)
- 黑马程序员--继承、抽象类、接口
- 黑马程序员--继承、抽象类、接口
- 黑马程序员--继承、抽象、接口(Java)
- 黑马程序员---面向对象:继承、抽象、接口和多态
- 黑马程序员 ---继承 抽象 接口
- 黑马程序员---继承,抽象,接口
- 黑马程序员--继承 抽象 接口
- button和input type=button的区别及注意事项
- java中instanceof的用法
- ORACLE取前10条数据
- 一批工业机械网站交换友情链接
- 浅谈oracle中row_number() over()分析函数用法
- 黑马程序员:C#基础篇(四)抽象类、接口、继承与多态
- 【算法】快速排序
- hdoj1896 Stones (priority_queue)
- Delphi 常用组件继承关系
- 44,数据库(06)
- JS动态添加事件
- java代码中追踪文件名和行号
- 不进位相加
- Dell OptPlex390 安装Linux