C#面向对象课件_第1页
C#面向对象课件_第2页
C#面向对象课件_第3页
C#面向对象课件_第4页
C#面向对象课件_第5页
已阅读5页,还剩271页未读 继续免费阅读

下载本文档

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

文档简介

面向对象1面向对象1Microsoft.NET介绍微软的.NET历史2000年微软公司向全球宣布其革命性的软件和服务平台:Microsoft.NET

2001年发布了.NETFramework1.0版经历5个版本1.0、1.1、2.0、3.0、3.5Microsoft.NET介绍微软的.NET历史Microsoft.NET介绍支持多种终端平台信息互联互通Web服务:Passport,MSN在线游戏Live服务任何时候、任何地方、利用任何工具都可以获得网络上的信息,并享受网络通信所带来的快乐Microsoft.NET介绍支持多种终端平台信息互联互通W.NET战略对微软的影响2003~2004年间,全球100强和《财富》100强加起来的共166个公司微软发布.NET前后的营业额Microsoft.NET介绍.NET战略对微软的影响2003~2004年间,全球100强为什么需要.NET框架不同平台(PDA、PC、游戏机)的程序如何在.NET环境下运行?使用C#的程序可以调用VB.NET开发的程序吗?.NETFramework为什么需要.NET框架不同平台(PDA、PC、游戏机)的程序.NET框架概述.NET框架.NET战略的基础框架便捷的开发平台强大的类库.NET程序的运行环境.NET框架公共语言运行时框架类库两个主要组件.NET框架概述.NET框架.NET框架公共语言运行时.NET框架的魅力面向对象编程提高软件可复用、可扩展、易维护性、灵活性强大的动态Web支持Web服务Passport服务MSN,Hotmail都通过PassportWeb服务验证世界级开发工具VisualStudio2005.NET框架的魅力面向对象编程强大的动态Web支持Web服务框架体系结构.NET框架的核心操作系统公共语言运行库(CLR)VC++.NETC#VB.NETVJ#….NETFramework类库(FCL)框架体系结构.NET框架的核心操作系统公共语言运行库(CL框架组件基本框架类Web窗体WebServiceWinFormsADO.NET和XML类.NETFramework.NETFramework类库ASP.NETCLSCLRCTS无论是WinForms和ASP.NET都可以使用ADO.NET与基类库框架组件基本框架类Web窗体WebServiceWin公共语言运行时CLR称为公共语言运行时C#VB.NET代码被执行MSILCLR通用语法,计算机不用了解CLR执行ILC#编译器VB.NET编译器公共语言运行时CLR称为公共语言运行时C#VB.NET公共语言运行时CTS和CLS是CLR的子集CTS(通用类型系统)定义了在IL中的的数据类型VB.NET的Integer和C#的int型都被编译成Int32CLS(公共语言规范)CLR支持的语言功能的子集,包括几种面向对象的编程语言的通用功能公共语言运行时CTS和CLS是CLR的子集框架类库提供对系统功能的访问建立.NET应用程序,组件和控件的基础庞大的类库数量170多个命名空间,上千个类功能齐全,方便使用对文件的基本操作对网络的访问安全控制对图形的操作……框架类库提供对系统功能的访问.NET平台全新的语言配合革命性平台,诞生了C#C#之父AndersHejlsberg曾工作于Borland公司Pascal和Delphi之父1996年赴微软,当时年薪300W$.NET平台全新的语言C#是一种简单、现代、面向对象编程语言目前经历了三个版本1.0、2.0、3.0我们学习的是2.0、3.0Anders.NET平台全新的语言配合革命性平台,诞生了C#Anders自定义命名空间如果在一个项目中,编写了两个功能不同但名字相同的类,就会发生冲突,如何解决冲突?重新命名类名namespaceMySchool{publicclassStudent{}}namespaceYourSchool{publicclassStudent{}}不同的命名空间使用命名空间自定义命名空间如果在一个项目中,编写了两个功能不同但名字相同嵌套命名空间回顾:命名空间用于组织相关类和其他类型与Java的package相似嵌套命名空间namespaceCity{namespaceMySchool{namespaceClass{classStudent{//此处编写代码}}}}引用命名空间:usingCity.MySchool.Class;嵌套命名空间回顾:命名空间用于组织相关类和其他类型names使用别名如果命名空间的名字非常的长给这个嵌套的命名空间指定一个简洁的名字City.MySchool.Classusinguser=City.MySchool.Class;//…namespaceMySchool{classStudent{

user.Studentstu=newuser.Student();}}别名使用别名使用别名如果命名空间的名字非常的长City.MySchool对象对象是人们要进行研究的任何事物

颜色:灰色

排量:3.0刹车产地:德国行驶名字:保时捷行为状态

颜色:红色

排量:4.0刹车产地:意大利行驶名字:法拉利行为状态回顾Java的对象,描述汽车的特征和行为有各自不同的状态对象对象是人们要进行研究的任何事物颜色:灰色排量:3.类和对象小汽车

颜色:灰色

排量:3.0

刹车产地:德国行驶名字:保时捷行为状态类的实例化,是由类具体化对象类产地车体颜色行驶刹车…归纳一组相似对象的共性对象属性方法类描述一组相似对象的共性类和对象小汽车颜色:灰色排量:3.0刹车产地:德国行驶类和对象的应用类和对象的简单应用//…Carferrari=NewCar();ferrari.Run();//…类对象实例化对象调用方法类和对象的应用类和对象的简单应用//…类对象实例化对象调用publicclassStudent{intage=26;

//姓名

privatestringname;publicstringName{get{returnname;}set{name=value;}}//问候publicvoidSayHi(){ …}}类和类的成员类的成员字段属性方法…

类名publicclassStudent类和类的成员类的成员自定义一个类classDBHelper{//数据库连接字符串privatestaticstringconnString="

…";//数据库连接Connection对象publicstaticSqlConnectionconnection=newSqlConnection(connString);}访问修饰符私有公有自定义一个类classDBHelper访问修饰符私有公公有成员和私有成员classstudent{

privatestringname;//姓名

publicintage;//年龄

publicstringidNumber

;//身份证号}…staticvoidMain(string[]args){studentmyStudent=newstudent();

myS="张三";

myStudent.age=20;

}私有成员公有成员实例化一个对象可以访问无法访问编译错误

公有成员和私有成员classstudent私有成员公有成数据安全staticvoidMain(string[]args){studentmyStudent=newstudent();myStudent.age=-2;myStudent.idNumber="123456";

}非法数据身份证号不能被修改无法获得数据无法正常赋值有时候将类中的字段公开是不安全的如果设为私有成员能否对这些字段进行规则约束或者只读呢?数据安全staticvoidMain(string[]在类中使用属性privateintage;//年龄publicintAge{get{returnage;}set{if(value>0&&value<100){age=value;}else{age=18;}}}myStudent.Age=-20;//打印…myStudent.Age=40;//打印…没有访问age公开Age录入非法数据打印私有变量age不公开age通过公有Age访问和约束私有字段age在类中使用属性privateintage;//年龄my什么是属性C#不直接访问类的数据通过访问器访问(get,set)classStudent{

//姓名

privatestringname;publicstringName{get{returnname;}set{name=value;}}}返回nameget用于获取相应字段的值set用于设置字段的值只有get时:只读属性只有set时:只写属性get和set都存在:读写属性属性的类型和字段类型必须一致给name赋值什么是属性C#不直接访问类的数据classStudent返属性的特点privateintage;//年龄publicintAge{get{returnage;}set{if(value>0&&value<100){age=value;}else{age=18;}}}控制私有字段的可访问性保护内部数据的安全建议:类内部敏感字段使用属性来控制访问类型可以是各种数据类型,如:对象、数组等等属性的特点privateintage;//年龄控制私有封装字段将类中的字段、属性绑到一起封装字段封装是面向对象的三大特性之一避免非法数据的访问保证数据的完整性演示:在VS中使用重构——封装字段封装字段将类中的字段、属性绑到一起封装字段封装是面向对象的三在类中使用方法方法是类或对象的行为对象需要做某些事情,在类中添加方法回顾方法的定义访问修饰符返回类型方法名(参数列表){//方法的主体…}通过return返回值如果返回类型是void,方法是否需要返回值?在类中使用方法方法是类或对象的行为访问修饰符返回类型方法的参数参数传递使用值传递,参数值的更改不能保留使用ref可以将参数值的更改保留out类型参数privatestaticvoidAddScore(ref

intscore,outintscoreResult){

if(score>50&&score<60){Console.WriteLine("你的成绩在50-60之间,可以加分。");score=60;}scoreResult=score;}都可以输出结果ref侧重修改,out侧重输出不能写成AddScore(outintscoreResult)方法的参数参数传递privatestaticvoidA方法的使用实现两个整型的加法classAdd{

publicintSum(intpara1,intpara2){returnpara1+para2;}}AddmyAdd=newAdd();intsum=myAdd.Sum(2,3);使用方法实例化一个对象返回结果调用方法方法的使用实现两个整型的加法classAddAddmyA静态方法classmySwap{publicstaticvoidSintnum1,refintnum2){inttemp;temp=num1;num1=num2;num2=temp;}}classProgram{staticvoidMain(string[]args){intnum1=5,num2=10;myS(refnum1,refnum2);}}回顾一下,Swap方法在另一类中如何调用?静态方法使用类名调用静态方法静态方法classmySwapclassProgram回静态方法和实例方法使用static修饰的方法称为静态方法使用实例对象调用的方法叫做实例方法静态方法实例方法static关键字不需要static关键字使用类名调用使用实例对象调用可以访问静态成员可以直接访问静态成员不可以直接访问实例成员可以直接访问实例成员不能直接调用实例方法可以直接访问实例方法、静态方法调用前初始化实例化对象时初始化静态方法和实例方法使用static修饰的方法称为静态方法静态为什么要重载

publicintSum(intpara1,intpara2){returnpara1+para2;}整型参数,返回值整型如果想让两个string型、两个double型相加,怎么做?编写两个不同名字的方法,这样我们在进行调用时要先判断是什么类型,能否不判断直接就能相加呢?为什么要重载publicintSum(intpara方法的重载同一个类中添加几个名字相同,参数与返回值不同的方法

publicstringSum(stringpara1,stringpara2){returnpara1+para2;}

publicdoubleSum(doublepara1,doublepara2){returnpara1+para2;}调用时只要传递参数即可,无需判断类型方法的重载同一个类中添加几个名字相同,参数与返回值不同的方法classAdd{

publicstringSum(stringpara1,stringpara2){…}publicintSum(intpara1,intpara2){…}}重载的方式基于不同类型参数的重载classAdd{

publicintSum(intpara1,intpara2){…}publicintSum(intpara1,intpara2,intpara3){…}}相同类型不同参数个数的重载不允许重载方法仅仅是返回值不同classAdd重载的方式基于不同类型参数的重载clasStudentzhang=newStudent();zhang.Name="张靓靓";zhang.Age=20;zhang.Hobby="唱歌歌";一种特别的方法班级来了新学员添加学员对象学员类实例化对象、设置属性初始属性若太多,设置麻烦能否在实例化时设置属性?publicStudent(stringname,intage,stringhobby){this.Name=name;this.Age=age;this.Hobby=hobby;}Studentzhang=newStudent("张靓靓",20,"唱歌歌");一次设置完成类中加入这个方法添加的方法叫做构造函数Studentzhang=newStudent();构造函数是类中的一种特殊的方法构造函数名与类名相同,不返回任何值可初始化成员变量classStudent{

publicStudent(stringname,intage,stringhobby){this.Name=name;this.Age=age;this.Hobby=hobby;}}初始化成员变量this关键字引用类的当前实例将参数的值,分别赋给当前实例的属性构造函数是类中的一种特殊的方法classStudent初始使用构造函数new

关键字可以实例化一个新的对象指定对某个带参数的构造函数Studentzhang=newStudent("张靓靓",20,"唱歌歌");每次创建类的实例都会调用此方法实例化对象调用构造函数使用new关键字Studentscofield=newStudent();Studentzhang=newStudent("张靓靓",20,"唱歌歌");实例化一个对象实例化一个新对象使用构造函数new关键字Studentzhang=npublicStudent(){}publicStudent(stringname,intage,stringhobby){=name;this.age=age;this.hobby=hobby;}构造函数的重载构造函数也可以重载Studentscofield=newStudent();Studentzhang=newStudent("张靓靓",20,"唱歌歌");方法名相同,参数不同publicStudent(){}构造函数的重载构造函privateinta;publicintA{get{returna;}set{a=value;}}你喜欢读哪段代码?合格的程序要符合编码规则直观易于理解、有意义的单词方便维护有利于调试编码规则的必要性如name,age,studentprivateintname;publicintName{get{returnname;}set{name=value;}}无法理解是什么privateinta;你喜欢读哪段代码?合格的程序为什么使用常量publicclassCompute{doublepi=3.14;//计算圆的周长publicdoublePerimeter(doubleradius){return2*pi*radius;}//计算圆的面积publicdoubleArea(doubleradius){returnpi*radius*radius;}}这个类中,会反复使用pi如果pi在类中被修改了,计算结果错误如何避免pi在类中被修改?为什么使用常量publicclassCompute这个类常量常量在使用过程中值不会发生变化常量程序中反复使用const类型常量名=常量值程序中不会被改变staticvoidMain(string[]args){

constintPI=3.14;

PI=3.20;}强制赋值会发生错误常量名通常使用大写常量常量在使用过程中值不会发生变化const类型常量随意赋值的危险conststringGENDER_M="男";conststringGENDER_F="女";…//性别privatestringgender;publicstringGender{get{returngender;}set{gender=value;}}用常量给属性赋值:student.Gender=GENDER_M;也可以这样给属性赋值:student.Gender="School";为Student类添加性别的属性,用常量赋值有违常理,非法数据随意赋值的危险conststringGENDER_M=什么是枚举用一种新的类型定义enumpublicenumGenders{Male,Female}//性别privateGendersgender;publicGendersGender{get{returngender;}set{gender=value;}}这样给属性赋值:student.Gender=Genders.Male;如果这样属性赋值:student.Gender="School";类型不同不能赋值性别属性的类型Genders是一个枚举类型代码错误什么是枚举用一种新的类型定义enumpublicenum枚举定义枚举是一组描述性的名称枚举定义一组有限的值,不能包含方法对可能的值进行约束枚举允许描述性名称表示整数值访问修饰符enum枚举名{值1,值2…}publicenumSchool{T1,T2,T3}publicenumSchool{T1=1,T2=2,T3=3}//……Console.WriteLine(“T2的整数值是{0}.",(int)(School.T2));取得枚举表示的整数值枚举定义枚举是一组描述性的名称访问修饰符enum枚举名枚举与其它类型的转换枚举转换为字符串字符串转换为枚举publicenumSchool{T1,T2,T3}//……Console.WriteLine(“T2的值是{0}.",School.T2.ToString());(School)(Enum.Parse(typeof(School),“T2");需要转换的字符串枚举与其它类型的转换枚举转换为字符串publicenum枚举的特点汽车类有一个成员是车身颜色staticvoidMain(string[]args){string[]color=newstring[]{"red","black","write"};Console.WriteLine("我要选择的颜色是:{0}",color[0]);}使用时,必须了解数组的构成枚举可以用描述性的名称表示值,使用时无需了解它的构成privateenumcolor{red,write,black}staticvoidMain(string[]args){Console.WriteLine("我要选择的颜色是:{0}",color.red);}枚举枚举的特点汽车类有一个成员是车身颜色staticvoid枚举的典型应用DialogResultchoice;choice=MessageBox.Show("确定要退出吗?","退出系统",MessageBoxButtons.OKCancel,MessageBoxIcon.Information);if(choice==DialogResult.OK)Application.Exit();DialogResult是个枚举,指示对话框的返回值这样我们就不会判断一些非法的值,导致系统异常枚举的典型应用DialogResultchoice;Dia为什么需要结构有很多预定义颜色正常人眼可分辨的颜色种类可达几十万种以上Color提供使用RGB值返回颜色的方法FromArgb()

System.Drawing.Color有很多颜色值,它是一个枚举吗?System.Drawing.Color是一个结构

为什么需要结构有很多预定义颜色正常人眼可分辨的颜色种类可达几结构定义结构中有属性,也可以有方法publicstructStructStudent{publicstringName;publicintAge;publicstringHobby;publicintPopularity;publicvoidSayHi(){//….}}访问修饰符struct结构名{定义结构成员}构成和类相似定义成员变量不能赋初值成员方法结构定义结构中有属性,也可以有方法publicstruct//…StructStudentmyStu;myStu.Age=20;myStu.Gender=Genders.Female;myStu.Hobby="唱歌歌";myStu.Name="张靓靓";myStu.Popularity=100;myStu.SayHi();//…结构的使用2-1定义结构可以不用new为结构成员赋值调用结构的方法运行结果和第二章的SayHi相同//…结构的使用2-1定义结构可以不用new为结构成员赋值//…

StructStudentmyStu=newStructStudent("张靓靓",Genders.Female,20,"唱歌歌",100);myStu.SayHi();//…结构的使用2-2structStructStudent{//…publicStructStudent(stringname,Gendersgender,intage,stringhobby,intpopularity){this.Name=name;this.Gender=gender;//…}}可以有构造函数只能声明有参数的构造函数构造函数传参//…结构的使用2-2structStructStude理解结构与类的区别都可以实现接口都可以包含字段、方法相同点结构中给字段赋值是错误的类中可以给字段赋值创建对象可以不用new创建对象必须使用new可以添加构造函数,但它们必须带参数可以添加无参的构造函数不可以有默认构造函数可以有默认构造函数不能被继承可以被继承值类型引用类型不同点结构类

理解结构与类的区别都可以实现接口都可以包含字段、方法相同点结值类型与引用类型使用类版Student和结构版Student实现下面操作staticvoidMain(string[]args){//使用值类型StructStudentstudent1=newStructStudent();StructStudentstudent2=newStructStudent();student1.Age=18;student2=student1;student2.Age=20;Console.WriteLine("student1={0},student2={1}",student1.Age,student2.Age);}staticvoidMain(string[]args){//使用引用类型Studentstudent1=newStudent();Studentstudent2=newStudent();student1.Age=18;student2=student1;student2.Age=20;Console.WriteLine("student1={0},student2={1}",student1.Age,student2.Age);}值类型与引用类型使用类版Student和结构版Student值类型值类型直接存储值Age=18student1student1studnet2student1.Age=18Age=18Age=18student2=student1student1.Age

student1studnet2Age=18Age=20student2.Age=20值类型值类型直接存储值Age=18student1stude引用类型student1student1.Age=18Age=18引用类型存储对值的引用student1studnet2student2=student1student1.Age

两个变量都发生变化Age=20student1studnet2student2.Age=20引用类型student1student1.Age=18A拆箱和装箱值类型和引用类型之间的转换值类型引用类型装箱拆箱staticvoidMain(string[]args){inti=123;objecto=i;//装箱

i=456;//改变i的内容

Console.WriteLine("值类型的值为{0}",i);Console.WriteLine("引用类型的值为{0}",o);}staticvoidMain(string[]args){inti=123;objecto=i;//装箱

intj=(int)o;}//拆箱与值类型的变量类型要一致拆箱和装箱值类型和引用类型之间的转换值类型引用类型装箱拆值方式的参数的传递值传递方式传递值类型:结构:StructStudent不会被修改

//传递值类型参数StructStudentscofield=newStructStudent("Scofield",Genders.Male,28,"越狱狱");scofield.SayHi();Vote(scofield);scofield.SayHi();privatevoidVote(StructStudentstu){stu.Popularity++;}人气属性加1的方法人气加1两次的人气值相同,参数未发生变化值传递值方式的参数的传递值传递方式传递值类型://传递值类型参数值方式的参数的传递值传递引用类型时:类:Student参数在程序中被修改

//传递引用类型参数Studentscofield=newStudent("Scofield",Genders.Male,28,"越狱狱");scofield.SayHi();Vote(scofield);scofield.SayHi();引用类型:类人气属性加1的方法人气加1值方式的参数的传递值传递引用类型时://传递引用类型参数引引用方式传递传递值类型传递引用类型ref方式传递完全修改privatevoidVote(refStructStudentstu){stu.Popularity++;}ref引用方式传递参数引用方式传递传递值类型传递引用类型ref方式传递完全修改pr值类型和引用类型细分数组:int[],string[]数组接口:interface接口自定义类:class字符串:string基类:System.Object类引用类型结构:struct结构类型枚举:enum枚举类型布尔型:bool字符型:char浮点型:float长整型:long整型:int基本数据类型值类型描述类别值类型和引用类型细分数组:int[],string[]数组接传递数组数组是值类型还是引用类型//…int[]odd={1,3,5};PrintArray(odd);ChangeToEven(odd);PrintArray(odd);//…privatevoidChangeToEven(int[]arr){for(inti=0;i<arr.Length;i++){arr[i]=i*2;}}值方式传递arr[0]=1arr[1]=3arr[2]=5arr[0]=0arr[1]=2arr[2]=4参数被修改数组是引用类型传递数组数组是值类型还是引用类型//…privatevoi什么是索引器能否通过姓名访问学员?publicStudentthis[intindex]{get{returnstudents[index];}}Students类中添加

//采用索引器的方式MyClassmyClass=newMyClass("T01");myClass.Students[2].SayHi();myClass.Students["周杰杰"].SayHi();…可以按照索引访问重载的索引器根据姓名查找学员什么是索引器能否通过姓名访问学员?publicStud索引器的特点DataRow["列名"]DataReader["列名"]数组属性只能根据下标(索引)来访问索引器可以被重载可以使用更灵活的方式访问,定义访问方式我们以前用过的索引器索引器的特点DataRow["列名"]DataReader类图VS2005的类图类图描述类的结构查看一个类的类图“锁”表示私有不同字段有不同的图标类图VS2005的类图类图描述类的结构查看一个类的类图“锁通用的类图-age:int-name:string+Name:string类名Student+SayHi():void“-”表示私有“+”表示公有“:”后是变量类型“:”后是返回类型读懂类图是OOP的基本要求通用的类图-age:int类名Student+SayHi(代码冗余对比这两个类:Student和Teacher加入校长、班主任的类,都需要加入这几个属性,代码冗余年龄、性别、姓名是重复的如何共用重复代码?代码冗余对比这两个类:Student和Teacher加入提取冗余代码将公共的成员放到一个类中保留自己特有的成员保留自己特有的成员提取冗余代码将公共的成员放到一个类中保留自己特有的成员保留自提取后的应用classStudent:Person{publicStudent(){}//爱好privatestringhobby;publicstringHobby{get{returnhobby;}set{hobby=value;}}…}1、提取后的Student类只有学员特有的属性2、创建一个学员对象Studentzhang=newStudent();zhang.Name="张靓靓";zhang.Age=20;zhang.Gender=Genders.Female;zhang.Hobby="唱歌歌";公共属性可以访问继承提取后的应用classStudent:Person1、提取卡车和巴士都是汽车生活中的继承汽车刹车行驶共有行为:轮子发动机共有特征:卸货拉货各自行为:载重货舱各自特征:停靠站报站各自行为:载客量客舱各自特征:他们共有的特征来自汽车有什么共同特征呢?卡车公共汽车卡车和巴士都是汽车生活中的继承汽车刹车行驶共有行为:轮子父类和子类在C#中,一个类可以继承另一个类Person子类继承父类,父类派生子类学员和老师类都继承PersonStudentTeacher子类父类Student类继承Person类Person类派生Student类子类又叫派生类父类又叫基类classStudent:Person父类和子类在C#中,一个类可以继承另一个类Person子类继承概述继承需要符合的关系:is-aStudentisaPerson子类继承父类的成员子类可以有自己的成员继承父类的成员自己特有的成员继承是面向对象的一个重要特性继承在类图中的表示继承概述继承需要符合的关系:is-aStudentisa继承的实际应用1班上所有的人都做自我介绍SayHi()学员大家好,我是某某同学,今年多少岁,喜欢什么老师大家好,我是某某老师,今年多少岁,工作几年了子类中访问继承父类的公共属性子类特有属性继承的实际应用1班上所有的人都做自我介绍SayHi()学员继承的实际应用2公共属性加入父类有独自的SayHi()继承的实际应用2公共属性加入父类有独自的SayHi()继承的实际应用3Teacher和Student类都继承PersonpublicclassStudent:PersonpublicclassTeacher:PersonpublicStudent(stringname,Gendersgender,intage,stringhobby,intpopularity){this.Name=name;this.Age=age;this.Gender=gender;//学生类扩展的属性

this.Hobby=hobby;this.Popularity=popularity;}构造函数设置公共属性与独有属性继承自父类的公共属性子类扩展的属性继承的实际应用3Teacher和Student类都继承Per继承的实际应用4都有不同的SayHi()方法publicvoidSayHi(){//学生的SayHi}publicvoidSayHi(){//老师的SayHi}创建对象调用SayHi()Studentzhang=newStudent(…);Teacherjacky=newTeacher(…);zhang.SayHi();jacky.SayHi();学生调用自己的SayHi()老师调用自己的SayHi()继承的实际应用4都有不同的SayHi()方法publicvbase关键字关键字base的作用调用父类的属性和方法调用父类的构造函数publicvoidSayHi(){stringmessage=string.Format("大家好,我是{0}同学,今年{1}岁了,我喜欢{2}!",

base.Name,base.Age,this.hobby);MessageBox.Show(message);}调用父类的属性publicStudent(stringname,Gendersgender,intage,stringhobby,intpopularity):base(name,age,gender){//学生类扩展的属性

this.Hobby=hobby;this.Popularity=popularity;}this.Name=name;this.Age=age;this.Gender=gender;调用父类的构造函数base关键字关键字base的作用publicvoidSprotected访问修饰符protected访问修饰符允许子类访问protected访问修饰符不允许其他非子类访问不可以可以可以protected不可以不可以可以private可以可以可以public其他类子类类内部

父类成员如果父类中的某个成员只允许其子类访问public修饰所有类都可以访问private修饰子类无法访问protected访问修饰符protected访问修饰符允许继承的传递性汽车双层单层小型卡车重型卡车同样具有汽车的特征继承的传递性卡车公共汽车还可以派生更多的类型继承的传递性汽车双层单层小型卡车重型卡车同样具有继承的传递性添加一个微型卡车类publicclassSmallTruck:Truck{protectedvoidsmallTruckRun(){Console.WriteLine("微型卡车在行驶!");}staticvoidMain(string[]args){SmallTrucksmalltruck=newSmallTruck();smalltruck.vehicleRun();

smalltruck.truckRun();smalltruck.smallTruckRun();}}publicclassTruck:Vehicle继承关系父类的父类成员父类的成员传递性继承的传递性添加一个微型卡车类publicclassSm继承单根性publicclassCharmingStudent:SportsMan,Musician编译错误C#中子类不能继承多个父类CharmingStudent

运动员音乐家某类学员是否可以这样描述?具有两种人的特征继承单根性publicclassCharmingStud隐式调用父类的构造函数Person类中去掉了构造函数publicPerson(){}“Person”方法没有采用“0”个参数的重载classStudent:Person{publicStudent(){}publicStudent(stringname,Gendersgender,intage,stringhobby,intpopularity)}base()隐式的调用base()子类的构造函数没有使用base指明调用父类哪个构造函数父类要提供无参的构造函数隐式调用父类的构造函数Person类中去掉了构造函数publ显示调用父类的构造函数如果父类没有无参的构造函数子类构造函数必须指明调用父类哪个构造函数publicStudent():base("张靓靓",20,Genders.Female){}publicStudent(stringname,Gendersgender,intage,stringhobby,intpopularity):base(name,age,gender){}显示调用父类的构造函数如果父类没有无参的构造函数子类构造函数软件开发中的继承模拟了现实世界的关系实现代码重用结构更清晰Student爱好…Person姓名年龄…子类更加关注与子类相关的行为和状态共有属性由父类负责软件开发中的继承模拟了现实世界的关系Student爱好…Pe窗口继承布局发生调整,需要同时改变三个窗体,复杂度增加通过继承,很好很有效地保持了界面的一致性和共同行为子类窗口按钮要实现不同的功能访问修饰符应该设置为protected窗口继承布局发生调整,需要同时改变三个窗体,复杂度增加通过继回顾继承Person类老师

学员SayHi()SayHi()继承List<Person>SayHi()遍历List,循环SayHi()内容不同将所有人都存入集合调用两种类型的SayHi()方法回顾继承Person类老师学员SayHi()Say扩展的麻烦for(inti=0;i<person.Count;i++){if(person[i]isStudent){((Student)person[i]).StuSayHi();}elseif(person[i]isTeacher){((Teacher)person[i]).TeachSayHi();}}进行判断对象类型调用相应类的SayHi()添加多个不同的子类,SayHi()都不同,增加代码复杂度如何解决?添加对象后遍历泛型集合扩展的麻烦for(inti=0;i<perso巧妙的做法abstractclassPerson{publicabstractvoidSayHi();}for(inti=0;i<person.Count;i++){person[i].SayHi();}这种方式实现了面向对象的多态

修改Person类添加一个未实现的方法用关键字修饰去除子类类型判断巧妙的做法abstractclassPersonfor(生活中的多态Cut….!!!听到这个声音他们会做什么?剪断头发切开皮肤停止表演不同对象对于同一个方法(Cut)调用的不同行为理发师外科医生演员生活中的多态Cut….!!!听到这个声音他们会做什么?剪断头什么是多态指不同对象收到相同消息时,会产生不同行为Student和Teacher类SayHi()的内容不同同一个类在不同的场合下表现出不同的行为特征PersonStudentTeacherPerson类,在这两种场合的行为不同什么是多态指不同对象收到相同消息时,会产生不同行为Stude抽象类和抽象方法abstractclassPerson{publicabstractvoidSayHi();}抽象方法一个没有实现的方法有抽象方法的类必然是抽象类抽象类用来列举一个类所需要的行为抽象类不明确提供具体实现方法抽象类必须由其子类实现它的抽象方法(除非子类也具有抽象性)抽象类和抽象方法abstractclassPerson抽常见错误抽象类不能被实例化抽象类不能是密封或静态的Personperson=newPerson();编译错误抽象类不能用sealed和static修饰常见错误抽象类不能被实例化抽象类不能是密封或静态的Perso实现抽象方法使用override实现抽象方法publicoverridevoidSayHi(){//…具体实现内容}重写实现抽象方法实现抽象方法使用override实现抽象方法publicoDog:AnimalCat:Animal抽象类的应用场合abstract

Animal

抽象类和抽象方法实现多态性父类提供一系列规定,约束子类的行为父类可以提供一些共性的行为猫咪喵喵叫狗狗汪汪叫abstract叫()是动物就要会叫Dog:AnimalCat:Animal抽象类的里氏替换原则//…Studentstu1=newStudent();Studentstu2=newStudent();List<Person>person=newList<Person>();person.Add(stu1);person.Add(stu2);//…子类对象可以替换父类里氏替换原则(LSP)子类的对象能够替换其父类父类对象不能够替换子类父类的方法都要在子类中实现或者重写里氏替换原则//…子类对象可以替换父类里氏替换原则(LSP)is与as操作符is检查对象是否与指定类型兼容if(person[i]isStudent)判断person集合的元素是否是Student对象as用于在兼容的引用类型之间执行转换for(inti=0;i<Students.Count;i++){Studentstu=Students[i]asStudent;Console.WriteLine(stu.Name);}转换失败返回值为空一种类型转换方式is与as操作符is检查对象是否与指定类型兼容if(pe为什么需要虚方法大家好,我是某某先生(女士),今年多少岁抽象方法不能在父类实现学员大家好,我是某某同学,今年多少岁,喜欢什么老师大家好,我是某某老师,今年多少岁,工作几年了提供一个通用的方式继续完善MySchool学员和老师也可以使用通用方式默认SayHi()能否写在Person类中?各子类可以重写不同行为SayHi()可以使用虚方法实现为什么需要虚方法大家好,我是某某先生(女士),今年多少岁抽象使用虚方法//Person类中默认实现通用的SayHi()publicvirtualvoidSayHi(){//…省略具体实现}虚方法用默认的SayHi()的对象,子类中不需要重写SayHi()用自己的SayHi()子类中要重写SayHi()同样使用override重写使用虚方法//Person类中默认实现通用的SayHi()虚只能在抽象类中除了密封类都可以写必须被子类override可以被子类override不允许有方法体要有方法体,哪怕是一个分号用abstract修饰用virtual修饰抽象方法虚方法虚方法与抽象方法只能在抽象类中除了密封类都可以写必须被子类override面向对象的三大特性隐藏内部实现,稳定外部接口封装继承子类继承父类成员,实现代码复用多态不同子类对同一个消息作出不同的反映面向对象的三大特性隐藏内部实现,稳定外部接口封装继承子类生活中的接口生活中的接口USB接口使用USB接口必须符合USB规范接口是一套规范,遵守这个规范就可以实现功能生活中的接口生活中的接口USB接口使用USB接口必须符合US.NET接口同样是一种规范和标准可以约束类的行为定义一个接口不指定具体的实现.NET接口一个类实现IComparable,在类中强制实现CompareTo方法publicinterfaceISampleInterface{stringName{get;set;}}publicinterfaceISampleInterface{voidShowName();}interface属性方法…接口中可以包含的内容.NET接口同样是一种规范和标准.NET接口一个类实现ICo接口的使用接口的名称通常以“I”开头IComparable,IList使用方法与继承一个类相似如果类继承了父类classStudent:IComparableclassStudent:Person,IComparable继承了一个类,实现了一个接口类图中的表示接口的使用接口的名称通常以“I”开头classStuden接口的特点接口可以说是对继承单根性的扩展C#中一个类能否继承多个父类?不能classStudent:Person,IComparable接口提供了一组规范,一个标准接口屏蔽了实现的细节Sort方法排序时,无需关心IComparable如何实现方便多人协同开发可以一组人实现IComparable,一组人去做排序功能接口的特点接口可以说是对继承单根性的扩展C#中一个类能否继自定义接口如老师和学员都可以收作业,那么收作业的方法应该放在哪个类?A:Teacher类B:Student类C:两个都放D:Person类E:重新定义造成代码冗余如果增加一个工程师类,他不会收作业如果继承这个类,Person类怎么办?调用收作业的方法不需要改变自定义一个接口来实现IHomeworkCollector自定义接口如老师和学员都可以收作业,A:Teacher类B:自定义接口publicinterfaceIHomeworkCollector{voidCollectHomework();}publicclassStudent:Person,IHomeworkCollectorpublicvoidCollectHomework(){MessageBox.Show("报告老师!作业收集完毕!");}1、定义一个收作业的接口2、在有收作业功能的类实现该接口3、不同的类收作业方式不同自定义接口publicinterfaceIHomewor使用自定义接口1、接口作为参数使用privatevoidDoCollectHomework(IHomeworkCollectorcollector){

collector.CollectHomework();}无论谁收作业这里都不需要做任何改变2、接口作为返回值使用DoCollectHomework(scofield);privateIHomeworkCollectorCreateHomeworkCollector(stringtype){

switch(type){case"student":collector=newStudent("Scofield",Genders.Male,28,"越狱狱");break;//…}returncollector;}返回一个实现该接口的对象collector.CollectHomework();使用自定义接口1、接口作为参数使用privatevoid作为返回值和参数的意义接口作为参数传递了实现接口的对象接口作为返回值返回一个实现了接口的对象作为返回值和参数的意义接口作为参数接口和抽象类的对比派生类必须实现未实现的方法

包含未实现的方法

不能实例化相似点直接实现需要override实现抽象方法

实现接口的类必须实现所有成员非抽象派生类必须实现抽象方法

可以实现多个接口只能继承一个类

用interface定义用abstract定义不同点接口抽象类

接口和抽象类的对比派生类必须实现未实现的方法包含未实现的方数组的局限string[]Students=newstring[3]{"张三","李四","王五"};如果每个班级的人数不固定班级中来了一个新的学员班级人员的数组调整大小困难增加元素困难能否动态的维护一个集合?重新定义数组相同类型和名称变量的集合数组的局限string[]Students=newsArrayList是一个可动态维护长度的集合可维护动态长度的集合新增元素可删除元素可访问单个元素objectobjectobjectobject0123索引(下标)object40123ArrayList自动调整索引通过索引访问ArrayList是一个可动态维护长度的集合可维护动态长度的ArrayList的初始化usingSystem.Collections;//…ArrayListStudents=newArrayList();ArrayListTeachers=newArrayList(5);可以指定长度引入命名空间实例化一个对象常见错误未引入命名空间定义时未实例化引入System.Collections命名空间实例化ArrayList对象ArrayList的初始化usingSystem.CollArrayList添加元素intAdd(Objectvalue)//添加一个对象到集合的末尾ArrayListstudents=newArrayList();Studentscofield=newStudent("Scofield",Genders.Male,28,"越狱狱");//…students.Add(scofield);创建学员对象添加学员连续添加三个学员对象并获取集合元素的数目返回索引ArrayList.Count获取元素数目建立班级学员的集合ArrayList添加元素intAdd(Objectva访问ArrayList元素(类型)ArrayList[index]//按指定索引(下标)取得对象Studentstu1=(Student)students[0];stu1.SayHi();…按索引取值转换为学员对象ArrayList第一个对象的索引是0需要类型转换访问ArrayList元素(类型)ArrayList[in删除ArrayList的元素ArrayList.Remove(对象名)//删除指定对象名的对象ArrayList.RemoveAt(index)//删除指定索引的对象ArrayList.Clear()//清除集合内的所有元素students.RemoveAt(0);students.Remove(zhang);Studentleave=(Student)students[0];leave.SayHi();通过索引删除对象通过指定对象删除只剩一个对象剩余的元素会自动调整索引取得删除后的第一个对象删除ArrayList的元素ArrayList.RemoveArrayList的遍历//遍历foreach(Objectstuoinstudents){StudentstuForeach=(Student)stuo;Console.WriteLine(stuForeach.Name);}通过对象遍历打印对象的Name属性Scofield张靓靓周杰杰可以使用和数组类似的方式for(in

温馨提示

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

评论

0/150

提交评论