C#锐利体验 第十讲 接口、继承与多态

转载 2004年09月06日 00:50:00

第十讲 接口 继承与多态

接口
???????接口定义对象成员的合同,是现代组件编程不可缺少的一环。C#采用关键字“interface”来创建接口。接口作为一种类型,它也具有其他类型所共有的五种存取修饰和new重定义修饰符。接口可以包含方法,属性,事件,索引器四种成员,接口本身只能声明这些成员,不必也不能提供这些成员的具体实现。C#不允许我们为接口成员做任何存取修饰,接口成员的存取修饰缺省为public——接口本来就是我们为其他类型定义的一种成员合同,对他们进行存取限制不符合我们应用接口的初衷。同样的道理,C#也不允许对接口做“abstract, virtual, override, static”修饰。下面是接口类型声明的一个典型的例子:

public delegate void StringListEvent(IStringList sender);
public interface IStringList
{
???void Add(string s);//方法
???int Count { get; }//只读属性
???event StringListEvent Changed;//事件
???string this[int index] { get; set; }//索引器
}??
???????
注意这里我们将接口名称写成IStringList,其中的大写字母“I”仅仅是.NET平台的命名约定,而非必须。
???????接口作为一种用于“合同”的类型不可以象类那样实例化,我们说一个数据是某个接口类型,我们是指该类型实现了某个接口。C#中类或结构可以实现多个接口,实现了接口的类型必需提供相应接口成员的实现。
interface ICloneable
{
???object Clone();
}
interface IComparable
{
???int CompareTo(object other);
}
class ListEntry: ICloneable, IComparable
{
???public object Clone() {...}// ICloneable接口实现
???public int CompareTo(object other) {...}// IComparable接口实现
}??
???????接口之间可以继承,一个接口可以继承自多个接口。直接或间接继承自己都会引起编译时错误。下面是一个接口继承的例子:
interface IControl
{
???void Paint();
}
interface ITextBox: IControl
{
???void SetText(string text);
}
interface IListBox: IControl
{
???void SetItems(string[] items);
}
interface IComboBox: ITextBox, IListBox {}????
???????通过继承,接口IComboBox拥有Paint,SetText,SetItems三个方法合同。多接口继承可能会带来同名成员冲突的问题,C#通过明晰转型来解决这个问题。看下面的例子:
interface IList
{
???int Count { get; set; }
}
interface ICounter
{
???void Count(int i);
}
interface IListCounter: IList, ICounter {}
class C
{
???void Test(IListCounter x) {
??????x.Count(1);????????????????// 错误!命名冲突
??????x.Count = 1;???????????????// 错误!命名冲突
??????((IList)x).Count = 1;?????????// 正确!调用IList.Count.set
??????((ICounter)x).Count(1);??????// 正确!调用ICounter.Count
???}
}

???????注意这种明晰转型是在编译时进行的,并不会带来任何程序运行的代价。上面的例子用IListCounter接口作为方法Test的参数类型,但我们知道接口是不可以实例化的类型,我们该怎样传递这样的参数呢?答案是传递直接或间接实现了该接口的类或结构的对象实例。

继承
???????继承是面向对象的三大特征之一(另外两个是封装和多态),在组件编程中有相当的应用。C#为我们提供两种继承机制——类继承和接口继承。类继承只允许每个类有一个父类(即单继承),而接口继承却允许一个类或接口可以同时继承(又称实现)多个接口。类不可以被接口继承。
在C#中类继承是指通过继承子类将拥有除父类的实例构造器,静态构造器和析构器以外的所有的成员。注意这里的“拥有”和“可见性”是两个概念。拥有某个成员是指该成员确确实实地存在于该类中,但如果该成员的保护级不允许该成员在继承子类中可见(比如private,internal),我们将不能在子类中对他们进行操作——但这不表示他们不存在。下面的例子清晰地说明了这一点:
class A
{
????int count;
????public int Count
????{
????????get {return count;}
????????set {count=value; }
????}
}
class B:A
{}
class Test
{
????public static void Main()
????{
????????B b=new B();
????????b.Count=39;
????????System.Console.WriteLine(b.Count);
????}
}
???????count变量在A中为private,在B中不可见,但通过公有属性Count的存取,我们可以清晰地感觉到它的存在。
子类在继承的同时可以添加新的类成员。new关键字可以使子类在继承的时候屏蔽同名的父类成员,注意这里屏蔽的意思同样是“不可见”,而非“去除”。
我们可以用类修饰关键字abstract和sealed来控制类继承时的行为。abstract使得该类只能被子类继承,而不能被实例化。sealed不允许该类被继承,使得继承树“到此为止”。
接口继承由于所有的成员都为public,它的行为比较简单,仅仅是继承所有接口的成员。和类继承相同的地方是new关键字同样可以屏蔽同名成员。

多态
???????多态是指为同名的方法提供不同的实现的能力,它使得我们不用关心方法的具体实现而仅仅依靠其名称来进行调用操作。比如我们现在有一个Road的类需要调用Drive方法,不管我们有什么样的车,Bike,Car,Jeep,尽管他们的Drive方式不同,但只要他们有Drive方法,我们的Road就可以调用他们的Drive方法使他们在上面“行驶”。多态集中体现了对象世界的共同行为。C#为我们提供了三种多态能力:接口多态,继承多态,抽象多态。
???????接口定义一个类型需要实现的方法,属性,索引和事件,包括可能的参数类型和返回值类型,而把具体的实现交由相应的类或结构来做,从而为组件提供多态能力。接口多态不仅为组件提供一个更好的逻辑功能的聚合方式,也为组件的多版本提供了很好的支持。随着组件规模的不断增长,需要的成员越来越多,将所有的成员简单地封装在一个组件内既不符合我们的逻辑思维方式,更会带来烦恼的版本问题。而将这些成员分解成多个聚合的逻辑块,然后采用接口的形势将他们进行封装,这种方式很好地解决了组件在设计和维护两个方面的问题。接口多态在现代软件开发中有着广泛的应用。
???????类继承使得子类自动拥有父类大多数的成员,C#允许我们通过普通的类继承来为组件提供多态能力。继承常用于在一个现有父类的基础上的功能扩展,往往是我们将几个类中相同的成员提取出来放在父类中实现,然后在各自的子类中加以继承。“子类 is a 父类,苹果 is a水果”是继承多态的经典测试用语。继承对于小规模的软件开发多有裨益,但在现代集群组件开发模式下,由于常常引入晦涩的逻辑误用和不必要的编码负担,它往往不被推荐使用。
???????抽象多态是指通过abstract(抽象)类同时实现继承和接口的多态功能。抽象类中既可以包括实现了的成员,也可以是仅仅提供成员接口而没有具体实现。抽象类不能被实例化,必须在其继成类中实现相应的接口,否则子类也应被标志为abstract。抽象类在为其子类提供一个恒定的功能集的同时,也为其子类提供了一个具备扩展能力的弹性接口。抽象类在组件的初始设计时非常有用,但由于类不能进行多继承,它的多态能力较之接口多态要有所损失。

C# 继承、接口与多态

C# 继承、接口与多态   我在这里想谈一谈在C#中的继承(继承于基类或接口)和多态(如方法的覆写)。继承和多态是面向对象编程中两个重要的特性,这种特性和编程语言本身是没多大关系的,因此我先会用非编...
  • Froser
  • Froser
  • 2014年03月26日 18:27
  • 1213

C#中的继承与多态还有接口

简单继承多态接口参考 简单继承 最简单的三个类 [csharp] view plain copy print? public class Animal {      public...
  • u011555996
  • u011555996
  • 2016年11月10日 11:25
  • 561

C#中的继承与多态还有接口

简单继承最简单的三个类public class Animal { public Animal() { Debug.Log("Construct Animal!"); ...
  • qp120291570
  • qp120291570
  • 2016年02月11日 17:35
  • 3646

C#中的继承封装和多态知识点总结

一、  封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类)。被封装的对象通常被称为抽象数据类型。 面向对象程序设计中一般以类作为数据封装...
  • xjc1278003262
  • xjc1278003262
  • 2013年03月01日 10:29
  • 2768

对接口、继承、组合、多态的理解

面向对象设计的原则 1、针对接口编程,而不是针对实现编程 2、优先使用对象组合,而不是类继承 继承    当子类继承父类时,子类包含了父类定义的所有数据和操作,子类的实例包含了所有子类和父类定...
  • gds2014
  • gds2014
  • 2016年02月28日 19:12
  • 916

1.面向对象编程思想(封装继承多态接口)

封装: 1.定义:隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。 2.封装的目的是:增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,一...
  • u014252871
  • u014252871
  • 2016年11月28日 09:22
  • 2066

Java运行时多态性:继承和接口的实现

转载地址:Java运行时多态性:继承和接口的实现 Java做为一个面向对象语言的最强大机制:运行时多态性。两个实现方式分别是继承和接口。Java是面向对象的语言,而运行时多态性是面向对象程序设计代码...
  • u011026329
  • u011026329
  • 2015年08月24日 08:54
  • 1349

多态(继承多态和接口多态、多态数组)

使用基类变量引用子类对象,或使用接口变量引用实现了此接口的对象。这其实就是多态编程。 多态编程的基本原理是:使用基类或接口变量编程。 在多态编程中,基类一般都是抽象基类,其中拥有一个或多个抽象方法,各...
  • brightyanmin
  • brightyanmin
  • 2016年05月10日 15:40
  • 690

C#中类的继承与多态

为了提高软件模块的可复用性和可扩充性,以便提高软件的开发效率,我们总是希望能够利用前人或自己以前的开发成果,同时又希望在自己的开发过程中能够有足够的灵活性,不拘泥于复用的模块。这就引出了面向对象程序设...
  • u010164936
  • u010164936
  • 2014年05月16日 16:07
  • 2004

Java入门习题(四)——接口、继承和多态

Java入门习题 Java入门习题 接口继承和多态 1请根据要求补全代码 2请写出下列程序的运行结果 3请写出下列程序的运行结果 4请写出下列程序的运行结果 5请写出下列程序的运行结果接口、继承和多态...
  • qq_32583189
  • qq_32583189
  • 2016年05月15日 13:32
  • 655
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#锐利体验 第十讲 接口、继承与多态
举报原因:
原因补充:

(最多只允许输入30个字)