第04章+面向对象的编程(高级语法)_第1页
第04章+面向对象的编程(高级语法)_第2页
第04章+面向对象的编程(高级语法)_第3页
第04章+面向对象的编程(高级语法)_第4页
第04章+面向对象的编程(高级语法)_第5页
已阅读5页,还剩95页未读 继续免费阅读

下载本文档

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

文档简介

第4章面向对象的编程(高级语法)第4章面向对象的编程(高级语法)4.1继承和多态性的概念4.2继承机制4.3多态性与重载4.4抽象类4.5接口4.6包与内部类、匿名类4.1.1继承的概述继承是一种由已有的类创建新类的机制。利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并根据需要增加它自己的新的状态和行为。由继承而得到的类称为子类(派生类),被继承的类称为父类(基类)。Java不支持多重继承(子类只能有一个父类)。4.1.1继承的概述继承是从一个类派生出一个新类的过程。通过继承,可以让一个类拥有(继承)另一个类的全部成员。动物食草动物食肉动物谁是父类?谁是子类?能说出继承的特点吗?继承需要符合的关系:is-a,父类更通用、子类更具体生活中的继承

子类具有父类的一般特性(包括属性和行为),以及自身特殊的特性巴士是汽车吗?卡车是汽车吗?出租车是汽车吗?最大载客数量报站引擎数量外观颜色刹车加速汽车最大载重量卸货所属公司最大载客数量打发票属性行为请问:出租车包含哪些属性和行为呢?什么是多态简单来说,多态是具有表现多种形态的能力的特征同一个实现接口,使用不同的实例而执行不同操作彩色打印机

打印机黑白打印机打印效果:彩色打印效果:黑白打印打印生活中的多态Cut….!!!听到这个声音他们会做什么?剪断头发切开皮肤停止表演不同对象对于同一个方法(Cut)调用的不同行为。理发师外科医生演员4.1.2多态性的概述多态性是指对象可以表示多个类型的能力。

JAVA中多态性主要体现在:指同一操作作用于不同的类的实例,不同的类实例将进行不同的解释,最后产生不同的执行结果。在Java语言中,多态性体现在两个方面:方法重载实现的静态多态性(编译时多态)方法重写实现的动态多态性(也称动态联编)。4.2继承机制模拟了现实世界的关系实现代码重用结构更清晰Student爱好…person姓名年龄…子类更加关注与子类相关的行为和状态共有属性由父类负责开发教师类,其中教师分为Java教师以及.NET教师,各自的要求如下:Java教师属性:姓名、所属部门方法:授课(步骤:打开MyEclipse、实施理论课授课)、自我介绍.NET教师属性:姓名、所属部门方法:授课(步骤:打开Visualstudio2010、实施理论课授课)、自我介绍4.2继承机制请问:以下这个解决方案中存在着什么问题?publicclassDotNetTeacher{privateStringname;//教师姓名privateStringschool;//所在学校publicDotNetTeacher(StringmyName,StringmySchool){name=myName;school=mySchool;}publicvoidgiveLesson(){System.out.println("启动VS2010");System.out.println("知识点讲解");System.out.println("总结提问");}publicvoidintroduction(){ System.out.println("大家好!我是" +school+"的"+name+".");}}publicclassJavaTeacher{privateStringname;//教师姓名privateStringschool;//所在学校publicJavaTeacher(StringmyName,StringmySchool){name=myName;school=mySchool;}publicvoidgiveLesson(){System.out.println("启动

MyEclipse");System.out.println("知识点讲解");System.out.println("总结提问");}publicvoidintroduction(){ System.out.println("大家好!我是" +school+"的"+name+".");}}代码存在重复,违背了“writeonce,onlyonce”的原则4.2继承机制如何改进?有没有可能建立继承关系,让子类自动继承父类的属性和方法?Java教师是教师吗?.NET教师是教师吗?publicclassTeacher{privateStringname;//教师姓名privateStringschool;//所在学校publicTeacher(StringmyName,StringmySchool){name=myName;school=mySchool;}publicvoidgiveLesson(){System.out.println("知识点讲解");System.out.println("总结提问");}publicvoidintroduction(){ System.out.println("大家好!我是“

+school+"的"+name+"。");}}现在,所有子类中相同的代码都抽取到父类中了属

性行

为姓名所在学校授课自我介绍教师Java教师.NET教师4.2继承机制publicclassJavaTeacher2extendsTeacher{publicJavaTeacher2(StringmyName,StringmySchool){super(myName,mySchool);}publicvoidgiveLesson(){System.out.println("启动MyEclipse");super.giveLesson();}}publicclassDotNetTeacher2extendsTeacher{publicDotNetTeacher2(StringmyName,StringmySchool){super(myName,mySchool);}publicvoidgiveLesson(){System.out.println("启动VS2010");super.giveLesson();}}使用继承,可以有效实现代码复用子类自动继承父类的属性和方法,子类中不再存在重复代码4.2继承机制一切类的“祖先”——Object在Java中,所有的Java类都直接或间接地继承了java.lang.Object类publicclassMyObject{//…}publicclassMyObectextendsObject{

//…}在Eclipse中调用MyObject对象的成员,会自动弹出继承自Object的所有方法4.2.1继承的定义在Java语言中,用extends关键字来表示一个类继承了另一个类,例如:publicclassDeriveClassextendsBaseClass{//其它代码}基类的公共成员被派生类继承后在派生类中可以直接访问,也可以在程序的任何地方通过派生类的对象或派生类名访问;基类的私有成员不能在派生类中访问,也不能通过派生类的对象或派生类名访问;基类的保护成员只能在基类和派生类中访问。在父类中只定义一些通用的属性与方法,例如:publicclassTeacher{privateStringname;//教师姓名privateStringschool;//所在学校publicTeacher(StringmyName,StringmySchool){//初始化属性值}publicvoidgiveLesson(){//授课方法的具体实现}publicvoidintroduction(){//自我介绍方法的具体实现

}}4.2.1继承的定义子类自动继承父类的属性和方法,子类中可以定义特定的属性和方法publicclassTeacher{privateStringname;//教师姓名privateStringschool;//所在学校publicTeacher(StringmyName,StringmySchool){//初始化属性值}publicvoidgiveLesson(){ //授课方法的具体实现}publicvoidintroduction(){ //自我介绍方法的具体实现

}}publicclassJavaTeacher2extendsTeacher{publicJavaTeacher2(StringmyName,StringmySchool){super(myName,mySchool);}publicvoidgiveLesson(){System.out.println("启动Eclipse");super.giveLesson();}}由于giveLesson()方法与父类的实现有所不同,因此重写了该方法方法重写:子类和父类的方法具有相同的名称、参数列表、返回类型父类中的属性和方法可以被子类继承4.2.1继承的定义继承的传递性汽车双层单层小型卡车重型卡车同样具有汽车的特征继承的传递性卡车公共汽车还可以派生更多的类型继承的传递性publicclassVehicle{voidvehicleRun(){

System.out.println("汽车在行驶!");}}publicclassTruckextendsVehicle{

voidtruckRun(){

System.out.println("卡车在行驶!");}}继承的传递性添加一个小型卡车类publicclassSmallTruckextendsTruck{protectedvoidsmallTruckRun(){

System.out.println("微型卡车在行驶!");}

publicstaticvoidmain(String[]args){SmallTrucksmalltruck=newSmallTruck();smalltruck.vehicleRun();smalltruck.truckRun();

smalltruck.smallTruckRun();}}继承关系父类的父类成员父类的成员传递性1.属性的继承子类可以继承父类的所有属性,但是父类的私有属性对子类是不可见的。publicclassPerson{publicStringname;publicintage;publicvoidshowInfo(){ System.out.println(“尊敬的”+name+”,您的年龄为:”+age);} }基类4.2.2类中属性的继承与隐藏publicclassStudentextendsPerson{publicstringschool;publicintengScore;publicintjavaScore;publicvoidsetInfo(){ name=“陈一”; age=20;school=“西亚斯学院”;}}派生类属性的继承访问基类成员子类也可以隐藏继承的成员变量,对于子类可以从父类继承的成员变量,只要子类中定义的成员变量和父类中的成员变量同名时,子类就隐藏了继承的成员变量.子类通过成员变量的隐藏可以把父类的状态变为自身的状态。属性的隐藏父类中非私有方法都可以被子类所继承。在子类继承父类的成员方法时,应注意:子类不能访问父类的private(私有)成员方法,但子类可以访问父类的public(公有)、protected(保护)成员方法。protected访问时,子类和同一包内的方法都能访问父类的protected成员方法,但其他方法不能访问。4.2.3类中方法的继承、覆盖与重载publicclassStudentextendsPerson{privateStringschool;privateintengScore;privateintjavaScore;

publicvoidsetScores(Strings,inte,intj){ school=s; engScore=e; javaScore=j;}}派生类publicclassPerson{privateStringname;privateintage;publicvoidinitInfo(Stringn,inta){name=n;age=a;}publicvoidshowInfo(){ System.out.println(“尊敬的”+name+”,您的年龄为:”+age);}}基类publicstaticvoidmain(String[]args){StudentobjStudent=newStudent();objStudent.initInfo(“王烁”,22); objStudent.showInfo(); objStudent.setScores(“清华大学”,79,92);}调用的基类成员无需实现initInfo()和showInfo()方法方法的继承方法的覆盖(重写)子类通过方法的覆盖可以隐藏继承的方法,方法覆盖是指:子类中定义一个方法,并且这个方法的名字、返回类型、参数列表与从父类继承的方法完全相同。注意:1.子类的方法不能缩小父类方法的访问权限2.子类的方法不能抛出比父类方法更多的异常3.父类的静态方法不能被子类覆盖为非静态方法4.父类的私有方法不能被子类覆盖方法的覆盖publicclassStudentextendsPerson{privateStringschool;privateintengScore;privateintjavaScore;publicvoidsetScores(Strings,inte,intj){ school=s; engScore=e; javaScore=j;}publicvoidshowInfo(){super.showInfo();System.out.println(",英语成绩是:"+engScore+",JAVA成绩是:"+javaScore); //System.out.println(school+“的同学+name+“年龄为:”+age+“英语成绩是:”+engScore+”,你的JAVA成绩是:”+javaScore);//此行代码错的原因}}覆盖了基类的showInfo()方法方法重载类方法方法参数方法实现司机轿车巴士火车驾驶启动、行驶、……等待乘客上车、启动、行驶、到站停车、……正点发车、行驶、到站停车、……如果用代码实现,我们需要三个方法,这些方法的方法名称相同,参数类型不同方法重载publicintSum(intpara1,intpara2){returnpara1+para2;}整形参数,返回值整型如果想让两个String型、两个double型相加,怎么做?编写两个不同名字的方法,这样我们在进行调用时要先判断是什么类型,能否不判断直接就能相加呢?方法重载对于类的方法,如果有两个方法的方法名相同,但参数列表不一致,那么可以说,一个方法是另一个方法的重载方法重载方法必须满足以下条件:方法名相同。方法的参数类型,个数,顺序至少有一个不同。方法的返回类型可以不相同(与方法的返回类型无关)。方法的修饰符可以不相同(与修饰符无关)。方法重载同一个类中添加几个名字相同,参数与返回值不同的方法publicString

Sum(String

para1,String

para2){returnpara1+para2;}publicdoubleSum(doublepara1,doublepara2){returnpara1+para2;}调用时只要传递参数即可,无需判断类型方法重载classAdd{

publicString

Sum(String

para1,String

para2){…}

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

publicintSum(intpara1,intpara2){…}

publicintSum(intpara1,intpara2,intpara3){…}}相同类型不同参数个数的重载不允许重载方法仅仅是返回值不同方法重载并不陌生System.out类的println方法能够打印数据并换行,根据数据类型的不同,有多种实现方式publicclassTest{publicstaticvoidmain(String[]args){inti=0;charc='z';Stringstr="hello";System.out.println(i);System.out.println(c);System.out.println(str);}}PrintStreamprintln(int)println(char)println(String)……方法名相同,参数类型不同调用不同的println方法方法重载方法重载构造函数的重载当实例化对象的时候,在不同的条件下,对象可能会有不同的初始化行为。对一个学生对象来说,初始的时候,有可能不知道姓名,有可能不知道年龄,有可能什么都不知道。我们可以通过对构造函数重载,来实现多种初始化的行为。构造函数的重载publicStudent(){}publicStudent(Stringname,intage,Stringschool){

=name;

this.age=age;this.hobby=hobby;}构造函数也可以重载Studentscofield=newStudent();Studentzhang=

newStudent(“张靓靓”,20,“西亚斯学院");方法名相同,参数不同请编码实现动物世界的继承关系:动物(Animal)具有行为:吃(eat)、睡觉(sleep)动物包括:兔子(Rabbit),老虎(Tiger)这些动物吃的行为各不相同(兔子吃草,老虎吃肉);但睡觉的行为是一致的。请通过继承实现以上需求,并编写测试类AnimalTest进行测试。

4.2.4在子类中使用构造函数子类不能继承父类的构造函数。

子类在创建新对象时,依次向上寻找其基类,直到找到最初的基类,然后开始执行最初的基类的构造函数,再依次向下执行派生类的构造函数,直至执行完最终的扩充类的构造函数为止。注意:对于无参数的构造函数,执行不会出现问题。如果是带参数的构造函数,还需要做相应的处理。如果基类中没有默认构造函数或者希望调用带参数的基类构造函数,就要使用关键字super来显式调用基类构造函数。使用关键字super调用基类构造函数的语句,必须是子类构造函数的第一个可执行语句。调用基类构造函数时传递的参数不能是关键字this或当前对象的非静态成员。4.2.4在子类中使用构造函数默认构造函数默认构造函数指的是没有参数的构造函数。可为分两种情况。(1)隐含的默认构造函数类中若未定义构造函数,则JAVA系统自动提供一个缺省的构造函数。缺省的构造函数无参,函数体为空,仅创建对象,不作任何初始化工作。publicPerson(){}(2)程序显示定义的默认构造函数publicPerson(){ name=“无名氏”;}只要类中定义了一个构造函数,编译器就不再提供缺省的构造函数隐式调用父类的构造函数Person类中去掉了构造函数publicPerson(){}“Person”方法没有采用“0”个参数的重载classStudentextendsPerson{publicStudent(){

}

publicStudent(stringname,intage,stringschool)}super()隐式的调用super()子类的构造函数没有使用super指明调用父类哪个构造函数父类要提供无参的构造函数显示调用父类的构造函数如果父类没有无参的构造函数子类构造函数必须指明调用父类哪个构造函数publicStudent(){

super("张靓靓",20)}publicStudent(stringname,intage,stringschool){ super(name,age)}4.2.5父类对象与子类对象间的使用和转化this和super关键字常用来指代子类对象与父类对象的关键字。this关键字this是Java的一个关键字,表示当前对象。this可以出现在实例方法和构造方法中,但不可以出现在static方法中。this关键字出现在类的构造方法中时,代表使用该构造方法所创建的对象。this关键字出现在类的实例方法中时,代表正在调用该方法的当前对象。this关键字classDemothis{inta;//成员变量intb;

publicDemo(inta){ this.a=a;}PublicDemo(inta,intb){this(a);this.b=b;}在成员方法定义时,我们使用的形式参数与成员变量名称相同,这时我们要用到this在某一构造方法中调用另一构造方法时,必须使用this来调用,this关键字必须写在构造方法内第一行位置super关键字在子类中通过super来实现对父类成员的访问。我们知道,this用来引用当前对象,与this类似,super用来引用当前对象的父类。(1)访问父类被隐藏的成员变量,如:

super.variable;(2)调用父类中被覆盖的方法,如:

super.Method([paramlist]);(3)调用父类的构造函数,如:

super([paramlist]);super关键字classChildextendsFather{intx=1;Child(){System.out.println(super.x);}publicstaticvoidmain(Stringargs[]){newChild();//其实是super.x=0}}classFather{intx=0;}通过super关键字访问父类中被隐藏的成员变量publicclassStudentextendsPerson{publicStudent(StringmyName,intmyAge){super(myName,myAge);}}子类的构造方法中,通过super关键字调用父类的构造方法方法重写后,通过super关键字调用父类的方法publicclassStudentextendsPerson{publicvoidshowInfo(){super.showInfo();

System.out.println(",你的英语成绩是:"+engScore+",JAVA成绩是:"+javaScore");}}通过调用父类的构造方法,完成对属性值的初始化super关键字4.3多态性在java语言中,多态性体现在两个方面:静态多态性是在编译的过程中确定同名操作的具体操作对象的。(体现在方法的重载)动态多态性则是在程序运行过程中动态地确定操作所针对的具体对象的。这种确定操作具体对象的过程就是联编,也称为动态绑定。(体现在方法的重写)4.3.1方法的动态调用当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。那么当我们把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个上转型对象在通过上转型对象在调用这个方法时,程序会动态地(在执行时)选择正确的子类的方法去实现该功能,就称为动态方法绑定。就可能具有多种形态。对象的上转型对象假设B类是A类子类或间接子类,当我们用子类B创建一个对象,并把这个对象的引用放到A类的对象中时:

Aa;Bb=newB();a=b;称这个A类对象:a,是子类对象b的上转型对象.对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原子类对象的一些属性和功能。上转对象不能操作子类新增的成员变量;不能使用子类新增的方法。上转型对象可以操作子类继承或隐藏成员变量,也可以使用子类继承的或重写的方法。上转型对象操作子类继承或重写的方法时,就是通知对应的子类对象去调用这些方法。因此,如果子类重写了父类的某个方法后,对象的上转型对象调用这个方法时,一定是调用了这个重写的方法。可以将对象的上转型对象再强制转换到一个子类对象,该子类对象又具备了子类所有属性和功能。对象的上转型对象

classMammal{//哺乳动物类

privateintn=40;voidcrySpeak(Strings){System.out.println(s);}}publicclassMonkeyextendsMammal{//猴子类

voidcomputer(intaa,intbb){intcc=aa*bb;System.out.println(cc);}voidcrySpeak(Strings){System.out.println("**"+s+"**");}}上转型对象的使用publicstaticvoidmain(Stringargs[]){

//mammal是Monkey类的对象的上转型对象.Mammalmammal=newMonkey();mammal.crySpeak("Ilovethisgame");//puter(10,10);//把上转型对象强制转化为子类的对象.Monkeymonkey=(Monkey)mammal;puter(10,10);}

如果子类重写了父类的方法,那么重写方法的调用原则如下:Java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。实例:TestPloymoph/Test.java4.3.2方法的动态调用classBase{publicStringname;publicBase(){name="Base";}publicBase(StringpName){name=pName;}publicvoidmethod(){System.out.println(name);}}classChildextendsBase{publicChild(){super("Child1");name="Child2";}}给定如下Java代码,编译运行后,输出结果是什么?publicclassSample{publicstaticvoidmain(String[]args){

Childc=newChild();c.method();

}}Child2控制台输出123给定如下Java代码,编译运行后,输出结果是什么?publicclassTeacher{publicvoidgiveLesson(){System.out.println("知识点讲解");}}

publicclassDBTeacherextendsTeacher{publicvoidgiveLesson(){System.out.println("启动SqlServer");}}12publicclassTest{publicstaticvoidmain(String[]args){Teachert=newDBTeacher();t.giveLesson();}}控制台输出启动SqlServer4.4抽象类

Java语言中,用abstract关键字来修饰一个类时,这个类叫做抽象类。抽象类只关心它的子类是否具有某种功能,并不关心该功能的具体实现,功能的具体行为由子类负责实现的。当一个类的定义完全表示抽象的概念时,它不应该被实例化为一个对象。例如Java中的Number类就是一个抽象类,它只表示数字这一抽象概念,只有当它作为整数类Integer或实数类Float等的父类时才有意义。4.4.1抽象类的定义abstractclassClassOne{ //类实现}不能实例化只能用作派生类的基类用关键字abstract修饰的类称为抽象类。由于抽象类不能被实例化,因此下面的语句会产生编译错误:

ClassOnea=newClassOne();4.4.2抽象方法抽象方法只有方法头,没有具体的方法体。publicabstractvoidMethod();

抽象方法的一个主要目的就是为所有子类定义一个统一的接口,至于方法体的具体实现,那是由当前类的不同子类在它们各自的类定义中完成的。与final类和方法相反,抽象类必须被继承,抽象方法必须被重写。含有抽象方法的类必须是抽象类,不过,一个抽象类并不一定仅拥有抽象方法。4.4.2抽象方法abstractclasscfath{intx;public

abstractvoidf();//抽象方法

publiccfath(){ x=1;System.out.println(x);}}abstractclassBase{//成员变量intbasevar;//成员函数publicabstract

voidM1();

//无法实现

…….}classDerivedextendsBase{

//成员变量intderivedvars;

//成员函数publicvoidM1(){

//实际实现}抽象类派生类4.4.2抽象方法必须重写

4.4.2抽象方法继承于抽象类的类一般应该实现抽象类中的所有抽象方法(重写)。如果没有,那么该派生类也应该声明为抽象类。 abstractclassA{ publicabstractvoidMethodA(); } classBextendsA{ //错误

publicvoidMethodB(){} } classCextendsA{ publicvoidMethodA(){} }抽象类实例:abstract/Test_abstract.java电脑主板上的PCI插槽的规范就类似于Java接口声卡显卡网卡每种卡的内部结构都不相同,可以把声卡、网卡、显卡都插在PCI插槽上,而不用担心哪个插槽是专门插哪个卡的主板生活中的接口:4.5JAVA语言中的接口生活中的接口OFFON请按开关按钮:ON/OFF两种方法ONOFF生活中的接口ISwitchON()OFF()4.5.1JAVA语言中的接口接口的主要特点是只有声明部分,没有实现部分。接口成员的实现是通过类完成的。定义在接口中的方法都是public的。需要在不相关的类中实现同样的功能时,可以使用接口。接口的声明publicinterfaceIBase{finalStringstr=常量;

voidmethod1();intmethod2(float);…….}只有声明没有实现无访问修饰符接口本身并不提供它所定义成员的具体实现,它只是指定了实现该接口的类或结构必须实现的成员。接口的声明接口体中包含常量和方法定义两部分。常量定义部分定义的常量均具有public、static和final属性。接口中只能进行方法的声明,不提供方法的实现,在接口中声明的方法具有public和abstract属性。publicinterfacePCI{finalintvoltage=10;

publicvoidstart();

publicvoidstop();

}这是Java接口,相当于主板上的PCI插槽的规范voltage具有publicstaticfinal修饰符接口的实现接口可以由类来实现,类通过关键字implements声明自己使用一个或多个接口。所谓实现接口,就是实现接口中声明的方法。class类名extends[基类]implements接口,…,接口{ ……//成员定义部分}

接口中的方法被默认是public,所以类在实现接口方法时,一定要用public来修饰。如果某个接口方法没有被实现,实现类中必须将它声明为抽象的,该类当然也必须声明为抽象的。interfaceIMsg{ voidMessage();}publicabstractclassMyClassimplementsIMsg{

publicabstractvoidMessage();}接口的实现classSoundCardimplementsPCI{publicvoidstart()

{

System.out.println("Dudu...");

}

publicvoidstop()

{

System.out.println("Soundstop!");

}

}Java接口中定义的方法在不同的地方被实现,可以具有完全不同的行为classNetworkCardimplementsPCI{publicvoidstart()

{

System.out.println("Send...");

}

publicvoidstop()

{

System.out.println("Networkstop!");

}

}声卡、网卡都实现了PCI插槽的规范,但行为完全不同接口的实现接口回调接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法.接口的实现publicclassAssembler{

publicstaticvoidmain(String[]args){

PCInc=newNetworkCard();

PCIsc=newSoundCard();

nc.start();sc.start();

}

}可以使用Java接口标识类型,运行时,根据实际创建的对象类型调用相应的方法实现Send...Dudu...控制台输出21接口的实现为学校各院系开发这样一个小系统,包含类型:教师、系部、打印机,具体要求如下:教师、以及系部都具有方法:输出详细信息系部具有属性:打印机,能够通过系部的打印机打印教师或系部的详细信息系统要具备良好的可扩展性与可维护性打印教师系部教师详细信息系部详细信息detail方法(输出详细信息)以下这个解决方案中存在着什么问题?publicclassTeacher1{//输出教员的详细信息publicStringdetail(){ return“本人是教师";}}publicclassSchool1{privatePrinterprinter=newPrinter();//输出系部的详细信息publicStringdetail(){return“这里是国际教育学院";}//使用打印机打印教师信息publicvoidprint(Teacher1t){printer.print(t.detail());}//使用打印机打印系部信息publicvoidprint(School1s){ printer.print(s.detail());}}publicclassPrinter{publicvoidprint(Stringcontent){System.out.println("开始打印:");System.out.println(content);}}每增加一种新类型,都需要增加相应的print(类型名称var)方法——程序的可扩展性及可维护性极差——这不符合系统的要求接口的实现可以通过多态性解决这个问题吗?显然,本系统符合使用多态性的条件教师系部detail方法(负责输出详细信息)教师

详细信息系部

详细信息1221回顾多态的含义:实现同一个接口,使用不同的实例而执行不同操作接口的实现在这个系统中,存在继承关系吗?教师、系部属于两种不同的类型教师、系部都存在一个共同的方法特征:detail,它们对detail方法有各自不同的实现——这完全符合Java接口的定义定义一个Java接口,在其中定义detail方法,但没有具体实现实现这个Java接口,不同的类对detail方法有不同的具体实现IntroduceableTeacher2(教员)School2(系部)接口的实现publicinterfaceIntroduceable{publicStringdetail();}publicclassSchool2

implementsIntroduceable{privatePrinterprinter=newPrinter();//输出系部的详细信息publicStringdetail(){return“这里是国际教育学院";}//使用系部打印机打印信息publicvoidprint(Introduceableintro){ printer.print(intro.detail());}}publicclassTeacher2

implementsIntroduceable{//输出教师的详细信息publicStringdetail(){ return“本人是教师";}}通过Java接口,我们同样可以享受到多态性的好处,大大提高了程序的可扩展性及可维护性使用print方法时,参数可以是任何实现Introduceable接口的类的对象,不必再为不同的类型建立不同的print方法了使用了Java接口之后,这个系统有了怎样的改进?接口的实现小结为刚才完成的系统增加一种新的类型:学员(Student),具体要求如下:学生具有detail方法,负责输出学员详细信息能够通过系部的打印机打印学员的详细信息系统要具备良好的可扩展性与可维护性编写测试类StudentTest进行测试,要求:通过中心的打印机打印学员的详细信息4.5.2什么是面向接口编程开发系统时,主体构架使用接口,接口构成系统的骨架,这样就可以通过更换接口的实现类来更换系统的实现publicclassSchool2implementsIntroduceable{privatePrinterprinter=newPrinter();publicStringdetail(){return“这里是国际教育学院";}//使用系部打印机打印信息publicvoidprint(Introduceableintro){ printer.print(intro.detail());}}IntroduceableTeacher2(教师)School2(系部)面向接口编程的示例-1升级上述的系统,要求:打印机有多种类型,比如:黑白打印机、彩色打印机等系部可能配备其中任意一款打印机,负责打印教师或者系部的详细信息系统要具备良好的可扩展性与可维护性print方法(打印)彩色打印机黑白打印机黑白内容系部/教师详细信息彩色内容面向接口编程的示例-2采用面向接口编程的方式实现,以下是三个步骤中的第一步:抽象出Java接口1、分析:黑白、彩色打印机都存在一个共同的方法特征:print黑白、彩色打印机对print方法有各自不同的实现2、结论:抽象出Java接口PrinterFace,在其中定义方法print3、具体实现:publicinterfacePrinterFace{publicvoid

print(Stringcontent);}面向接口编程的示例-3采用面向接口编程的方式实现,以下是三个步骤中的第二步:publicclassColorPrinter

implementsPrinterFace{publicvoid

print(Stringcontent){System.out.println("彩色打印:");System.out.println(content);}}publicclassBlackPrinter

implementsPrinterFace{publicvoid

print(Stringcontent){System.out.println("黑白打印:");System.out.println(content);}}实现Java接口1、分析:已经抽象出Java接口PrinterFace,并在其中定义了print方法黑白、彩色打印机对print方法有各自不同的实现2、结论:黑白、彩色打印机都实现PrinterFace接口,各自实现print方法3、具体实现:面向接口编程的示例-4采用面向接口编程的方式实现,以下是三个步骤中的第三步:使用Java接口1、分析:主体构架使用接口,让接口构成系统的骨架2、结论:更换实现接口的类就可以更换系统的实现3、具体实现:publicclassSchool3implementsIntroduceable{privatePrinterFaceprinter;//打印机

publicvoidsetPrinter(PrinterFacep){this.printer=p;}publicStringdetail(){return“这里是国际教育学院";}publicvoidprint(Introduceableintro){

printer.print(intro.detail());}}publicclassTest{publicstaticvoidmain(String[]args){//创建系部实例School3school=newSchool3();//为该系部配备黑白打印机

school.setPrinter(newBlackPrinter());school.print(school);//为该系部配备彩色打印机

school.setPrinter(new

ColorPrinter());school.print(school);}}小结阅读如下Java代码,然后请采用面向接口编程的思想,在空白处填写正确的代码publicinterfacePCI{

void

start();

void

stop();

}classSoundCardimplementsPCI{publicvoidstart()

{

System.out.println("Dudu...");

}

publicvoidstop()

{

System.out.println("Soundstop!");

}

}classNetworkCardimplementsPCI{publicvoidstart()

{

System.out.println("Send...");

}

publicvoidstop()

{

System.out.println("Networkstop!");

}

}这是Java接口,相当于主板上的PCI插槽的规范声卡、网卡都实现了PCI插槽的规范,但行为完全不同小结publicclassMainBoard{

publicvoidusePCICard(______p)

{

p.start();

p.stop();

}

}publicclassAssembler{

publicstaticvoidmain(String[]args)

{

MainBoardmb=newMainBoard();

//在主板上插入网卡

//在主板上插入声卡

}

}提示:通过这个方法,主板上可以插入任意符合PCI插槽规范的卡PCInc=newNetworkCard();mb.usePCICard(nc);

PCIsc=newSoundCard();

mb.usePCICard(sc);PCI提示:可以通过更换实现接口的类来更换系统的实现4.6包和接口生活案例

文档分门别类,易于查找不同内容的文档可以放在不同的袋子中,拥有相同的名字,避免冲突

易于管理为什么需要包4.6.1java中的包树形文件系统使用目录解决文件同名冲突问题如何存放两个同名的类而不冲突?Sort.java

插入排序Sort.java

冒泡排序4.6.1java中的包包包——解决类的同名问题允许类组成较小的单元(类似文件夹),易于找到和使用相应的文件

防止命名冲突更好的保护类、数据和方法A.java包如何创建包packagecs.java.chap4;publicclassSchool{……publicStringtoString(){……}}

包名使用package声明包,以分号结尾如果有包的声明,一定作为Java源代码的第一条语句包命名规范包名由小写字母组成,不能以圆点开头或结尾自己设定的包名之前最好加上唯一的前缀,通常使用组织倒置的网络域名。如:域名

设定的包名部分依不同机构各自内部的规范不同而不同packagemypackage;package

net.javagroup.mypackage;package

net.javagroup.research.powerproject;

部门名项目名package.mypackage;×包与目录的关系创建好的包和Java源文件是如何存储的?创建包cs.java.chap4,即创建了目录结构:..\cs\java\chap4Programcsjavachap4School.classHello.classSchool.java如何导入包为了使用不在同一包中的类,需

温馨提示

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

评论

0/150

提交评论