C#面向对象编程基础.ppt_第1页
C#面向对象编程基础.ppt_第2页
C#面向对象编程基础.ppt_第3页
C#面向对象编程基础.ppt_第4页
C#面向对象编程基础.ppt_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章 C#面向对象编程基础,2,本章要点,7.1 类和继承 7.2 多态 7.3 命名空间和程序集,3,7.1 类继承 7.2 访问继承的成员 7.3 隐藏基类成员 7.4 基类访问 7.5 使用基类的引用 7.6 构造函数的执行 7.7 成员访问修饰符 7.8 抽象成员 7.9 抽象类 7.10 密封类 7.11 静态类 7.12 扩展方法 7.13 外部方法,4,7.1 类继承,通过继承我们可以定义一个新类,新类纳入一个已经声明的类并进行扩展。 可以使用一个已经存在的类作为新类的基础。已存在的类称为基类(base class),新类称为派生类(derived class)。派生类成员的组成如下: 自己声明中的成员 基类的成员 要声明一个派生类,需要在类名后加入基类规则说明。基类规则说明由冒号和后面跟着用作基类的名称组成。派生类被描述为直接继承自列出的基类 派生类被描述为扩展它的基类,因为它包含了基类的成员,加上在它自己的声明中的任何附加功能 派生类不能删除它所继承的任何成员,5,7.1 类继承,6,7.2 访问继承的成员,继承的成员可以被访问,就像它们是派生类自己声明的一样。 例子:AccessBaseClassMember.sln,7,7.2 访问继承的成员,8,所有类都派生自object类,除了特殊的类object,所有的类都是派生类,即使它们没有基类规格说明。类object是唯一的非派生类,因为它是继承层次结构的基础。 没有基类规格说明的类隐式地直接派生自object。不加基类规格说明只是指定object为基类的简写。,9,所有类都派生自object类,关于类继承的其他重要内容如下: 一个类声明的基类规格说明只能有一个单独的类。这称为单继承。 虽然类只能直接继承一个基类,但继承的层次没有限制。也就是说,作为基类的类可以派生自另外一个类,而它又可以派生自另外一个类,一直下去,直至最终到object。,10,7.3 隐藏基类成员,虽然派生类不能删除它继承的任何成员,但它可以隐藏它们。 要隐藏一个继承的数据成员。需要声明一个新的相同类型的成员,并使用相同的名称 通过在派生类中声明新的带有相同签名的函数成员,可以隐藏或掩盖继承的函数成员 要让编译器知道我们在故意隐藏继承的成员,使用new修饰符。没有它,程序可以成功编译,但编译器会警告隐藏了一个继承的成员 也可以隐藏静态成员 例子:MaskBaseMember.sln,11,7.3 隐藏基类成员,12,7.4 基类访问,有时,派生类需要访问被隐藏的继承成员。可以使用基类访问表达式访问隐藏的基类成员。基类访问表达式由关键字base后面跟着一个点和成员的名称组成,如下所示:,13,7.4 基类访问,14,7.5 使用基类的引用,派生类的实例由基类的实例加上派生类附加的成员组成。派生类的引用指向整个类对象,包括基类部分。 如果有一个派生类对象的引用,就可以获取该对象基类部分的引用,使用类型转换运算符把该引用转换为基类类型。类型转换运算符放在对象引用的前面,由圆括号括起的要被转换成的类名组成。 例子:UseBaseReference.sln,15,7.5 使用基类的引用,16,虚方法和覆写方法,前面我们看到,当使用基类引用访问派生类对象时,得到的是基类的成员。虚方法可以使基类的引用访问“升至”派生类内。 可以使用基类引用调用派生类的方法,只需要满足下面的条件: 派生类的方法和基类的方法有相同的签名和返回类型 基类的方法使用virtual标注 派生类的方法使用override标注,17,虚方法和覆写方法,18,虚方法和覆写方法,关于virtual和override修饰符的重要事项如下所示: 覆写和被覆写的方法必须有相同可访问性。也就是说,被覆写的方法不能是private等,而覆写方法是public 不能覆写static方法或非虚方法 方法、属性和索引,以及事件,它们都可以被声明为virtual和override。 例子:VirtualMethod.sln,19,覆写标记为override的方法,覆写方法可以在继承的任何层次出现: 当使用对象基类部分的引用调用一个覆写的方法时,方法的调用被沿派生层次上溯执行,一直到标记为override的方法的最派生(most-derived)版本。 情况1:使用override声明 例子:Virtual_override.sln 情况2:使用new声明 例子:Virtual_override_new.sln,20,7.6 构造函数的执行,在前面,我们看到构造函数执行代码,准备一个类以使用。这包括初始化类的静态成员和实例成员。在这一部分,我们会看到派生类对象有一部分就是基类对象。 要创建对象的基类部分,基类的一个构造函数被作为创建实例过程的一部分被调用 继承层次链中的每个类在执行它自己的构造函数之前执行它的基类的构造函数,21,7.6 构造函数的执行,当一个实例被创建时,完成的第一件事是初始化对象的所有实例成员。在此之后,基类的构造函数被调用,然后该类自己的构造函数才被执行。,22,构造函数初始化语句,默认情况下,在对象被构造时,基类的无参数构造函数被调用。但构造函数可以被重载,所以基类可能有一个以上的构造函数。如果希望派生类使用一个指定的基类构造函数而不是无参数构造函数,必须在构造函数初始化语句中指定它。 有两种形式的构造函数初始化语句: 第一种形式使用关键字base并指明使用哪一个基类构造函数 第二种形式使用关键字this并指明应该使用当前类的哪一个另外的构造函数 基类构造初始化语句放在冒号后面,冒号紧跟着类的构造函数声明的参数列表。构造函数初始化语句由关键字base和要调用的基类构造函数的参数列表组成。,23,构造函数初始化语句,例子:BaseKeywordExample.sln,24,类访问修饰符,类可以被系统中其他类看到并访问。 术语可见的有时用作术语可访问的。它们可以被互相访问。类的可访问性有两个级别:public和internal。 标记为public的类可以被系统内任何程序集中的代码访问 标记为internal的类只能被它自己所在的程序集内的类看到 这是默认的可访问级别,所以,只有在类的声明中显式地指定修饰符public,程序集外部的代码才能访问该类 可以使用internal访问修饰符显式地声明一个类为内部的,25,类访问修饰符,26,7.7 成员访问修饰符,到现在为止,我们只讨论了类的可访问性。成员(数据成员和函数成员)的可访问性描述了类成员的可见性。 声明在类中的每个成员对系统的不同部分可见,这依赖于类声明中指派给它的访问修饰符。有7个成员访问级别: 公有的(public) 私有的(private) 受保护的(protected) 内部的(internal) 受保护内部的( protected internal),27,7.7 成员访问修饰符,28,7.7 成员访问修饰符,必须对每个成员指定成员访问级别。如果不指定某个成员的访问级别,它的隐式访问级别为private 成员不能比它的类更可访问。也就是说,如果一个类的可访问性限于它所在的程序集,那么类的成员个体也不能从程序集的外部看到,无论它们的访问修饰符是什么,29,公有成员的可访问性,public访问级别是限制性最少的。所有的类,包括程序集内部的类和外部的类都可以自由地访问成员。,30,私有成员的可访问性,私有成员的可访问性限制是最严格的。 private类成员只能被它自己的类的成员访问。它不能被其他的类访问,包括继承它的类 然而,private成员能被嵌套在它的类中的成员访问,31,受保护成员的可访问性,protected访问级别如同private访问级别,除了一点,它允许派生自该类的类访问该成员。,32,内部成员的可访问性,标记为internal的成员对程序集内部的所有类可见,但对程序集外部的类不可见。,33,受保护内部成员的可访问性,标记为protected internal的成员对所有继承该类的类以及所有程序集内部的类可见。 例子:MemberAccessModifier.sln,34,7.8 抽象成员,抽象成员是被设计来覆写的函数成员。抽象成员有以下特征: 它被用abstract修饰符标记 它没有实现代码块。抽象成员的代码块被分号代替,35,7.8 抽象成员,关于抽象成员的其他重要事项如下: 尽管抽象方法必须在派生类中用相应的方法覆写,但不能把virtual修饰符附加到abstract修饰符 就像虚方法,派生类中抽象方法的实现必须指定override修饰符 抽象成员只能被声明在抽象类中,36,7.8 抽象成员,比较虚成员和抽象成员:,37,7.9 抽象类,抽象类只能被用作其他类的基类。抽象类就是被设计来被继承用的。 不能创建抽象类的实例 抽象类使用abstract修饰符声明,38,7.9 抽象类,抽象类可以包含抽象成员,但不是必须的。抽象类的成员可以是抽象成员和普通带实现的成员的任意组合 抽象类可以派生自另一个抽象类。 例子:AbstractClass.sln AbstractExample.sln,39,7.9 抽象类,40,7.10 密封类,密封类的重要事项: 密封类只能被用作独立的类,它不能被用作基类 密封类使用sealed修饰符标记,41,7.11 静态类,静态类是这样一种类,在类中所有的成员都是静态的。静态类用于分组不受实例数据影响的数据和函数。静态类的一个普通的用途就是创建一个包含一组数学方法的数学库。 关于静态类的重要事项如下: 类本身必须标记为static 类的所有成员必须是静态的 类可以有一个静态构造函数,但没有实例构造函数,不能创建该类的实例 不能继承静态类,它们是密封的,42,7.11 静态类,43,7.12 扩展方法,在迄今为止的内容中,我们所看到的每个方法都和声明它们的类相关联。C#3.0扩展方法扩展了这个边界,允许编写和声明它的类之外的类关联的方法。 看下面MyData类,假如想追加一个更有用的方法,应该怎么办?,44,7.12 扩展方法,45,7.12 扩展方法,如果有源代码改源代码 然而,如果不能修改这个类,那就把这个类当作一个基类并在派生自它的类中实现这个增加的方法 如果不能访问源代码,或该类是密封的等原因。那就在另一个类中使用该类的公有成员编写一个方法,46,7.12 扩展方法,47,7.12 扩展方法,然而,还使用扩展方法特性来做。 在参数声明中的类型名前增加关键字this,把this关键字加到静态类的静态方法的第一个参数上,把方法从类的正规方法变为一个类的扩展方法。,48,7.12 扩展方法,扩展方法重要的事项如下: 扩展方法必须被声明为static 扩展方法声明所在的类也必须被声明为static 扩展方法必须包含关键字this作为它的第一个参数类型,并在后面跟着它所扩展的类的名称,49,7.12 扩展方法,扩展方法的例子: ExtensionMethod.sln,50,7.13 外部方法,外部方法(external method)是在声明中没有实现的方法。其实常常是用C#语言之外的语言编写的方法。 外部方法使用extern修饰符标记,而且在类的声明没有实现。它的实现被分号取代。,51,7.13 外部方法,声明和实现的连接是依赖实现的,但常常使用DllImport特性完成 例子:ExternalMethod.sln,52,7.2 多态,7.2.1 理解多态 7.2.2 实现多态,53,什么是多态,多态性(polymorphism)是一项允许将父对象设置为和一个或多个子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以及不同的方式运作。从字面上来理解,多态就是“多种形式”。在计算机领域,它意味着可以利用动态绑定技术,用相同名称的方法来调用方法的不同具体实现。,54,7.2.1 理解多态,重载(overload)和多态无关,真正和多态相关的是覆盖(override)。当派生类重新定义了基类的虚拟方法后,基类根据赋给它的不同的派生类引用,动态地调用属于派生类的对应方法,这样的方法调用在编译期间是无法确定的。因此,这样的方法地址是在运行期绑定的(动态邦定)。结论就是:重载只是一种语言特性,与多态无关,与面向对象也无关。,55,7.2.2 实现多态,例子:PolymorphismExample.sln 当方法前使用了virtual关键字时,它就成为虚拟方法。虚拟方法是多态的基础,在派生类中能够(但不是必须)改变方法的执行,改变基类中虚拟方法的过程叫做覆盖(override)。抽象方法与虚拟方法的区别在于: 虚拟方法有实现,抽象方法没实现 抽象方法是隐含的虚拟,而且它必须被子类覆盖,56,7.3 命名空间和程序集,在这一部分,我们要在高层次上观察了解编译过程。编译器接受源代码文件并生成名称为程序集的输出文件。我们会详细阐述程序集以及它们是如何生成和部署的。还会看到命名空间是如何帮助组织类型的。 在我们看到的所有程序中,大部分都是声明并使用它们自己的类。然而,在许多项目中,你会想使用来自其他程序集的类或者类型。这些其他程序集可能来自BCL(Base Class Library),或来自一个第三方卖主,或你自己创建了它们,这些程序集就称为类库,而且它们的程序集文件的名称通常以.dll扩展名结尾而不是.exe扩展名。,57,7.3 命名空间和程序集,引用另一个程序集,58,7.3 命名空间和程序集,mscorlib库 有一个类库,我们几乎先前的每一个示例都使用它。它就是包含Console类的那个库。Console类被定义在mscorlib的程序员集中,在名称为mscorlib.dll的文件里。在这个程序集中,含有C#类型以及大部分.NET语言的基本类型的定义。在编译C#程序时,它必须总是被引用。,59,7.3 命名空间和程序集,引用类库,60,7.3 命名空间和程序集,大家看下图,由于程序集Superlib和UltraLib都含有名称为SquareWidget的类的声明,编译器不知道实例化哪一个。这个问题怎么解决呢?,61,7.3 命名空间和程序集,如果我们有源代码,我们就可以改变它们的类名来解决这些问题。但是,如果这些类型由不同的公司开发的,而且我们也没有源代码,那怎么办? 大家想像一下,在自己做开发的机器上含有不同公司生产的程序集,很可能有一定数量的类名重复。如果你不能把两个程序集用在一个程序中,仅仅因为它们碰巧有相同的类名,这是一种耻辱。 但是,命名空间名称帮助我们解决了这个问题。,62,7.3 命名空间和程序集,命名空间把一组类型分组在一起并给它们一个名称,称为命名空间名称。 下面声明了一个命名空间: name

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论