版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
.net课程系列C#高级编程.NET方向
第二学期课程第一章面向对象高级编程Newture新程教育面向对象介绍封装多态之重载使用可选参数和命名参数继承继承介绍继承之隐藏与重写扩展方法面向对象之多态面向对象之抽象本章目录面向对象之接口面向对象之值类型与引用类型面向对象之结构面向对象之枚举面向对象之命名空间本章目录一次失败的面试小菜今天计算机专业大四毕业,学了不少软件开发的东西,也学着编了不少小程序,踌躇满志,一心想找个好单位。当投了N份简历后,终于收到一个单位的面试通知,欣喜若狂。到了人家单位,前台小姐给了他一份题目,上面写着“请用C++,java,C#或VB.NET任意一种面向对象语言实现一个简单的计算器控制台应用程序,要求输入两个运算数和运算符,得到结果”。小菜一看,这不很简单,三下五除二,5分钟不到,小菜写完了,觉得也没错误。交卷后,单位说一周之内等通知。于是小菜耐心等待。可是半个月过去了,什么消息也没有,小菜很郁闷,我的代码实现了啊,为什么不给我机会?面向对象介绍初识面向对象所有的编程初学者都有同样的问题——就是碰到问题只考虑怎么去解决眼下的问题,而不考虑这种解决问题的方式是否能反复使用、当条件发生变化时这种解决问题的方式是否还能适用。比如计算器这个程序,先要求输入两个两个数和运算符,然后根据运算符判断选择如何运算,得到结果,这本身没错,但这样的思维却使得我们的程序只为满足当前的需求,缺少灵魂。
不易维护
不易扩展低质量
不易复用面向对象介绍面向对象:它是一种思想,这种思想就是把构成问题的事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。面向对象=对象+类+继承+通信面向对象是根据现实世界中客观存在的事物(即对象)的本质特点,抽象地表示为系统中的类,作为系统的基本构成单元,这使得系统可以直接映射客观世界,并在保持客观世界中事物及其相互关系的本来面貌。面向对象的最小的程序单元是类,类可以生成多个对象,而对象则直接映射成客观世界的各种事物。例如:五子棋游戏的设计面向对象介绍五子棋游戏的设计不采用面向对象思想面向对象介绍开始游戏黑子先走绘制画面判断输赢轮到白子绘制画面判断输赢输出最后结果回到步骤二进行下一局五子棋游戏的设计采用面向对象思想面向对象介绍黑白双方这两方的行为是一模一样的棋盘系统负责绘制画面规则系统负责判定诸如犯规、输赢等面向对象与面向过程面向过程是把一件事、一项工程分解为一个个的功能模块,用函数来实现。函数是面向过程的核心。面向对象是把一项工程看成是一个个的对象组成,这些对象之间的相互关系,构成了整个项目。类和对象是构成面向对象的程序的主体,也是本章讨论的重点。面向对象程序设计是在面向对象思想指导下进行的软件开发工作,由OOA(面向对象分析),OOD(面向对象设计),OOP(面向对象编程)三个部分有机构成。面向对象介绍面向对象的胜利—四大发明之活字印刷话说三国时期,曹操带领百万大军攻打东吴,大军在长江赤壁驻扎,军船连成一片,眼看就要灭掉东吴,统一天下,曹操大悦,于是大宴众文武,在酒席间,曹操诗性大发,不觉吟道:“喝酒唱歌,人生真爽。…………”。众文武齐呼:“丞相好诗!”于是一臣子速命印刷工匠刻版印刷,以便流传天下。面向对象介绍面向对象的胜利—四大发明之活字印刷样张出来给曹操一看,曹操感觉不妥,说道:“喝与唱,此话过俗,应改为‘对酒当歌’较好!”,于是此臣就命工匠重新来过。工匠眼看连夜刻版之工,彻底白费,心中郁闷。只得照办。面向对象介绍面向对象的胜利—四大发明之活字印刷样张再次出来请曹操过目,曹操细细一品,觉得还是不好,说:“人生真爽太过直接,应改问语才够意境,因此应改为‘对酒当歌,人生几何?…………’!”当臣转告工匠之时,工匠吐血身亡!面向对象介绍面向对象的胜利—四大发明之活字印刷可惜三国时期活字印刷还未发明,所以类似事情应该时有发生,如果是有了活字印刷。则只需更改四个字就可,其余工作都未白做。实在妙哉。面向对象介绍面向对象的胜利—四大发明之活字印刷要改,只需更改要改之字,此为可维护;这些字并非用完这次就无用,完全可以在后来的印刷中重复使用,此乃可复用此诗若要加字,只需另刻字加入即可,这是可扩展;的排列其实有可能是竖有可能是横排,此时只需将活字移动就可做到满足排列需求,此是灵活性好。活字印刷术之前,上面的四种特性都无法满足,要修改,必须重刻;要加字,必须重刻;要重新排列,必须重刻,印完这本书后,此版已无任何可再利用价值。面向对象介绍面向对象程序设计中有两个重要概念:类(Class)和对象(Object,也称之为实例)。具有相同或相似性质的一组对象的抽象就是类,类是对一类事物的描述,是抽象的、概念上的定义。对象是实际存在的该类事物的每个个体,因而也称为实例(instance)对象的抽象是类,类的具体化就是对象,也可以说是的实例是对象。类是用来描述一系列对象,类概述每个对象应包括的数据,概述每个对象的行为特征。因此可以把类理解为某种概念、定义,它规定了某类对象所共同具有的数据和行为特征。常说的“人类”是指的“类”,如果具体说“张三”这个人,则“张三”就是“人类”这种类型的一个具体对象了。面向对象介绍思考:先有类还是先有对象?面向对象介绍深入理解C#中的类类是一种自定义的数据类型,就像整形和字符型,可以使用类来声明变量,用类声明的变量称之为引用型变量。所以,类是引用型数据类型。C#提供了创建类和对象的功能,用C#编程时,要做的主要工作就是定义组成程序各种类。类定义可以作为一个模板或蓝图,封装了它的对象的数据和行为。一旦类定义好了,就可以以它作为模版来创建类的对象或实例。面向对象介绍匿名类:它提供了一种方法,将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。类名由编译器生成,并且不能在源代码级使用。每个属性的类型由编译器推断。例如:varv=new{Amount=108,Message="Hello"};面向对象介绍面向对象的优点与人类的思维方法一致稳定性好可重用性好易于开发大型软件产品可维护性好面向对象介绍面向对象的基本特征:封装、继承、多态(或加:抽象)封装(Encapsulation),是指将对象的实现细节隐藏起来,然后用公共方法来暴露该对象的功能。继承(Inheritance),是软件实现复用与共享的重要方式,当子类继承父类后,子类将获得父类的属性和方法,并可以在父类的基础上扩展自己的功能。多态(Polymorphism),多种形态。是指同一类型的对象在运行时可能表现出不同的行为特征。除此之外,抽象也是面向对象的重要组成部分,抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注重与当前目标有关的那部分。抽象并不打算考虑全部问题,而只是考虑部分问题。面向对象介绍封装:指将对象的实现细节隐藏起来,然后用公共方法来暴露该对象的功能。它有两层含义:第一:将方法和数据合并到一个类中;换言之,为了支持分类第二:控制对方法和数据的访问;换言之,为了控制类的使用封装的优点:隐藏类的实现细节让使用者只能通过实现预定的方法来访问数据,从而可以在该方法里加入控制逻辑,限制对属性的不合理访问可以进行数据检查,从而有利于保证对象信息的完整性封装实际上有两个方面的含义:把该隐藏的隐藏起来,把该暴露的暴露出来。封装封装举例例如与你住一个小区一栋楼上的一个美女邻居,大家看她的装扮知道是女性,那性别这个属性与她见过的人都知道,因为住在一个楼上是邻居,她的名字你知道,但她的生日除去父母亲人外你可能就不知道了,最后比如女孩最近学会了抽烟,常常在家中无人时一个人躲在厕所抽两口,抽烟这个方法只有她一个人知道,并且不准备告诉任何人。上例中女孩的性别属性就是公开的,姓名生日属性就是半公开的,抽烟方法就是私有的,我们也把别人不知道不能访问的属性方法叫隐藏的属性方法,这个就是封装的一种表现。封装封装举例老师最近手头比较紧,想找班里某位同学借点小钱周转一下,我向张三开口了,说借旺旺老师十万块大洋小花一下怎么样?张三竟然拍着胸膛说没问题,其实他要是犹豫的说“旺旺老师只能借你一万”我心里还比较安心,现在他说没问题我反而没底了。那我就问,张三啊,你准备怎么弄这十万块大洋呢?不会去工地做苦力或卖血去吧!张三对我说,反正下次上课我给你把钱带来就行了,至于我怎么筹钱老师您就甭管了上例中张三给我提供了一个可以访问的借钱方法,返回值是十万块大洋,我能看到的只是方法的声明,那它的方法体内部是怎么实现的我无从知晓,我们把这隐藏方法实现细节的过程也称为封装。封装封装的实现:C#的封装通过访问修饰符实现C#支持五种访问修饰符封装访问修饰符说明public公有访问。不受任何限制private私有访问。只限于本类成员访问,子类、实例均不能访问protected保护访问。只限于本类和子类访问,实例不能访问。internal内部访问。只限于本项目内访问,其他不能访问。protectedinternal内部保护访问。只限于本项目或是子类访问,其他不能访问访问修饰符说明直接声明在命名空间中的类的访问修饰符只能是public或internal类默认访问修饰符是internal类的成员默认访问修饰符是privateprotectedinternal是受保护或内部,而不是受保护和内部。一般类的字段是私有的(private),属性和方法是公共(public)的封装重载(overloaded):在同一个类中,允许出现两个或以上的同名方法,这种现象我们称之为重载。重载主要应用于针对不同的数据类型执行相同操作时。重载的语法要求(两同一不同)在同一类中方法名相同参数列表不同:参数数量不同或参数类型不同不能重载方法的返回类型多态之重载重载举例:Console.WriteLine()四个获取最大值的Max方法多态之重载MicrosoftWindows使用的一项技术是组件对象模型技术(ComponentObjectModel),COM不支持重载方法,相反它允许获取可选参数。为了方便在C#解决方案中集成COM库和组件,C#提供了对可选参数的支持。可选参数在很多情况下很有用。有的时候,参数类型差异不足以是编译器区分两个不同的实现,造成无法使用重载技术,在这个时候,可选参数提供一个简单、好用的解决方案。使用可选参数和命名参数例:
publicvoidDoWorkWithData(intintData,floatfloatData,intmoreIntData){……}现在,假定你想提供只获得两个参数(intData
,floatData
)的一个DoWorkWithData方法实现:
publicvoidDoWorkWithData(intintData,floatfloatData){……}写一个语句调用DoWorkWithData方法时,可提供恰当类型的两个或三个参数,编译器会根据类型信息判断应该调用哪个重载版本: intarg1=99;
floatarg2=100.0F;
intarg3=101;
DoWorkWithData(arg1,arg2,arg3); DoWorkWithData(arg1,arg2);使用可选参数和命名参数到目前为止一切都还好,但是,如果你要实现DoWorkWithData的另外两个版本,他们只获取第一个参数和第三个参数,那么你或许会很快的写出以下重载版本:
DoWorkWithData(intintData){……}
DoWorkWithData(intmoreIntData){……}现在的问题对于编译器来说,这两个重载版本是完全一致的,程序将无法通过编译。在这种情况下,使用可选参数和命名参数可以有效的解决这个问题。使用可选参数和命名参数为了指定一个参数是可选的,可以在定义方法是为该参数提供一个默认值。例:
voidOptMethod(intfirst,doublesecond=0.0,stringthird=“Hello”){……}所有可选的参数都只能放在必须的参数之后。调用支持可选参数的一个方法时,采用的方式和调用其他任何方法一样,都是指定方法名,并提供任何必须的参数(实参)。区别在于,调用支持可选参数的方法时,可省略对应的实参。例:
OptMethod(99,123.45,”world”);//全部三个参数都提供了实参
OptMethod(99,123.45);//只为前两个参数提供了实参使用可选参数和命名参数C#默认根据每个实参在方法调用中的位置判断他们对应于哪个形参。在C#中还允许按照名称指定参数,利用这个功能,就可以按照不同的顺序传递实参了。为了将一个实参作为命名参数来传递,必须输入参数名,一个冒号,然后要传递的值。例:OptMethod(first:99,second:123.45,third:”world”)这个功能还允许你省略实参:
例如:OptMethod(first:99,third:”world”);此时second参数则使用默认值另外还可以兼按位置和名称来指定参数,然而,如果使用这个技术,必须先指定好所有按照位置的实参,再指定命名的参数:例如:OptMethod(99,third:”world”);//第一个实参按位置来定使用可选参数和命名参数假定OptMethod方法被定义成一个重载方法:
OptMethod(intfirst,doublesecond=0.0,stringthird=“hello”){……}
OptMethod(intfirst,doublesecond=0.0,stringthird=“hello”,intfourth=100){……}以下语句调用OptMethod方法:
OptMethod(1,2.5,”world”);以上调用语句合法,但是该调用OptMethod方法的哪一个版本?答案是和方法调用最匹配的那个版本。使用可选参数和命名参数看以下调用:
OptMethod(1,fourth:101);但是下面这个调用就比较纠结了:
OptMethod(1,2.5);编译器认为这是一个存在歧义的调用,所以不允许编译。在看这些调用:OptMethod(1);OptMethod(1,third:”world”);OptMethod(second:2.5,first:1);使用可选参数和命名参数可选参数与参数数组:获取参数数组的方法和获取可选参数的方法似乎存在一定程序的重叠。对于获取可选参数的方法来说,它仍然有一个固定的参数列表,不能传递一组任意的实参。使用参数数组的方法相当于有一个完全任意的参数列表,没有任何参数具有默认值。此外,方法可以准确判断调用者提供了多少个实参。多态之重载继承:是软件实现复用与共享的重要方式,当子类继承父类后,子类将获得父类的属性和方法,并可以在父类的基础上扩展自己的功能。继承是面向对象的三大特征之一,是一种在已有类的基础上创建新类的机制,是实现代码共享和复用的重要手段。类的继承通过“:”关键字来实现,语法如下:classDerivedClass:BaseClass{//类体}注意被继承的类称为超类(superclass)、基类(baseclass)或父类(parentclass)实现继承的类称为子类(subclasschildclass)或派生类(derivedclass)DerivedClass(派生类)将从BaseClass(基类)继承,基类中的方法会成为派生类的一部分在C#中一个类最多只允许从一个其他的类继承,不允许直接从多个类继承Object类是所有类的基类,也就是说所有类隐式的派生于Object类继承何时使用继承:有现成类已具备某些特征和行为,继承之。发现类之间有分类、父子关系(hasa),使用继承增加代码灵活性和可扩展性。例如:动物和狗、鸟的关系,狗、鸟是动物的一种,有动物的特征,动物是狗、鸟的父类,狗、鸟是动物的子类。注意:父类和子类之间的关系是一般和特殊的关系子类不仅可以从父类中继承字段和方法,而且可以对这些字段和方法重定义及扩充新的内容通常创建具有公有属性和方法的父类,再创建具有特殊属性和方法的子类。继承继承的优点代码的复用,减少代码冗余。父类的属性和方法可用于子类,因而可以扩大现有类的功能易于修改和维护。代码驻留在超类里,对超类的任何变化将自动改变子类的行为。这是因为子类会自动继承新行为。继承继承之Protected:继承是将不同的类联系到一起重要方式,在派生类及其基类之间,明显存在着一种特别而紧密的关系。继承中经常需要允许一个基类的派生类访问基类的部分成员。与此同时,禁止不属于这个继承层次结构的类访问这些成员。在这种情况下,就可以使用protected关键字来标记成员。假定类A派生于类B,就能访问B类的protected成员。也就是说,在派生类A中,B类的protected成员实际就是public的如果类A不是从类B派生的,就不能访问类B的protected成员。也就是说,在A中,B的protected成员实际是private的。注意:C#允许将方法和字段声明为protected,建议使用private。public破坏了封装性,protected虽然为类的用户维持了封装性,然而protected字段在派生类中实际就是public字段,所以这个封装性仍然可能被派生类破坏。继承继承之构造函数调用由于子类继承了父类的成员,所以在建立子类对象时,必须先调用父类的构造函数来初始化子类对象中的父类成员隐式的,实例化子类对象时会默认的调用父类默认的(无参)构造函数初始化父类对象。如果父类构造函数被重载,且该父类没有提供默认的(无参)构造函数时,子类就必须显式的调用父类的构造函数来初始化父类成员显式调用父类构造函数使用base关键字继承继承之构造函数调用举例继承classAnimal
{privatestringname;privateintage;privateintno;publicAnimal()
{Console.WriteLine("父类构造器");
}
}classDog:Animal
{publicDog()
:base()//显式的调用父类无参的构造函数,可以省略
{Console.WriteLine("子类构造器");
}
}classAnimal{privatestringname;privateintage;privateintno;publicAnimal(stringname){Console.WriteLine("父类构造器");}}classDog:Animal{publicDog(stringname):base(name)//父类构造函数被重载,且没有提供默认无参的构造函数{ //所以必须显式的调用父类的构造函数,并带参数Console.WriteLine("子类构造器");}}子类与父类构造函数、析构函数的执行顺序:继承classAnimal{publicAnimal(){Console.WriteLine("父类构造器");}~Animal(){Console.WriteLine("父类析构器");}}classDog:Animal{publicDog(){Console.WriteLine("子类构造器");}~Dog(){Console.WriteLine("子类析构器");}}继承之对象的赋值:在继承中一个类的对象可以赋给继承层次结构中较高位置的一个类的变量。例如有ClassStudent:Person{//类体},Class
Teacher:Person{//类体}则:Studentstu=newStudent();
Personp=stu;//合法,因为所有的学生都是人类。注意:p的数据类型是Person而不是Student
Personp=newPerson();Studentstu=p;//非法,并不是所有人类对象都是学生Studentstu=newStudent();Teachertec=stu;//非法,类型不同继承classPerson{publicvoidAction(){Console.WriteLine("动作");}}classStudent:Person{publicvoidStudy(){Console.WriteLine("学习");}
}staticvoidMain(string[]args){Studentstu=newStudent();Personp=stu;p.Action();p.Study();//非法,Study不属于Person类
}继承之禁止继承:用sealed声明的类称为密封类,表示该类不能被继承在编写类时,如果想设置该类不被继承,用sealed(密封)关键字声明该类继承
sealedclassPerson{
}classStudent:Person
//错误,密封类不能被继承{
}继承之隐藏与重写:多态的另外一种表现形式,用来修改基类的数据和方法。多态:多种形态。是指同一类型的对象在运行时可能表现出不同的行为特征。实现多态的几种方式通过方法重载实现通过继承实现通过抽象类实现通过接口实现继承继承之隐藏:在子类中通过new修饰符来隐藏基类中同名的方法或数据子类和父类声明了两个具有相同签名的方法,那么在编译应用程序时就会显示一条警告信息。(方法签名由方法名、参数数量和参数类型共同决定,方法返回类型不计入签名)在实际调用时,会调用子类的同名的方法。然而这样易于造成代码混乱,应该尽量避免,最好重命名方法,避免冲突。但是,假如确实希望有两个方法有相同的签名,从而隐藏父类的方法,可以使用new关键字消除警告。继承classPerson{publicvoidEat(){Console.WriteLine("father");}}classTeacher:Person{publicnewvoidEat()//父类同名方法被隐藏,通过new关键字消除警告信息
{Console.WriteLine("son");}}staticvoidMain(string[]args){Personp=newPerson();p.Eat();Teachert=newTeacher();t.Eat();Personpp=newTeacher();pp.Eat();}思考:上述代码的输出是什么?继承之重写:将父类方法用virtual关键字声明,表示该方法是一个虚方法,可以被子类重写。而子类则通过override关键字声明签名相同的方法来覆盖父类同名方法。大部分时候,子类总是以父类为基础,额外增加新的属性和方法。但有一种特殊情况,子类需要重写父类的方法。例如鸟类都包含了飞翔的方法,其中鸵鸟是一种特殊的鸟类,因此鸵鸟应该是鸟的子类,因此它将从鸟类获得飞翔的方法,但这个飞翔方法明显不适合鸵鸟,为此鸵鸟需要重写(覆盖)鸟类方法。继承classBird{publicvirtualvoidFly()//虚方法
{Console.WriteLine("我在天空自由的飞翔……");}}classOstrich:Bird{publicoverridevoidFly()//重写父类的方法
{Console.WriteLine("我只能在地上奔跑……");}}staticvoidMain(string[]args){Ostrichos=newOstrich();os.Fly();}思考:上述代码的输出是什么?使用virtual和override关键字实现方法重写时必须遵守的规则:不允许使用virtual或override关键字声明一个private方法。两个方法签名必须完全一致,返回类型也必须相同。两个方法必须具有相同的可访问性。只能重写virtual方法。假如子类不用override关键字声明方法,就不会重写父类方法。此时,编译器会发出警告。一个override方法将隐式的成为virtual方法,本身可以在未来的一个子类中被override,不允许使用virtual关键字,将一个override方法显式的声明为virtual方法。继承重写之base的使用:在子类中重写父类的方法需要调用父类版本时base.方法名。继承
classCustomerAccount{publicvirtualdecimalCalculatePrice(){return0.9M;}}classGoldAccount:CustomerAccount{publicoverridedecimalCalculatePrice(){returnbase.CalculatePrice()*0.9M;//重写后,调用父类版本}}重写之密封:使用sealed关键字声明为密封方法,使之不能被重写注意:不是类的每个成员方法都可以作为密封方法的,密封方法用来密封通过override重写后的方法,也就是说对于方法而言,sealed只能和overide同时出现(不能与virtual同用),表明该方法不能再被重写。也就是说密封方法是方法的最后一个实现。继承
classBird{publicvirtualvoidFly(){Console.WriteLine("我在天空自由的飞翔……");}}classOstrich:Bird{publicsealedoverridevoidFly()//表面如果Ostrich还有子类,则子类不能再重写该方法{Console.WriteLine("我只能在地上奔跑……");}}隐藏与重写的区别隐藏和重写方法都出现在类的继承关系中,方法都具有相同的签名。但重写时,方法的返回类型也必须一致。当用new关键字修饰子类中与父类同名方法,表示消除隐藏父类同名方法时编译器的警告。重写方法的目的是提供一个方法的不同实现,这些方法是相互关联的,因为它们完成相同的任务,只是不同的类会以不同的方式完成。隐藏方法的目的是将一个方法替换成另一个方法,方法通常互不相关,而且可能执行完全不同的任务。继承扩展方法(extentionmethod):允许通过附加的静态方法来扩展现有的类型。继承允许从一个类中派生出另外一个类,从而扩展类的功能。但在希望快速扩展一个类型,又不想影响现有代码的情况下,使用继承不一定是最佳方案,这时可以使用扩展方法。任何语句一旦引用被扩展类型的数据,就能立即开始调用这些静态方法。招展方法只能定义在静态类(使用static修饰的类,其所有成员均为静态的)中,要扩展的类型必须是方法的第一个参数,而且必须加this关键字扩展方法多态(Polymorphism),多种形态。是指同一类型的对象在运行时可能表现出不同的行为特征。静态多态:重载(编译时多态)动态多态:重写(运行时多态)面向对象之多态抽象类与抽象方法:当编写一个类时,常常为会该类定义一些方法,这些方法用以描述该类的行为,那么这些方法都有具体的方法体。但在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确的知道这些子类如何实现这些方法。使用抽象方法即可满足该要求:抽象方法是只有方法签名,没有方法体。抽象方法必须包含在抽象类中,必须使用关键字abstract关键字修饰有抽象方法的类只能被定义成抽象类,但是抽象类里可以没有抽象方法抽象类的用途是提供多个子类可共享的父类的公共方法,并使用abstract关键字定义面向对象之抽象定义抽象类和抽象方法语法 abstract
classShape//定义抽象类 {
//定义抽象方法,抽象方法没有方法体
publicabstractdoubleCalPerimeter(); }面向对象之抽象
classTriangle:Shape{privatedoublea,b,c;publicTriangle(){}publicTriangle(doublea,doubleb,doublec){this.a=a;this.b=b;this.c=c;}publicoverridedoubleCalPerimeter()//通过override修饰方法来实现父类抽象方法
{returna+b+c;}}
classCircle:Shape{privatedoubleradius;publicCircle(){}publicCircle(doubleradius){this.radius=radius;}publicoverridedoubleCalPerimeter()//通过override修饰方法来实现父类抽象方法{return2*Math.PI*radius;}}抽象类和抽象方法语法规则:抽象方法和抽象类必须使用关键字abstract关键字修饰,抽象方法不能有方法体抽象类只能作为其他类的基类,不能被实例化,无法使用new关键字来调用抽象类的构造器创建类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能创建实例含有抽象方法的类,必须被定义成抽象类对抽象方法,不能使用static或virtual修饰符抽象类不能同时是密封类,abstract和sealed永远不能同时用继承一个抽象类,必须在子类里实现父类所有的抽象方法在子类中实现父类抽象方法时,必须与父类方法保持签名、返回类型、访问控制符一致子类使用override关键字修饰方法来实现父类的方法面向对象之抽象抽象类的作用从语义的角度来说,抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类设计的随意性抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式面向对象之抽象接口:从多个相似类中抽象出来的规范,接口不提供任何实现。接口体现的是规范和实现分离的设计。接口是最彻底的抽象接口里不包含普通方法,接口里的所有方法都是抽象方法面向对象之接口接口一般形式说明:修饰符可以省略,默认为internalinterface是定义接口的关键字建议接口名以大写字母I开头,以便区分这是一个接口面向对象之接口[修饰符]interface
接口名{//接口成员(方法、属性、索引器、事件)}
publicinterfaceIBankAccount
//定义一个接口{voidPayIn(decimalamount);
boolWithDraw(decimalamount);decimalBalance{get;}}创建接口时要注意:接口不能使用static、virtual、abstract和sealed定义不允许在接口在定义任何字段不允许在接口中定义任何构造函数和析构函数不允许为任何成员声明访问修饰符,接口中所有成员隐式地为public接口中成员只有声明,没有实现。接口可以通过使用关键字:继承其他接口当一个类实现一个接口时,必须实现接口中的所有成员面向对象之接口接口实现举例实现接口时,方法签名和返回类型必须与接口中定义的完全一致实现一个接口时必须实现接口中的所有方法使用接口名作为方法名的前缀,这称为显式接口实现(建议平时多用显式接口实现)用于实现一个接口的所有方法都必须具有public可访问性。但是,假如使用显式接口实现,则不应该为方法添加访问修饰符一个类最多只有一个直接父类,但可以实现数量无限的接口(用逗号隔开)。类必须实现它从它的所有接口继承来的方法。面向对象之接口接口的继承面向对象之接口抽象类与接口接口和抽象类都不能被实例化,都用于被其他类继承接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法接口体现的是一种规范,对于接口的实现者而言,接口规定了实现者必须向外提供哪些服务(以方法的形式来提供);对于接口调用者而言,接口规定了调用者可以调用哪些服务,以及如何使用这些服务(就是如何调用方法)从某种程度上来说,接口类似于整个系统的“总纲“,它制定了系统各模块应该遵循的标准,因此一个系统中的接口不应经常改变抽象类则不一样,抽象类作为系统中多个子类的共同父类,它所体现的是一种模板设计。抽象类作为多个子类的抽象父类,可以被当成系统实现过程中的中间产品,这个中间产品已经实现了系统的部分功能(哪些已经提供实现的方法),但这个产品依然不能当成最终产品,必须有进一步的完善,这种完善可能有多种不同方式面向对象之接口值类型和引用类型的基本区别在于其在内存中的存储方式值类型的数据存储在内存中的栈区,可以快速访问引用类型指向存储在内存堆区中的数据的引用。简单的说值类型是现金,引用类型是存折操作系统运行时,通常将用于容纳数据的内存划分为两个独立的区域,每个区域都采用不同的方式管理。这两个区域通常称为栈(stack)和堆(heap)。栈的是由操作系统来管理的,而堆是由程序员自己分配的,所以引用类型初始化时需要使用new关键字分配内存面向对象之值类型与引用类型装箱:将数据从栈中自动复制到堆的行为称为装箱(boxing)例如:publicvoidTest(){inti=42;objectobj=i;}说明:i是一个值类型,它存在于栈区,假如obj直接引用i,那么引用的将是栈。然后所有引用都必须引用堆区上的对象,引用类型引用栈区的数据是不允许的,所以先在堆中分配一小片内存,然后i中的值的一个副本被复制在这片内存中,然后让obj引用这个副本。面向对象之值类型与引用类型拆箱:为了访问已装箱的值,必须进行一次强制类型转换,这个过程称为拆箱例如:inti=42;objectobj=i;//装箱i=(int)obj;//拆箱:说明:编译器发现指定了类型int,所以会在运行时生成代码来检查obj实际引用的是什么。假如obj真的引用一个已装箱的int,而且一切条件都满足,强制类型转换就会成功执行,编译器生成面向对象之值类型与引用类型值类型与引用类型的区别面向对象之值类型与引用类型比较类型值类型引用类型内存存储方式栈中堆中效率效率高,不需要地址转换效率低,需要地址转换回收方式使用完立即回收使用完不立即回收,等待垃圾回收器回收赋值方式复制,创建一个复制的新对象只是引用原对象默认值0nullis与as操作符:一种安全的进行强制数据类型转换的机制is操作符:检查对象是否与特定的类型兼容,可以用它来判断对象是否为给定的类型定义格式为:运算对象
is类型其运算结果为bool类型as操作符:用于在兼容的引用类型之间执行转换,把一种类型转换为指定的引用类型。与强制类型转换不同的是,as不会引发错误基本格式:运算对象as
类型如果转换成功,就返回成功的结果,如果转换失败,as表达式的求值结果就是null面向对象之is与as操作符
classPerson{}classStudent:Person{}staticvoidMain(string[]args){Studentstu=newStudent();if(stuisPerson)//判断stu对象是否是Person类型{Console.WriteLine("YES");}else{Console.WriteLine("NO");}}staticvoidMain(string[]args){objectobj=null;stringstr=objasstring;
//将一个对象转换成一种类型if(str!=null){Console.WriteLine(“转换成功”+obj);}else{Console.WriteLine("obj不可转换为字符串");}}结构:值类型,在栈上存储,能够有效地减少内存管理的开销(当期前提是这个结构足够小)类定义的是一个引用类型,它总是在堆上创建的,某些时候,类中只包含极少的数据,因为管理堆而造成开销显得极不合算。在这种情况下,更好的做法是将类型定义成一个结构结构可以包含字段、方法和构造器,这和类完全相同一般形式面向对象之结构struct结构名{//结构成员}structTime{privateinthours,minutes,seconds;publicintSeconds{get{returnseconds;}set{seconds=value;}}publicintMinutes{get{returnminutes;}set{minutes=value;}}publicintHours{get{returnhours;}set{hours=value;}}publicTime(inthours,intminutes,intseconds){this.hours=hours;this.minutes=minutes;this.seconds=seconds;}}staticvoidMain(string[]args)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 重组抗破伤风毒素单克隆抗体临床应用专家共识总结完整版
- 儿童肺移植中国专家建议重点2026
- 2026年消防和应急救援人员资格考试试卷及答案(共十六套)
- 2025-2026学年人教版五年级数学下册全册知识点总结(完整版)
- 2026年餐饮加盟经营合同模板二篇
- OTC 钙和保健钙的区别
- 儿童青少年自主神经介导性晕厥诊断与治疗指南总结2026
- 《铅、锌工业大气污染物排放标准》(GB 25466-2025)
- (2026年)烧烤店食品安全管理制度规范
- 2026比赛类面试题模板及答案
- 神木能源局从业人员培训考试证及答案解析
- 2025年北京海淀社区工作者招聘考试试题(附含答案)
- IPC7711C7721C-2017(CN)电子组件的返工修改和维修(完整版)
- DB23∕T 3824-2024 挡土墙技术状况评定规范
- DGTJ08-2001-2016 基坑工程施工监测规程
- 江苏常州联盟学校2024~2025学年高一下册期末调研数学试题学生卷
- 数码喷印技术课件
- T/CAPE 11005-2023光伏电站光伏组件清洗技术规范
- 2025年入团面试技巧试题及答案
- 《结直肠癌化疗方案》课件
- 地理会考试卷及答案贵阳
评论
0/150
提交评论