面向对象程序设计第4章.ppt

上传人:max****ui 文档编号:3286662 上传时间:2019-12-11 格式:PPT 页数:61 大小:208KB
返回 下载 相关 举报
面向对象程序设计第4章.ppt_第1页
第1页 / 共61页
面向对象程序设计第4章.ppt_第2页
第2页 / 共61页
面向对象程序设计第4章.ppt_第3页
第3页 / 共61页
点击查看更多>>
资源描述
1,第4章,继承与多态,2,4.1继承与多态的实现技术,继承是指一个类的定义可以基于另外一个已经存在的类,即子类基于父类,从而实现父类代码的重用。两个类之间的这种继承关系可以用UML图形符号表示:,3,父类与子类相比较,涵盖了更加共性的内容,更加具有一般性,而子类所添加的内容更加具有个性,是一般性之外的特殊内容,因此,这种类的继承关系充分地反映了类之间的“一般-特殊”关系。类的继承具有传递性,即子类还可以再派生子类,最终形成一个类层次结构。在Java语言中,通过定义子类支持继承性。不仅如此,Java还提供了抽象类和接口,以便使类层次得到更高级别的抽象。,4,多态性是面向对象程序设计的又一个核心概念,它有助于增加软件系统的可扩展性、自然性和可维护性。所谓多态是指不同的类对象收到同一个消息可以产生完全不同的响应效果的现象。利用多态机制,用户可以发送一个通用的消息给各个类对象,而实现细节由接收对象自行决定,这样,同一个消息可能会导致调用不同的方法。,5,类层次结构举例,6,4.2类的继承,4.2.1定义子类子类是通过在定义类时利用关键字extends指出父类实现的,其语法格式为:ModifierclassClassNameextendsSuperClassName/ClassBody,7,在一个公司中,雇员是该公司聘用的工作人员,经理是管理公司的一种特殊雇员,这类雇员不但拥有普通雇员的所有特征外,还可以得到公司发给的特殊津贴,因此这两个类可以用继承关系进行描述,雇员类Employee是父类,经理类Manager是子类。假设Employee类只包含姓名、所在部门和基本工资三个属性及相关的行为方法,Manager类在继承Employee类所有内容的基础上,还需要附加一个描述特殊津贴的属性及相关的行为方法。,举例1:公司雇员,8,9,publicclassEmployee/雇员类privateStringname;/姓名privatedoublesalary;/工资privateStringdepartment;/部门publicEmployee()name=;salary=0.0;department=;publicEmployee(Stringname,doublesalary,Stringdepartment)this.name=newString(name);this.salary=salary;this.department=newString(department);publicvoidsetName(Stringname)this.name=newString(name);publicvoidsetSalary(doublesalary)this.salary=salary;publicvoidsetDepartment(Stringdepartment)this.department=newString(department);publicStringgetName()returnname;publicdoublegetSalary()returnsalary;publicStringgetDeparyment()returndepartment;publicStringtoString()returnname:+name+nsalary:+salary+ndepartment:+department;,10,publicManagerextendsEmployee/经理类privatedoublespecial;/特殊津贴publicManager()super();special=0.0;publicManager(Stringname,doublesalary,Stringdepartment,doublespecial)super(name,salary,department);this.special=special;publicvoidsetSpecial(doublespecial)this.special=special;publicdoublegetSpecial()returnspecial;publicStringtoString()returnsuper.toString()+nspecial:+special;,11,任何一个几何图元都有颜色和原点这两个基本属性。矩形是一种图元,它还有长(length)、宽(width)两个属性,正方形是一种特殊的矩形,它的特殊性在于长和宽相等。,举例2:几何图元处理,12,两个属性:一个是颜色Color类;另一个是原点,使用类库中的Point类。,Shape类,13,publicclassColor/Color类定义privateintred;/红色privateintgreen;/绿色privateintblue;/蓝色publicColor()red=0;green=0;blue=0;/构造方法publicColor(intred,intgreen,intblue)/构造方法if(red255)this.red=0;elsethis.red=red;if(green255)this.green=0;elsethis.green=green;if(blue255)this.blue=0;elsethis.blue=blue;,14,publicvoidsetColor(intred,intgreen,intblue)/设置颜色if(red255)this.red=0;elsethis.red=red;if(green255)this.green=0;elsethis.green=green;if(blue255)this.blue=0;elsethis.blue=blue;publicintgetRed()returnred;/获取红色publicintgetGreen()returngreen;/获取绿色publicintgetBlue()returnblue;/获取蓝色publicStringtoString()/将颜色信息转换成字符串描述形式returnRed:+red+,Green:+green+,Blue:+blue;,15,Shape类的定义,16,publicclassShape/Shape类定义privateColorcolor;/颜色属性privatePointorigin;/原点属性publicShape()/构造方法color=newColor();origin=newPoint();publicShape(Colorc,Pointo)/构造方法color=c;origin=o;publicvoidsetShape(Colorc,Pointo)/设置几何图形的颜色和原点color=c;origin=o;publicColorgetColor()returncolor;/获取颜色publicPointgetOrigin()returnorigin;/获取原点publicStringtoString()/将几何图形的信息转换成字符串描述形式returncolor.toString()+n+origin.toString();,17,Rectangle类的UML类图描述,18,publicclassRectangleextendsShape/Rectangle类定义privateintlength;/长privateintwidth;/宽publicRectangle()/构造方法super();/调用父类的构造方法length=0;width=0;publicRectangle(Colorc,Pointo,intl,intw)/构造方法super(c,o);length=l;width=w;publicintgetLength()returnlength;/获取长度publicintgetWidth()returnwidth;/获取宽度publicvoidsetLW(intl,intw)length=l;width=w;/设置长、宽,19,Square类不需要增加新的成员变量,只重新定义一些适用于正方形的成员方法或更改一些成员方法的接口形式以便更加适用于正方形即可。,Square类,20,publicclassSquareextendsRectangle/Square类定义publicSquare()super();publicSquare(Colorc,Pointo,inte)super(c,o,e,e);publicintgetEdge()returngetLength();/获取边长publicvoidsetEdge(inte)setLW(e,e);/设置边长,21,在Java语言中,子类将继承父类的成员,但子类对象对父类成员的可访问性却由访问属性控制。如果子类与父类在同一个包中,子类可以直接访问父类具有public、proteced和默认访问属性的成员。如果子类和父类不在同一个包中,子类只能够直接访问父类具有public、proteced访问属性的成员,而具有private和默认访问属性的成员需要通过具有public或protected的成员方法实现访问目的。,22,在同一个包中子类访问父类成员的规则,23,在不同包中子类访问父类成员的规则,24,在Java语言中,子类不负责调用父类中带参数的构造方法。若要在创建子类对象时希望对从父类继承的成员变量初始化,就要在子类的构造方法中利用super()调用父类的构造方法,并且必须将它作为子类构造方法中的第一条语句。如果第一条语句不是调用父类构造方法的语句,系统将自动地插入一条调用父类默认构造方法的语句。由于默认的构造方法不带参数,所以,如果父类定义了带参数的构造方法,而没有定义不带参数的构造方法,将会出现编译错误。,4.2.2子类的构造方法,25,publicclassAnimal/动物类privateStringtype;/动物种类publicAnimal(Stringtype)/构造方法this.type=newString(type);publicStringtoString()returnThisisa+type;,26,publicclassDogextendsAnimal/狗类privateStringname;privateStringbreed;publicDog(Stringname)super(Dog);/调用父类的构造方法this.name=name;breed=Unknow;publicDog(Stringname,Stringbreed)super(Dog);/调用父类的构造方法this.name=name;this.breed=breed;,27,在Dog类中,定义了两个构造方法。为了初始化type属性,需要在构造方法中,调用父类的构造方法,由于它们传递的参数都是“Dog”,所以,不管调用哪个构造方法,type都将被初始化为“Dog”。但是,如果在这两个构造方法中,第一条语句不是调用父类的构造方法,将会出现编译错误,这是因为,此时系统会自动地在第一条语句的位置添加调用父类的默认构造方法的语句,但在Animal类中,不存在不带参数的构造方法。,28,Java语言将所有的类都作为Object类的子类。首先,一个Object类型的变量可以用来引用任何类的对象。当在程序中,处理未知类型的对象时这个功能显得尤为重要;其次,可以将成员方法的参数设置为Object类型,以便方法能够接收参数传递进来的任何类型的对象;最后,在Object类中提供了所有对象都应该具有的行为方法,这样可以更好地统一这些成员方法的接口形式。,4.2.3通用父类Object,29,Object类中7个常用的public成员方法,30,4.3类成员的隐藏与重载,在子类继承父类成员的同时,子类自己还可以定义一些新的成员。当子类中定义的新成员变量与父类中某个成员变量的名字相同时,子类会将父类相应的成员变量隐藏起来。当子类中定义的成员方法与父类中某个成员方法的签名完全一样时,子类同样将父类的相应成员方法隐藏起来,这种现象被称为覆盖。倘若只是子类中定义的成员方法与父类中某个成员方法的名字相同,则称为重载。,31,子类将继承父类中除私有访问属性的所有成员变量,除此之外,子类还可以自行定义一些成员变量,这些新的成员变量有些用来扩展父类的描述细节,有些用来将父类中的某个成员变量隐藏起来,使之更加适于描述特定的对象类型。在程序设计中,这种子类隐藏父类成员变量的形式使用的并不多。如果不是必要,建议不要这样设计成员变量,以便降低程序的可读性,增加系统的资源开销。,4.3.1成员变量的继承与隐藏,32,子类将继承父类除私有访问属性的所有成员方法,除此之外,子类还可以自行定义一些成员方法,其中主要包括下列几种形式:在父类中没有的、全新的成员方法。这些成员方法将用来扩展父类的接口形式,增加子类对象的操作功能。子类中定义与父类具有相同签名的成员方法。这些成员方法起到了覆盖父类相应成员方法的作用,因此又称为成员方法的覆盖。子类中定义的某个成员方法只是与父类中的某个成员方法的名字相同,称为成员方法的重载。,4.3.2成员方法的继承、重载与覆盖,33,publicclassComplexNumberprivatedoublere;/实部privatedoubleim;/虚部publicComplexNumber()re=0.0;im=0.0;publicComplexNumber(doublere,doubleim)this.re=re;this.im=im;publicvoidsetRe(doublere)this.re=re;publicvoidsetIm(doubleim)this.im=im;publicdoublegetRe()returnre;publicdoublegetIm()returnim;publicbooleanequals(ObjectotherObject)if(this=otherObject)returntrue;/是否引用同一个对象if(otherObject=null)returnfalse;/otherObject是否为空if(getClass()!=otherObject.getClass()/是否属于同一个类型returnfalse;ComplexNumberother=(ComplexNumber)otherObject;if(re=other.re),34,publicclassTestComplexNumberpublicstaticvoidmain(Stringargs)ComplexNumberc1,c2;c1=newComplexNumber(2,3);c2=newComplexNumber(2,-3.4);if(c1.equals(c2)System.out.println(+c1+)=(+c2+);elseSystem.out.println(+c1+)(+c2+);,35,4.4多态性的实现,多态性是指不同类的对象调用同一个签名的成员方法,却执行不同的代码段的现象。若要实现多态性,需要具备下面两个条件。多态性作用于子类,它是依赖于类层次结构中的一项新功能。在Java语言中,提供了一个指向父类对象的引用可以被用来指向它的任何子类对象的能力,这是实现多态性的先决条件。若得到多态性的操作,相应的成员方法必须同时包含在父类和子类中,且对应的成员方法签名完全一样,子类中该方法的访问属性不能严于父类中该方法的访问属性。如果这个成员方法在父类中不存在,就不能使用父类型对象引用调用它。,36,定义一个父类的引用让该引用指向其子类对象使用该对象调用成员方法,实现多态性需要的基本步骤,37,Animal、Dog、Cat、Duck类关系的UML类图,实现多态性的举例,38,importjava.util.Random;classAnimal/动物类protectedStringtype;/种类protectedStringname;/名称protectedStringbreed;/品种publicAnimal(Stringtype,Stringname,Stringbreed)this.type=newString(type);this.name=newString(name);this.breed=newString(breed);publicStringtoString()returnThisisa+type+nIts+name+the+breed;publicvoidsound(),39,classDogextendsAnimal/Dog类publicDog(Stringname)super(Dog,name,Unknow);publicDog(Stringname,Stringbreed)super(Dog,name,breed);publicvoidsound()System.out.println(WoofWoof);classCatextendsAnimal/Cat类publicCat(Stringname)super(Cat,name,Unknow);publicCat(Stringname,Stringbreed)super(Cat,name,breed);publicvoidsound()System.out.println(Miiaooww);classDuckextendsAnimal/Duck类publicDuck(Stringname)super(Duck,name,Unknow);publicDuck(Stringname,Stringbreed)super(Duck,name,breed);publicvoidsound()System.out.println(Quackquackquack);,40,Animal是一个具有抽象意义的类。这是因为在现实世界中,每个动物都一定属于某个特定的种类,因此,这个类中的sound()成员方法的方法体为空,即本身没有任何特定的操作,只是为了实现多态性而设置。在Dog、Cat和Duck中,覆盖了Animal类中的这个成员方法,它们根据具体动物的特点发出不同的叫声。,41,publicclassTryPolymorphism/测试类publicstaticvoidmain(Stringargs)AnimaltheAnimals=/创建包含Dog、Cat和Duck对象的数组newDog(Rover,Poodle),newCat(Max,Abyssinian),newDuck(Daffy,Aylesbury);AnimalpetChoice;/声明父类的引用Randomselect=newRandom();/创建随机数对象for(inti=0;i5;i+)petChoice=theAnimalsselect.nextInt(theAnimals.length);System.out.println(nYourChoice:n+petChoice);petChoice.sound();每次执行sound()成员方法时都将根据petChoice当前引用的对象类型调用相应的代码段,这就是典型的多态性效果。,42,4.5抽象类,概念是对类进行高层抽象的结果,可实例化的类是抽象概念的具体表现。在Java语言中,用抽象类表示概念性的事物,用类表示可实例化的实体类别,例如,可以用“学生”类描述“学生”这个抽象的概念,用“小学生”、“中学生”、“大学生”描述具体的学生类别,这些类可以被实例化,是“学生”概念的具体体现。,43,在Java语言中,抽象类就是用abstract修饰符声明的类。ModifierabstractclassclassName/成员变量和成员方法其中的成员方法既可以是抽象的,也可以是一般的。,Java语言中抽象类的声明,44,所谓抽象方法是指在类定义中,只被声明原型,而不定义方法体的成员方法。ModifierabstractreturnTypemethodName(parameterList)其中,abstract是声明抽象方法的关键字,returnType是返回类型,methodName是抽象方法的名称,parameterList是参数列表。由于抽象方法是不完整的成员方法,因此,只能包含在不能够被实例化的抽象类中。,45,publicabstractclassAnimalprotectedStringtype;/种类protectedStringname;/名称protectedStringbreed;/品种publicAnimal(Stringtype,Stringname,Stringbreed)this.type=newString(type);this.name=newString(name);this.breed=newString(breed);publicStringtoString()returnThisisa+type+nIts+name+the+breed;publicabstractvoidsound();/抽象方法,46,publicclassDogextendsAnimalpublicvoidsound()System.out.println(WoofWoof);publicclassCatextendsAnimalpublicvoidsound()System.out.println(Miiaooww);classDuckextendsAnimalpublicvoidsound()System.out.println(Quackquackquack);,47,任何包含抽象方法的类都必须被定义成抽象类由于抽象类不是一个完整的类,因此不能够被实例化抽象类主要用来派生子类,且在子类中必须覆盖抽象类中的所有抽象方法,以便完善它们的定义static、private和final修饰符不能应用于抽象方法和抽象类中。,使用抽象类时,需要注意下面几点:,48,4.6接口,4.6.1接口的声明声明接口的基本格式为:publicinterfaceinterfacename常量声明;抽象方法声明;public为接口的访问属性。在接口中,只允许出现常量和成员方法的定义,常量必须为publicstaticfinal,因此可以省略,成员方法必须是抽象方法,所以也可以省略abstract修饰符。,49,publicinterfaceConversions/各种计量单位转换接口/1英寸=25.4毫米doubleINCH_TO_MM=25.4;/1盎司=28.349523125克doubleOUNCE_TO_GRAM=28.349523125;/1磅=453.5924克doublePOUND_TO_GRAM=453.5924;/1马力=745.7瓦特doubleHP_TO_WATT=745.7;/1瓦特=1.0/745.7马力doubleWATT_TO_HP=1.0/HP_TO_WATT;,50,51,publicinterfaceComparable/比较两个对象大小intcompareTo(ObjectotherObject);,52,接口是一种用来声明常量和操作行为格式的特殊抽象类,在接口中声明的所有成员方法都是抽象方法,因此接口不能实例化,需要构造一个类,并在该类中覆盖接口中的所有方法,以便将其完善,通常,称此为某个类实现接口。,4.6.2接口的实现,53,publicclassEmployeeimplementsComparableprivateStringname;/姓名privatedoublesalary;/工资privateStringdepartment;/部门publicEmployee()publicEmployee(Stringname,doublesalary,Stringdepartment)this.name=newString(name);this.salary=salary;this.department=newString(department);/其他成员方法publicintcompareTo(ObjectotherObject)/完成compareTo()方法的定义Employeeother=(Employee)otherObject;if(salaryother.salary)return-1;/比较工资多少if(salary=other.salary)return0;elsereturn1;,54,Employeee1=newEmployee(Wang,2000.0,Software);Employeee2=newEmployee(Sun,3000.0,Math);switch(pareTo(e2)case-1:System.out.println();break;,55,接口是一种特殊形式的抽象类,它主要用来组织公用的常量,并统一操作行为的格式,通常它被应用在三个主要方面:用接口包装常量。可以将各式各样的常量放在接口中,让每个使用这些常量的类对象实现这个接口,从而达到享有这些常量的目的用接口实现多态性。将成员方法从类中分离出来组成一个接口,随后由每个类实现这个接口统一同类事物的操作接口。,接口的主要应用,56,4.7包,包是类和接口的集合。将所有的类和接口按功能分别放置在不同的包中主要有两点好处:一是便于将若干个已存在的类或接口整体地添加到程序代码中;二是避免出现类名冲突的现象。Java语言规定,在一个包中不允许有相同名称的类文件,但对于在不同包中的类文件没有这种限制,这是因为加载每个类时,必须指明该类所在的包名,以此区别不同包中的类。,57,包的概念是通过创建目录实现的。创建一个包就是用包的名称在文件系统下创建一个目录。在创建的目录下,既可以存放类文件或接口文件,也可以包含子目录,这些子目录是该包中的子包。创建一个包且将类文件放入其中的语法格式为:packagepackageName;,4.7.1创建包,58,若将类文件放入userPackage中,可以这样写:packageuserPackage;一条包语句必须是文件中的第一条语句。如果在一个类文件中,包含了这样一条语句,系统就会自动地在指定路径下寻找这个包,即目录名。若不存在,立即创建,并将该文件放入这个包中。如果希望将在一个文件中定义的类或接口放在不同的包中,就只能将它们分别放在不同的文件中,并利用包语句指定不同的包。,包的举例,59,指定一个包中的子包,就需要将每个包按层次顺序书写成一个包序列,包之间用逗号分隔。例如,若希望将一个类文件放入userPackage1的子包userPackage2的子包userPackage3中,就应该将包语句写成:packageuserPackage1.userPackage2.userPackage3;,指定子包,60,对于在包中具有public访问属性的类或接口,可以通过导入语句(import)将其添加到程序代码中,并通过类名或接口名引用这些类或接口。导入语句的基本格式为import后跟包名序列及类名。importuserPackage.*;userPackage是包名,.*代表将包中的所有类和接口都加载进来。importuserPackage1.userPackage2.userPackage3.*;这条语句表示将userPackage1包中的子包userPackage2的子包userPackage3中的所有类和接口加载进来。,4.7.2加载包,61,(1)自学4.8中的设计两人游戏。(2)作业:第4章中编程题1-5(3)上机作业:上机部分的实践题2。实现“井字棋”游戏。,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!