您的位置:首页 > 职场人生

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

2013-11-01 02:25 816 查看
----------------------
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培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐