《C#-程序设计教程第6章.ppt》由会员分享,可在线阅读,更多相关《C#-程序设计教程第6章.ppt(28页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第6 6章章 面向对象的高级应用面向对象的高级应用6.1 6.1 类的继承类的继承6.2.6.2.访问控制符访问控制符6.3.6.3.多态性多态性6.4.6.4.密封类密封类6.5.6.5.抽象类抽象类6.6 6.6 接口接口目目 录录 继承是面向对象程序设计中的一种重要机制,该机制自动的将一个类中的操作和数据结构提供给另一个类,这使得程序员可以使用已有类的成分来建立新类。理解面向对象程序设计的关键就是要理解继承。继承(inheritance)是指一个新类可以从现有的类派生而来。新类继承了现有类的特性,包括一些属性和行为,并且可以修改或增加新的属性和行为,使之适合具体的需要。继承是面向对象技
2、术能够提高软件开发效率的重要原因之一,很好地解决了软件的可重用性问题。6.1 6.1 类的继承类的继承 C#语言中可以让你声明一个新类作为另一个类的派生。派生类(也叫子类)继承其父类的域、属性、方法和接口等,子类也可以声明新的域、属性和方法等,这样,继承可以让你重用父类的代码,专注于子类代码的编写。6.1 6.1 类的继承类的继承 开始使用继承实现一个类时,必须先从派生子类的现有类开始。这个现有的类(基类)可以是.NET系统框架类库的一部分,也可以是其他应用程序或.NET程序集的一部分,甚至可以把它作为现有应用程序的一部分来创建。一旦有了基类,就可以在该基类的基础上实现一个或多个子类。每个子类
3、都自动拥有该基类的所有方法、属性和事件包括每个方法、属性和事件的实现代码。子类可以添加自己的新方法、属性和事件,用新的功能来扩展原始的接口。另外,子类还能使用自身的实现方法代替基类中的方法和属性重写原来的行为,用新的行为来代替它。继承本质上是一种将现有类的功能合并到新子类中的方式。继承也定义了合并方法、属性和事件的规则,包括如何改变或代替它们,以及子类如何为其自身增加新的方法、属性和事件。这些规则的具体内容以及在C#中如何使用这些规则将在下面详细介绍。6.1 6.1 类的继承类的继承1、创建基类 在C#语言平台中,创建出来的任何类都可以作为基类,派生其他的类。因此,如果没有明确的在代码中指明这
4、个类不能作为基如果没有明确的在代码中指明这个类不能作为基类,就可以从这个类中派生子类。类,就可以从这个类中派生子类。首先,用如下代码创建一个Employee(职员)类:public class Employee 这样我们就有了一个基类。即使这个类不能做任何事情或者不包括任何内容,也可以继承它。6.1 6.1 类的继承类的继承public class Employee private string name;private DateTime birthDate;public string Name get return name;set name=value;public DateTime Bi
5、rthDate get return birthDate;set birthDate=value;这样就为Employee类添加了两个属性。6.1 6.1 类的继承类的继承2、创建子类为了实现继承,需要添加一个新类。以下面的代码为例,创建一个SalesForce(销售人员)类:public class SalesForce private decimal salesVolume;private int salesManagerID;/销售额 public decimal SalesVolume /所属销售经理ID public int SalesManagerID SalesForce对象带有
6、销售额和所属销售经理ID,它也应当具有Name和BirthDate属性,就像Employee类那样。如果没有继承,就只能从Employee类中把代码直接复制和粘贴到新的SalesForce类中,但是通过继承,就可以重用Employee类中的代码。下面创建继承自Employee类的新类。要使SalesForce类成为Employee类的一个子类,只需修改SalesForce类的第一行代码:public class SalesForce:Employee6.1 6.1 类的继承类的继承3、重载方法SalesForce类通过继承自动获得了Name和BirthDate属性,它还拥有自己的SalesVo
7、lume和SalesManagerID属性。这就说明了可以给SalesForce子类添加方法和属性来扩展基本的 Employee接口。可以给SalesForce类添加新的属性、方法和事件,它们将成为任何基于SalesForce类型创建的对象的一部分。这对Employee类没有任何影响,仅影响SalesForce类和SalesForce对象。甚至可以给子类添加和基类中的方法同名的方法,以扩展基类的功能,只要这些方法具有不同的参数列表即可。重载基类中的现有方法在本质上与重载常规方法相同。6.1 6.1 类的继承类的继承 访问控制符是C#语言中的一类关键字,用于指定声明的成员或类型的可访问性。本节主
8、要介绍C#语言中常用的四个访问控制符:public、protected、internal和private。public 关键字是类型和类型成员的访问控制符。public访问控制符允许最高访问级别。对访问public修饰的成员没有限制,如下所示:class SampleClass public int x;/无访问限制6.2.6.2.访问控制符访问控制符protected 关键字是一个成员访问控制符。protected修饰的成员在它的类中可访问并且可由派生类访问,也就是说,仅当访问通过派生类类型发生时,基类的受保护成员在派生类中才是可访问的。6.2.6.2.访问控制符访问控制符internal
9、关键字是类型和类型成员的访问控制符。只有在同一程序集的文件中,内部类型或成员才是可访问的6.2.6.2.访问控制符访问控制符private 关键字是一个成员访问控制符。私有访问是允许的最低访问级别。私有成员只有在声明它们的类和结构体中才是可访问的6.2.6.2.访问控制符访问控制符通常一个成员或类型只能有一个访问控制符,使用 protected internal 组合时除外。命名空间上不允许使用访问控制符。命名空间没有访问限制。根据发生成员声明的上下文,只允许某些声明的可访问性。如果在成员声明中未指定访问控制符,则使用默认的可访问性。不嵌套在其他类型中的顶级类型的可访问性只能是 interna
10、l 或 public。这些类型的默认可访问性是 internal。6.2.6.2.访问控制符访问控制符访问控制符在使用时也受一些条件的限制,比如声明类型时,最重要的是查看该类型是否必须至少与其他成员或类型具有同样的可访问性。例如,直接基类必须至少与派生类具有同样的可访问性。以下声明将导致编译器错误,因为基类 BaseClass 的可访问性小于 MyClass:class BaseClass.public class MyClass:BaseClass./错误6.2.6.2.访问控制符访问控制符 多态性(polymorphism)是面向对象程序设计中的一个重要概念,它是指同一个消息被不同类型的对
11、象接收时产生不同的行为。所谓消息是指对类成员的调用,不同的行为是指调用了不同的类成员。1、方法的重载方法重载(function overload)是指功能相似,方法名相同但所带参数不同的一组方法。这里的“所带参数不同”既可能是参数的数据类型不同也可能是参数的个数不同。在第五章,我们已经简单介绍了方法的重载。6.3.6.3.多态性多态性2、隐藏基类方法 除了常规方法重载之外,还有一些特殊情况需要考虑。例如,在有些情况下,希望往派生类中添加一个与基类中方法名相同,所带参数也相同的成员方法。这种情况下程序运行时由于无法通过参数列表来确定调用基类还是派生类中的方法,所以对于这种特殊的方法重载我们需要隐
12、藏基类中的方法,使通过派生类对象进行的方法调用能调用到派生类中的与基类中方法名相同,所带参数也相同的成员方法。在派生类中定义与基类中方法名相同,所带参数也相同的成员方法时可以使用new关键字隐藏基类中的方法。6.3.6.3.多态性多态性3、虚方法 派生类定义的重载函数成员(函数名和参数类型与基类中函数成员相同)虽然可以隐藏基类的同名函数成员,但是只能通过派生类对象来调用派生类再定义的函数成员。如果使用基类变量引用派生类对象,然后通过基类变量调用该函数成员,访问的仅仅是从基类继承的同名函数,无法访问派生类定义的重载成员函数。如何通过基类变量来访问派生类中重载的函数成员呢?C#提供了虚方法机制来解
13、决这个问题。首先在基类中将这个可能会被重载地方法通过virtual关键字定义为虚方法,接着在派生类中通过override关键字重载该方法,最后就可以通过基类变量引用派生类对象,来访问派生类中重载的这个同名方法。这样,通过基类的变量,就可以使属于同一个类族的不同对象产生不同的行为,从而实现了运行过程中的多态。6.3.6.3.多态性多态性4、base关键字 前面说明了如何利用多态的特性在子类中重载基类方法,来完全替换基类中的功能。不过这有点极端有时重写方法是为了扩展基本功能,而不是替代原来的功能。为此,需要像上面那样使用override关键字重载方法,但是在新的实现代码中,仍然调用方法的原始实现代
14、码。这样就可以在调用原始实现代码的前后添加自己的代码即在扩展功能的同时,仍利用基类中的代码。为了直接从基类中调用方法,可以使用base关键字。这个关键字可以在任何类中使用,它提供了基类中的所有方法,以供使用。base 关键字用于从派生类中访问基类的成员:调用基类上已被其他方法重写的方法;指定创建派生类实例时应调用的基类构造函数。基类访问只能在构造函数、实例方法或实例属性访问器中进行。从静态方法中使用 base 关键字是错误的。6.3.6.3.多态性多态性 密封类在声明中使用sealed修饰符,这样就可以防止该类被其它类继承。如果试图将一个密封类作为其它类的基类,C#将会提示出错。理所当然,密封
15、类不能同时又是抽象类,因为抽象总是希望被继承的。在哪些场合下使用密封类呢?密封类可以阻止其它程序员在无意中继承该类,而且密封类可以起到运行时优化的效果。实际上,密封类不可能有派生类,如果密封类实例中存在虚成员函数,该成员函数可以转化为非虚的,函数修饰符virtual不再生效。6.4.6.4.密封类密封类 除了对类使用sealed 修饰符外,还可以在重写基类中的虚方法或虚属性的方法或属性上使用 sealed 修饰符。这将使你能够允许类从你的类继承,并防止它们重写特定的虚方法或虚属性。6.4.6.4.密封类密封类 在定义类的前面加上关键字abstract,那么这个类就是抽象类了,抽象类本身无法产生
16、实例对象,而且抽象类可以包含一个以上的抽象方法,这些方法只是提供函数名称,并没有定义如何具体实现,由继承的派生类实现,派生类同时必须实现所有抽象类的方法,否则其本身将成为另外一个抽象类。需要我们注意的一点是,当派生类重写抽象类的方法时,要使用override关键字来重写抽象类所定义的方法。6.5.6.5.抽象类抽象类 C#接口(interface)用来定义一种程序的协定。实现接口的类或者结构要与接口的定义严格一致。有了这个协定,就可以抛开编程语言的限制(理论上)。C#接口可以从多个基接口继承,而类或结构可以实现多个接口。C#接口可以包含方法、属性、事件和索引器。接口本身不提供它所定义的成员的实
17、现。接口只指定实现该接口的类或接口必须提供的成员。C#接口好比一种模版,这种模版定义了对象必须实现的方法,其目的就是让这些方法可以作为接口实例被引用。接口不能被实例化。类可以实现多个接口并且通过这些实现的接口被引用。接口变量只能引用实现该接口的类的实例。6.6 6.6 接口接口C#中接口定义如下:/接口定义 interface IMyExample string thisint index get;set;void Find(int value);string Point get;set;6.6 6.6 接口接口C#中接口可以支持多重继承。在下面的代码中,接口“IComboBox”同时从“IT
18、extBox”和“IListBox”继承。interface IControl void Paint();interface ITextBox:IControl void SetText(string text);interface IListBox:IControl void SetItems(string items);interface IComboBox:ITextBox,IListBox 6.6 6.6 接口接口在C#中类和结构可以同时派生至多个C#接口。就像在下面的代码中,类“EditBox”继承了类“Control”,同时从“IDataBound”和“IControl”继承。in
19、terface IDataBound void Bind(Binder b);class EditBox:Control,IControl,IDataBound public void Paint();public void Bind(Binder b)6.6 6.6 接口接口总的说来,C#中的接口有如下特点:C#中的接口是独立于类来定义的。接口和类都可以继承多个接口。类可以派生于一个基类,接口不能派生于一个基类。一个接口定义一个只有抽象成员的引用类型。C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码。这就暗示了不能实例化一个接口,只能实例化一个派生自该接口的对象。接口可以定义方法、属性和索引。所以,对比一个类,接口的特殊性是:当定义一个类时,可以派生自多重接口,而你只能从仅有的一个类派生。6.6 6.6 接口接口 本章以面向对象的高级应用为主体核心,围绕C#语言中面向对象的特性,重点说明了类的继承、访问控制符、多态性、密封类、抽象类、接口和委托与事件等概念,并辅以大量程序实例对上述概念进行了演示。本章小结本章小结