关闭

关闭

关闭

封号提示

内容

首页 C#网络编程技术教程 教学课件 ppt 作者 金华 华进 第3章.ppt

C#网络编程技术教程 教学课件 ppt 作者 金华 华进 第3章.ppt.ppt

C#网络编程技术教程 教学课件 ppt 作者 金华 华进 第…

希望
2019-09-15 0人阅读 举报 0 0 暂无简介

简介:本文档为《C#网络编程技术教程 教学课件 ppt 作者 金华 华进 第3章.pptppt》,可适用于高等教育领域

吉林快3—吉林快三高等教育频道提供C#网络编程技术教程 教学课件 ppt 作者 金华 华进 第3章.ppt.ppt文档免费下载,数万用户每天上传大量最新资料,数量累计超一个亿!

*C#网络编程技术教程第三章C#面向对象编程第章C#面向对象编程*学习目标理解面向对象的基本概念。了解基本的面向对象分析、设计方法主要是UML中的类图和序列图。掌握C#中类的定义和实例化方法。掌握C#中继承、多态、接口的实现方法。第章C#面向对象编程*本章内容面向对象的基本概念类和对象字段方法属性与索引委托与事件继承与多态基于UML的系统分析与设计方法第章C#面向对象编程*面向对象的基本概念客观世界是由各种各样的对象组成的如汽车、飞机、火车、人等。每种对象都有各自的内部状态和运动规律不同对象之间的相互作用和联系就构成了各种不同的系统。将客观世界中的对象模型化形成一种计算机化的表示并以此为基础来分析和解决问题便形成了面向对象技术。PeterCoad和EdwardYourdon提出了下列等式来说明面向对象技术。面向对象=对象分类继承消息通信可以说采用对象、类、继承、消息这个概念开发的软件系统是面向对象的。第章C#面向对象编程*面向对象的基本概念.对象在面向对象技术中任何客观事物都是对象对象是对客观事物的抽象。任何复杂的事物都可以通过对象的某种组合结构构成。复杂对象可由相对比较简单的对象以某种方式组成。对象由属性和方法组成。属性反映了对象的信息特征而方法则定义改变属性状态的各种操作。因此对象是属性和方法的一个封装体。通过封装可以更好地隐蔽对象的内部细节只保留有限的对外接口实现对外联系。每个对象都有自身唯一的标识通过这种标识可找到相应的对象。在对象的整个生命期中它的标识都不改变不同的对象不能有相同的标识。.类具有相同属性和方法的对象可归纳成类对象是类的一个实例而对象的抽象是类。类具有属性它是对象的状态的抽象用数据结构来描述类的属性类具有操作它是对象的行为的抽象用操作名和实现该操作的方法来描述。第章C#面向对象编程*面向对象的基本概念.继承类有一定的结构可以派生出子类子类除了继承父类的属性和方法外还可以有自己的属性和方法。对象和类之间的层次结构靠继承关系维系。继承是子类自动共享父类数据结构和方法的机制也是面向对象程序设计语言不同于其他语言的最重要的特点。在类层次中将子类只继承一个父类的数据结构和方法的方式称为单重继承将子类继承多个父类的数据结构和方法的方式称为多重继承。在软件开发中类的继承使所建立的软件具有开放性、可扩充性这是信息组织与分类的行之有效的方法它简化了对象、类的创建工作量增加了代码的重用性。同时通过类的继承关系使公共的特性能够共享提高了软件的重用性。.消息对象之间的联系主要是通过传递消息来实现消息传递是对象间通信的手段一个对象通过向另一个对象发送消息来请求其服务。一个消息通常包含接收对象的标识、发送给接收对象的消息名(方法名)和适当的参数。消息只告诉接收对象需要完成什么操作但并不指示接收者如何完成操作。消息完全由接收者解释并由其独立决定采用什么方法完成所需的操作。第章C#面向对象编程*面向对象的基本概念.多态性多态性是指相同的操作或方法可作用于多种类型的对象上并获得不同的结果。即将不同的对象收到同一消息时产生不同的结果的现象称为多态性。多态性允许每个对象以适合自身的方式去响应共同的消息增强了软件的灵活性和重用性。面向对象技术正是利用对现实世界中对象的抽象和对象之间的相互关联和相互作用的描述来模拟现实世界并且使其映射到目标系统中。第章C#面向对象编程*类和对象类是对象的抽象描述类似于模板。从定义上来说类是一种复杂的数据结构其中包含数据成员和功能成员。在C#中类必须先定义后使用。.类的定义类是C#中最基础的类型。类是一个数据结构将数据成员(状态)和功能成员(行为)组合在一个单元中进而体现了面向对象技术的封装性。类的定义格式如下:Attribute类修饰符class类名:基类和实现的接口列表{类成员定义}其中类的修饰符如下表所示。第章C#面向对象编程*类和对象下面是一个名为Point的简单类的声明。publicclassPoint{privateintx,y数据成员publicPoint(intx,inty){功能成员thisx=xthisy=y}}第章C#面向对象编程*类和对象.类的成员类的成员分为数据成员和功能成员其中数据成员包括:成员常量代表与类相关的常数数据字段类的变量。功能成员包括:方法即类中的成员函数属性定义了命名的属性以及读写属性的相关的行为索引允许类的实例通过与数组相同的方法来索引操作符定义了可以用于类的实例上的表达式操作事件定义了由类产生的事件公告构造函数对类的实例进行初始化的操作析构函数在类的实例销毁前执行与资源释放相关的操作。.类成员的可访问性类的每个成员都有关联的可访问性它控制能够访问该成员的程序区域。在C#中有种可能的可访问性如下表所示。第章C#面向对象编程*类和对象.静态成员和非静态成员类的成员可以是静态成员也可以是非静态成员。在C#中用关键字static修饰的类成员(包括字段、方法、属性、事件、操作符或构造函数)称为静态成员它们属于类。而没有用关键字static修饰的类成员称为非静态成员它们属于对象。静态成员具有如下特征。一个静态字段对应一个存储位置不管其包含类创建了多少个实例总是只有一个静态字段的备份。静态成员(包括方法、属性、事件、操作符或构造函数)不会对非静态成员进行操作也不能使用this。静态成员属于类因此可以在包含类的实例之间共享它们。静态成员一般通过类来访问例如ConsoleReadLine()其中ReadLine()就是类Console中的静态方法。对于非静态字段在包含类的每个实例中都包括一个它的独立备份同时在非静态成员中可以使用this也可以对非静态成员进行操作。非静态成员通过包含类的实例来访问。第章C#面向对象编程*类和对象.对象对象是类的实例。与C不同在C#中类是一种引用类型因此在C#中不能直接用类来定义对象它定义的只是一个对象引用变量。一般可以使用new运算符动态创建一个对象再将其赋值给一个对象引用变量。例如:Pointp=newPoint(,)指向一个动态创建的Point对象Pointp=pp和p指向同一个Point对象Pointp不指向任何对象当不再使用对象时该对象所占的内存将被自动回收。在C#中没有必要也不可能显式地释放对象。而是通过系统中的垃圾回收器来实现对无用对象的回收操作。.构造函数与析构函数C#既支持实例构造函数也支持静态构造函数。实例构造函数用来初始化类实例中的数据成员。静态构造函数用来在类首次加载时初始化类本身的数据成员即静态字段。构造函数的名称与类名相同没有返回类型。若构造函数的声明中包含static修饰符则它声明了一个静态构造函数否则声明的是实例构造函数。静态构造函数不需要访问修饰符同时也不带任何参数实例构造函数可以带参数表可以加访问修饰符进行修饰不能被继承。如果一个类没有声明任何实例构造函数则会自动为它提供一个默认的空的实例构造函数一般其参数列表为空函数体也为空。第章C#面向对象编程*类和对象由于实例构造函数可以带参数因此实例构造函数可以重载并且可以通过参数列表(参数的个数、类型和顺序)来区分不同的实例构造函数。析构函数是用于实现析构类实例所需操作的成员。析构函数不能带参数不能具有可访问性修饰符也不能被显式地调用。当没有任何代码要使用一个实例时系统中的垃圾回收器会自动调用该实例的析构函数对其进行析构如代码实例所示。usingSystemnamespaceex{classProgram{privateintdata非静态数据成员(字段)staticprivateintstaticdata静态数据成员publicProgram()无参数实例构造函数{ConsoleWriteLine(无参数构造函数)data=}publicProgram(intvalue)带参数实例构造函数{ConsoleWriteLine(带参数构造函数)data=value}staticProgram()静态构造函数{ConsoleWriteLine(静态构造函数)staticdata=}~Program()析构函数{ConsoleWriteLine(析构函数)}publicvoidPrint()打印方法{ConsoleWriteLine(Staticdatais{},Datais{},staticdata,data)}staticvoidMain(stringargs){Programp没有创建对象Programp=newProgram()创建一个对象Programp=newProgram()创建一个对象p=ppPrint()pPrint()pPrint()}}}第章C#面向对象编程*字段字段即类的变量类中的数据成员用来存储类所需的数据信息。它可以声明为静态的也可以声明为只读的(readonly)。当字段被声明为只读时与声明为const的效果是一样的区别在于只读型表达式在程序运行时形成而const型表达式的值在编译时形成。只读型字段可以通过构造函数赋值但实例创建后则不能再对其进行赋值。字段声明的格式如下:修饰符字段类型字段名列表其中修饰符可以是public、protected、internal、private、static和readonly字段类型可以是基本类型、用户自定义类型和其他类。例如:classCalendarDate{publicreadonlyintmonth只读字段实例创建后不能对其赋值publicintdaypublicstaticintyear=静态字段属于类的成员}虽然字段是一种类变量但是C#为每个未初始化的变量都确认一个默认值因此字段声明后便可以使用。这在一定程度上保证了程序的安全性。如下代码实例所示为字段使用的程序实例。第章C#面向对象编程*字段usingSystemnamespaceex{classProgram{publicreadonlyintmonthpublicintdaypublicstaticintyear=publicProgram()无参数的构造函数{}publicProgram(intd,intm,inty)构造函数中可以对只读型字段赋值{day=dmonth=myear=y}publicvoidPrint(){ConsoleWriteLine(Yearis{},Monthis{},Dayis{},year,month,day)}staticvoidMain(stringargs){Programp=newProgram(,,)Programp=newProgram()字段具有默认值pPrint()pPrint()pday=pmonth=错误只读型字段不能修改pPrint()}}}第章C#面向对象编程*方法方法是一种用于实现可以由对象或类执行的计算或操作的功能成员。与C中的函数成员类似方法可以是静态也可以是非静态。静态方法只能通过类来访问非静态方法(即实例方法)则要通过类的实例访问。方法有一个参数表(可能为空)表示传递给方法的值或者引用方法还有返回类型用于指定由该方法计算和返回的值的类型。如果方法不返回值则它的返回类型为void。方法的声明格式如下:修饰符返回类型方法名称(参数列表){方法体}其中方法的名称、参数个数、参数顺序、每个参数的修饰符和类型一起组成方法的签名。在声明方法的类中该方法的签名必须是唯一的。正因为方法可以带参数所以类中的方法可以重载重载方法的签名不同主要是参数个数、参数类型和参数顺序不同。第章C#面向对象编程*方法在C#中方法中的参数用于将值或者引用变量传递给方法体。当方法被调用时方法的参数从指定的自变量得到它们实际的值。C#中有种参数:值参数、引用参数、输出参数和参量参数。值参数:用于输入参数的传递。值参数相当于一个局部变量它的初始值是从实参获得的。对值参数的修改不会影响其对应的实参。引用参数:用于输入和输出数据的传递。引用参数对应的实参必须是一个变量并且在方法执行期间引用参数和其实参指向同一个存储空间因此引用参数值的变化将直接影响其实参。引用参数用ref修饰符声明。输出参数:用于输出数据的传递。输出参数类似于引用参数不同之处在于实参有无初始值无关紧要。输出参数用out修饰符声明。参量参数:可以把一维数组或不规则数组传递给方法。在方法声明的参数列表中参量参数必须以params开始例如:publicintsum(paramintintParams){方法体}。在带参量参数的方法调用中既可以传递数组类型的单个实参也可以传递充当数组元素的若干实参。对于后一种的情形数组实例将自动被创建并且通过给定的实参初始化。第章C#面向对象编程*方法usingSystemnamespaceex{classFuncEx{staticprivateintobjectnum=静态字段publicintx,y,xyprivateintmsumpublicFuncEx(inta,intb)构造函数{x=ay=bobjectnum统计对象实例个数}publicvoidswap(inta,intb)值参数{inttemptemp=aa=bb=temp}publicvoidswap(refinta,refintb,outints)引用参数输出参数{inttemptemp=aa=bb=temps=ab}publicvoidsum(paramsintintparams)参量参数{msum=foreach(intvinintparams)msum=v}publicvoidprint()实例方法{ConsoleWriteLine(x={},y={},xy={},sum={},x,y,xy,msum)}staticpublicvoidprintObjectNum()静态方法{ConsoleWriteLine(已创建的对象个数为{},objectnum)}staticvoidMain(stringargs){FuncExf=newFuncEx(,)FuncExprintObjectNum()fprint()静态方法调用fswap(fx,fy)*值参数的方法调用*fprint()fswap(reffx,reffy,oxy)*引用和输出参数的方法调用*fprint()FuncExf=newFuncEx(,)FuncExprintObjectNum()*静态方法调用*fprint()fsum(,,,)*参量参数的方法调用*fprint()inta={,,,,,,}fsum(a)*参量参数的方法调用*fprint()}}}第章C#面向对象编程*属性与索引属性属性是对对象或类的字段进行特定访问的成员是字段的自然扩展并且访问属性和字段的语法相同。在C#中属性与字段完全相同属性不表示存储位置。而且属性有访问器通过这些访问器可以实现对相关字段值(或计算值)的访问。在C#中属性的声明格式如下:修饰符类型属性名{get{执行代码return表达式}set{执行代码}}get访问器和set访问器的功能如下。get访问器相当于一个具有属性类型返回值的无参数方法。当在表达式中引用属性时会调用该属性的get访问器来计算该属性的值。set访问器相当于一个具有单个名为value的参数和无返回类型的方法。当属性作为赋值运算的左值表达式或者作为或运算符的操作数被引用时就会调用set访问器来修改相应字段中的值。第章C#面向对象编程*属性与索引属性两种访问器都包含的属性称为读写属性只具有get访问器的属性称为只读属性只具有set访问器的属性称为只写属性。与字段和方法类似属性可以被定义为实例属性和静态属性。静态属性的声明中具有static修饰符而实例属性则没有静态属性只能访问静态成员。属性的访问器可以是虚拟的。当属性声明中包含virtual、abstract、override修饰符时它们将运用到属性访问器。但是与字段或方法不完全相同属性声明时需要注意如下几点属性不能声明为const也不能在一个表达式声明多个属性。不能通过set访问器对属性进行初始化。属性不属于变量不能将属性作为引用参数或输出参数传递。属性必须有返回类型并且不能为void型。在属性声明中除了get和set访问器外不能进行其他任何操作。第章C#面向对象编程*属性与索引索引索引是这样一个成员它使对象能够用与数组相同的方式进行索引。索引的声明与属性很相似不同之处在于成员的名字是this后面的参数列表在定界符ldquordquo之间。参数在索引的访问器中是可用的。索引的声明形式如下:修饰符类型this类型index{get{执行代码主要是对index值指定的相应数组字段的某个元素进行访问return表达式}set{执行代码主要是对index值指定的相应数组字段的某个元素进行访问}}如果包含get和set访问器则该索引是读写索引如果只包含get访问器则是只读索引而只包含set访问器则是只写索引。注意:索引主要是用来通过数组下标的方式操作对象实例中的某个数组型字段成员的数组元素而不是对象实例数组。第章C#面向对象编程*属性与索引usingSystemnamespaceEx{classNameList{privatestringnamelist名称数组privatereadonlyintMaxLength数组最大长度privateintnamecount=数组当前长度staticprivateintnamelistcount=实例个数privatestringnamelisttile名称标题字段publicNameList(intmaxlength)构造函数{MaxLength=maxlengthnamelist=newstringMaxLengthnamecount=namelistcount}staticpublicintNameListCount静态属性{get{returnnamelistcount}}publicstringNameListTile读写属性{get{returnnamelisttile}set{namelisttile=value}}publicintMAXLength只读属性{get{returnMaxLength}}publicintCount只读属性{get{returnnamecount}}publicstringthisintindex读写索引{get{if((index=)(indexnamecount))returnnamelistindexelsereturn}set{if((index=)(indexnamecount))namelistindex=value}}publicvoidAddName(stringv)方法{if(namecountMaxLength)namelistnamecount=v}publicvoidPrintNamelist()方法{ConsoleWriteLine(NameListTileis{},namelisttile)for(inti=inamecounti)ConsoleWriteLine(tNamelist{}is{},i,namelisti)}第章C#面向对象编程*属性与索引staticvoidMain(stringargs)测试代码{NameListnl=newNameList()创建两个对象NameListnl=newNameList()nlNameListTile=NameBookfor(inti=ii)nlAddName(NameiToString())nlNameListTile=NameBookfor(inti=ii)nlAddName(BookiToString())nl=ITBook通过索引设置实例的值nl=ITBooknlPrintNamelist()ConsoleWriteLine(NameListTitleis{},nlNameListTile)for(intk=knlCountk)ConsoleWriteLine(tNameList{}is{},k,nlk)通过索引读取实例的值}}}第章C#面向对象编程*委托与事件委托委托是事件的基础。它是一种变量类型类似于C中的函数指针可以间接地实现与命名方法或匿名方法的关联提供在程序运行期间对不同方法(或函数)进行选择的能力即后联编但是委托是类型安全和可靠的。与抽象方法类似委托在声明中指定了方法的返回类型和形式参数类型但没有指定具体的实现过程其声明格式如下:修饰符delegate类型委托名(参数列表)其中修饰符和参数列表都是可选的。委托定义了方法的返回类型和参数列表每一个使用委托的方法都必须与委托有着相同的签名。定义了委托之后便可以实例化委托并在此基础上实现与指定方法的关联进而可以通过委托实例调用相关联的方法。委托方法的使用如代码实例所示。该实例实现了一个雇员类Employee并在其中实现了按年龄比较大小和按薪资比较大小两种比较方法以此为基础在测试类Test中利用委托实例做排序函数参数进而实现了分别按照年龄和薪资的排序。第章C#面向对象编程*委托与事件委托usingSystemnamespaceEx{delegateboolCompareOp(objecto,objecto)声明委托classEmployee{privateintmageprivatedoublemsalaryprivatestringmnamepublicEmployee(stringname,intage,doublesalary){mname=namemage=agemsalary=salary}publicvoidPrint(){ConsoleWriteLine(Nameis{},ageis{},salaryis{},mname,mage,msalary)}第章C#面向对象编程*委托与事件委托staticpublicboolAgeIsGreater(objecte,objecte){Employeeemp=(Employee)eEmployeeemp=(Employee)ereturn(empmageempmage)true:false}staticpublicboolSalaryIsGreater(objecte,objecte){Employeeemp=(Employee)eEmployeeemp=(Employee)ereturn(empmsalaryempmsalary)true:false}}classTest{staticpublicvoidSort(objectsortArray,CompareOpgtMethod)使用委托做函数参数{for(inti=isortArrayLengthi){for(intj=ijsortArrayLengthj){if(gtMethod(sortArrayj,sortArrayi)){objecttemp=sortArrayisortArrayi=sortArrayjsortArrayj=temp}}}}}第章C#面向对象编程*委托与事件委托staticvoidMain(stringargs){Employeeemployees={newEmployee(Wang,,),newEmployee(Li,,),newEmployee(Xu,,),newEmployee(Liu,,),newEmployee(Zhang,,),newEmployee(Yuan,,)}CompareOpCompareByAge=newCompareOp(EmployeeAgeIsGreater)定义委托实例CompareOpCompareBySalary=newCompareOp(EmployeeSalaryIsGreater)定义委托实例ConsoleWriteLine(Sortedbyage:)Sort(employees,CompareByAge)委托实例作实参for(inti=iemployeesLengthi)employeesiPrint()ConsoleWriteLine(Sortedbysalary:)Sort(employees,CompareBySalary)委托实例作实参for(inti=iemployeesLengthi)employeesiPrint()}}第章C#面向对象编程*委托与事件事件事件是使对象或类能够提供通知的成员。如果将某个为用户提供服务的类称为服务类使用服务的类称为客户类则事件提供了一种在客户类中扩展服务类的某个功能的机制即在客户类中可以定义事件响应函数。例如在Windows程序中窗口是一个对象当用户在其中单击按钮、按下按键、最大化或最小化窗口时都会激发响应事件并且用户可以为该响应事件添加执行代码。在C#中事件机制的实现主要包括声明事件、激活事件、声明事件响应函数、订阅事件等步骤其中声明事件、激活事件在提供事件通知的服务类中实现而声明事件响应函数和订阅事件则在使用服务类的客户类中实现。.声明事件事件的声明通过委托来实现先定义委托再用委托声明事件并且通过委托将事件响应函数关联到事件中。激发事件的时候通过调用委托实现对事件响应函数的调用。因此事件可以看成是一种特殊的委托其声明格式如下:修饰符event类型事件名其中类型必须是委托类型。例如:publicdelegatevoidAlarmEventHandle(objectsender,stringmsg)声明委托publiceventAlarmEventHandleAlarm定义事件事件的声明与字段的声明类似不同之处在于事件声明包含一个event关键字并且事件声明的类型必须是委托类型。在包含事件声明的类中事件可以像委托类型的字段一样使用。第章C#面向对象编程*委托与事件事件.激活事件当事件激活条件满足并且事件已经与某个事件响应函数关联时便可以激活事件即通过委托实例调用委托函数如下:if((mcurrentTime==malarmTime)(Alarm!=))Alarm(this,定时时间到!)条件满足时激活事件.订阅事件订阅事件就是实现事件与事件响应函数的关联即委托实例与委托函数的关联。在C#中通过ldquo=rdquo操作符实现事件与事件响应函数的关联通过ldquo=rdquo操作符将事件与已关联的事件响应函数去除关联如下:tAlarm=newAlarmEventHandle(OnAlarm)事件响应函数与事件关联tAlarm=newAlarmEventHandle(OnAlarm)去掉事件响应函数与事件的关联如果事件没有实现与事件响应函数的关联则其值为。第章C#面向对象编程*委托与事件事件.声明事件响应函数事件响应函数是客户类在接收到服务类的事件通知后进行响应处理的函数类似于回调函数。因此通过事件响应函数可以在客户类中扩展服务类的某个功能。事件响应函数是委托实例的关联函数因此其签名应与事件的签名一致。下面的OnAlarm函数便是事件Alarm的事件响应函数。staticpublicvoidOnAlarm(objectsender,stringmsg)声明事件响应函数{ConsoleWriteLine(Alarmmessageis{},msg)}事件机制的使用如代码实例所示。该实例中定义了一个定时器类Timer当定时事件与当前时间一致时将通知客户程序并通过与Alarm事件关联的事件响应函数进行处理。而在测试类Test中定义了Timer类的对象并将已定义好的事件响应函数与事件Alarm实现关联同时也测试了去掉关联后的运行效果。第章C#面向对象编程*委托与事件事件usingSystemnamespaceEx{publicdelegatevoidAlarmEventHandle(objectsender,stringmsg)声明委托classTimer{privateDateTimemcurrentTime,malarmTime定义字段publiceventAlarmEventHandleAlarm定义事件publicTimer(DateTimect,DateTimeat){mcurrentTime=ctmalarmTime=at}publicDateTimeCurrentTime{get{returnmcurrentTime}set{mcurrentTime=valueif((mcurrentTime==malarmTime)(Alarm!=))Alarm(this,定时时间到!)条件满足时激活事件}}第章C#面向对象编程*委托与事件事件publicDateTimeAlarmTime{get{returnmalarmTime}set{malarmTime=valueif((mcurrentTime==malarmTime)(Alarm!=))Alarm(this,定时时间到!)条件满足时激活事件}}}classTest{staticpublicvoidOnAlarm(objectsender,stringmsg)声明事件响应函数{ConsoleWriteLine(Alarmmessageis{},msg)}staticvoidMain(stringargs){DateTimealarmtime=DateTimeParse(::)Timert=newTimer(DateTimeNow,alarmtime)tAlarm=newAlarmEventHandle(OnAlarm)事件响应函数与事件关联tCurrentTime=alarmtime将激活事件响应函数tAlarm=newAlarmEventHandle(OnAlarm)去掉事件响应函数与事件的关联tCurrentTime=alarmtime事件响应函数为空不作处理}}}第章C#面向对象编程*继承与多态继承现实世界中实体之间不是相互孤立的它们往往具有共同的特征也有着内在的差别。人们可以采用层次结构来抽象描述这些实体之间的相同之处和不同之处如图所示的交通工具的分类。为了用程序语言对现实世界中的层次结构进行模型化面向对象技术引入了继承的概念一个类可以从另一个类派生出来派生类继承了基类的相应特性同时派生类也可以作为其他类的基类进而实现类间的层次继承关系。因此继承是一种共性的抽象机制。图交通工具的分类第章C#面向对象编程*继承与多态继承.继承的定义C中派生类可以继承一个基类或多个基类的特性而在C#中派生类只能从一个类中继承。派生类的声明格式如下:修饰符class派生类名:基类名{派生类成员}派生类能从它的直接基类中继承的成员包括方法、字段、属性、事件、索引即除了构造函数和析构函数派生类隐式地继承了直接基类的所有成员。在C#中关于继承需要注意以下几个重要规则。继承是可传递的。如果C从B中派生B又从A中派生那么C不仅继承了B中声明的成员而且继承了A中的成员。派生类应当是对基类的扩展。派生类可以添加新的成员但不能除去已经继承的成员的声明。构造函数和析构函数不能被继承。除此之外的其他成员不论对它们声明了怎样的访问方式都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。派生类如果声明了与继承而来的成员同名的新成员就可以覆盖已继承的成员。但这并不意味着派生类删除了这些成员只是不能再访问这些成员。类可以声明虚方法、虚属性以及虚索引它的派生类能够重载这些成员从而实现类的多态性。第章C#面向对象编程*继承与多态继承.覆盖在派生类的成员声明中可以声明与继承而来的成员同名的成员并且使用相同的签名。这时我们称派生类的成员覆盖了基类的成员。在C#中要实现覆盖的成员一般在基类中将其声明为virtual或override而派生类中覆盖成员声明为override。即基类中的virtual成员在派生类中可以覆盖基类中的覆盖成员在派生类中可以进一步声明为覆盖成员。其中用virtual修饰的成员称为虚成员而用override修饰的成员称为覆盖成员。如下所示:classShape{helliphellipvirtualpublicvoidPrint()虚方法{ConsoleWriteLine(Shapeis{},name)}}classLineClass:Shape{helliphellippublicoverridevoidPrint()覆盖方法{basePrint()ConsoleWriteLine(tShapetypeisLine,Lengthis{},Length)}}如果基类中的成员在派生类中被覆盖了则在派生类中直接用该成员名访问的将是派生类中声明的成员。为了在派生类中可以继续访问基类中的相应成员在C#中引入了base关键字通过该关键字可以访问基类中的成员。因此可以将base看成是一个指向派生类直接基类的引用而this则是指向对象实例本身的引用。第章C#面向对象编程*继承与多态继承.object类为了提高程序员的编程效率各种编程环境(工具)都提供了许多重用度高的类库以方便程序员直接使用。同样在NET中也提供了相应的类库。其中Object是该类库中最基本的类它属于System命名空间通常也写成SystemObject。在C#中所有的类都直接或间接派生于Object类。在声明类时如果没有明确指明基类则编译器会自动将Object类指定为其基类。因此Object类是C#所有类的根每个类都将从Object类继承类成员。表列出了Object类的常用方法。第章C#面向对象编程*继承与多态抽象类与密封类.抽象类为了满足分层次抽象的需要在许多面向对象的程序设计语言中都引入了抽象类的概念。抽象类是基类的一种特殊形式它除了拥有普通的类成员之外还拥有抽象类成员。在C#中抽象类成员是指那些只有声明没有实现的方法、属性或索引并且使用了abstract修饰符。因此抽象类不能实例化它一般出现在类层次结构中的中间层或根节点上不能出现在叶节点中。在C#中包含一个或多个抽象成员的类本身也必须声明为abstract但是抽象类可以包含非抽象的成员。从抽象类派生的类必须对基类中包含的所有抽象成员进行实现否则它也是抽象类。抽象成员为隐式的虚成员因此在抽象类的派生类中实现抽象成员的方法与覆盖一个虚方法类似。如下代码定义了一个抽象类Shape其中包含抽象方法和虚方法。abstractclassShape抽象类{privateintx,yprivatestringnameprotectedColorTypeftColorhelliphellipabstractpublicvoidDraw()抽象方法virtualpublicvoidPrint()虚方法{ConsoleWriteLine(Shapeis{},name)}}第章C#面向对象编程*继承与多态抽象类与密封类.密封类密封类是指那些不能被继承的类。在C#中为了提高程序运行效率和稳定性对那些认定为不能再继承的类可以定义为密封类用修饰符sealed进行修饰。当一个类被声明为密封类后就不能再用来派生新的类。因此密封类中不可能存在抽象成员一般也不存在虚成员。当某个类中的某个成员认定为不能被覆盖时也可以将其声明为密封成员即用修饰符sealed对该成员进行修饰。包含密封成员的类不一定要声明为密封类。密封类可以从抽象类派生也可以使用关键字override覆盖基类中的虚成员。如下代码定义了一个密封类SquareClass它从基类RectClass派生而来。sealedclassSquareClass:RectClass密封类{publicSquareClass(stringname,intx,inty,intw,intl):base(name,x,y,xw,yl){}publicoverridevoidDraw(){ConsoleWriteLine(Square{}isdrawed,Name)}publicoverridevoidPrint(){ConsoleWriteLine(Shapeis{},Name)ConsoleWriteLine(tShapetypeisSquare,Lengthis{},Areais{},Length,GetArea())}}由抽象类和密封类的概念可知在C#中修饰符sealed和abstract不能同时出现在同一个类或同一个成员中。第章C#面向对象编程*继承与多态接口在C#中继承的实现包括两种方式:实现继承和接口继承。其中前面所介绍的类继承方式属于实现继承它实现的主要是抽象共享或派生类对基类的修改和扩展等。接口继承是一种对外约定的实现在接口中定义相关的对外约定(包括方法、属性、索引和事件)即类必须实现的对外行为特征实现接口的类则实现了这些约定。这样客户程序只要了解类所实现的接口便可以知道其对外提供了哪些服务。在C#中定义接口的语法规则如下:访问修饰符interface接口名:父接口列表{接口成员}其中接口成员可以是方法、属性、索引和事件的声明但仅仅是声明不需要给出实现体这与抽象类中的抽象成员类似。父接口列表用于指定接口继承的父接口这与类有很大区别接口允许多继承因此该列表可以包含无数个接口。如下代码定义了两个接口IRegion和ILine其中一个接口定义的是方法另一个定义的是属性。publicinterfaceIRegion{doubleGetArea()}publicinterfaceILine{doubleLength{get}}接口最终还是要通过类来实现即要求类来实现接口中的接口成员这与派生类要实现基类中的抽象成员一样。另外由于接口中声明的仅仅是功能约定即抽象的功能成员没有数据成员因此不会由于多重继承带来二义性问题。在C#中一个类最多可以有一个基类但是可以具有无限个接口。第章C#面向对象编程*继承与多态多态性多态性是面向对象技术中的一个重要概念。是指通过基类引用绑定不同对象实例时同样的方法可以具有不同的运行行为即对象运行时刻的类型决定它的行为而不是它的引用方法编译时的类型决定它的行为。在C#中多态性的实现依赖于基类中的虚成员声明以及派生类中对虚成员的覆盖。如下代码表现了多态性的实现。Shapel=newLineClass(Line,,,,)Shaper=newRectClass(Rect,,,,)Shapes=newSquareClass(Square,,,,)lDraw()lPrint()依据Draw和Print在LineClass中的实现来执行rDraw()rPrint()依据Draw和Print在RectClass中的实现来执行sDraw()sPrint()依据Draw和Print在SquareClass中的实现来执行因此通过对象引用调用的方法的执行行为取决于该对象引用动态绑定的对象类型。多态性在程序运行的动态过程中体现进而增加了程序的灵活性和通用型。继承与多态的实现方法如代码实例所示该实例中定义了抽象类Shape、接口IRegion和ILine、具体类LineClass、RectClass和SquareClass。第章C#面向对象编程*继承与多态多态性usingSystemnamespaceEx{enumColorType{Red,Green,Blue,Black,White,Yellow}abstractclassShape{privateintx,yprivatestringnameprotectedColorTypeftColorpublicShape(){name=Nonenamex=y=}publicShape(stringname,intx,inty){thisname=namethisx=xthisy=y}publicColorTypeFtColor{get{returnftColor}set{ftColor=value}}第章C#面向对象编程*继承与多态多态性publicintX{get{returnx}set{x=value}}publicintY{get{returny}set{y=value}}publicstringName{get{returnname}}abstractpublicvoidDraw()virtualpublicvoidPrint(){ConsoleWriteLine(Shapeis{},name)}}第章C#面向对象编程*继承与多态多态性publicinterfaceIRegion{doubleGetArea()}publicinterfaceILine{doubleLength{get}}classLineClass:Shape,ILine{privateinttoX,toYpublicLineClass(stringname,intx,inty,inttoX,inttoY):base(name,x,y){thistoX=toXthistoY=toY}publicdoubleLength{get{return(MathSqrt((toXX)*(toXX)(toYY)*(toYY)))}}第章C#面向对象编程*继承与多态多态性sealedpublicoverridevoidDraw(){ConsoleWriteLine(Line{}isdrawed,Name)}sealedpublicoverridevoidPrint(){basePrint()ConsoleWriteLine(tShapetypeisLine,Lenghtis{},Length)}}classRectClass:Shape,ILine,IRegion{privateinttoX,toYpublicRectClass(stringname,intx,inty,inttoX,inttoY):base(name,x,y){thistoX=toXthis

类似资料

该用户的其他资料

2015.11创新杯创新杯说课大赛国赛说课课件.ppt

19--课程..创新杯说课大赛国赛说课课件.ppt

2014创新杯直线的倾斜角与斜率课程创新杯说课大赛国赛说课课件.ppt

13幼师3 住创新杯说课大赛国赛说课课件.ppt

2010血栓的形成讲课曹颜冬创新杯说课大赛国赛说课课件.ppt

职业精品

精彩专题

让你惊艳又清新的英文短诗合集

让你清新惊艳的英文小诗有哪些呢?小编汇集了以下经典英文诗、唯美爱情小诗、英文诗押韵技巧等等,让爱好英文短诗的你能够一起体验其中的乐趣!

用户评论

0/200
上传我的资料

热门资料排行换一换

  • 钢板桩止水帷幕施工方案

  • 乙肝两对半标准操作规程POS

  • 2005年度艺术科学论文评奖获奖论…

  • 糖尿病人得白内障

  • 方位角与象限角

  • 重组腺相关病毒介导的细胞色素P45…

  • 河南省理科491分能上什么学校

  • 10倍放大镜

  • 重庆阳光绿洲项目经济技术指标&#4…

  • 资料评价:

    / 53
    所需积分:0 立即下载

    VIP

    在线
    客服

    免费
    邮箱

    吉林快3—吉林快三服务号

    扫描关注领取更多福利