封装与继承知识回顾课程项目电子宠物系统主人登录领养宠物给宠物喂食与宠物游戏给宠物看病显示主人信息显示宠物信息本章任务用类图描述电子宠物系统的设计编写代码实现领养宠物功能一个现实世界的问题宠物——现实世界的对象如何在计算机中描述它?从现实中抽象出类分三步:1.找出它的种类2.找出它的属性3.找出它的行为用面向对象描述世界3-1用面向对象的思想描述世界第一步:发现类根据“对象”抽象出“类”classDog{}名词各个狗对象用面向对象描述世界3-2第二步:发现类的属性狗类共有的特征:1.品种2.年龄3.昵称4.健康情况5.跟主人的亲密度……classDog{Stringname=旺财;//昵称inthealth=100;//健康值intlove=0;//亲密度Stringstrain=拉布拉多犬;//品种}只放我关心的属性名词用面向对象描述世界3-3第三步:发现类的方法狗类共有的行为:1.跑2.吠3.输出狗的信息……动词classDog{Stringname=旺财;//昵称inthealth=100;//健康值intlove=0;//亲密度Stringstrain=拉布拉多犬;//品种/*输出狗的信息*/publicvoidprint(){//输出狗信息的代码}}只放我关心的方法类图使用类图描述类用于分析和设计“类”直观、容易理解+name:String+health:int+love:int+strain:StringDog+print():void“+”:public“-”:private类名返回值类型类型属性名参数:名字:类型,名字:类型方法名实现领养宠物实现领养宠物功能编写宠物类Dog和Penguin创建宠物对象,输入宠物信息,最后输出演示示例:领养宠物功能构造方法3-1对象初始化Penguinpgn=newPenguin();pgn.name=qq;pgn.sex=Q仔;classPenguin{//属性/*无参构造方法*/publicPenguin(){name=qq;love=20;sex=Q仔;System.out.println(执行构造方法);}}使用构造方法:Penguinpgn1=newPenguin();能否在创建对象的同时就完成赋值?构造方法构造方法3-2构造方法public构造方法名(){//初始化代码}与类名相同没有返回值类型publicPenguin(){name=qq;love=20;sex=Q仔;System.out.println(执行构造方法);}可以指定参数构造方法3-3阅读代码,说出运行结果,并指出原因classPenguin{publicvoidPenguin(){health=10;sex=雄;System.out.println(执行构造方法);}publicvoidprint(){System.out.println(企鹅的名字是+name+,健康值是+health+,性别是+sex);}}Penguinpgn3=newPenguin();pgn3.print();有返回值类型,不是构造方法方法重载一个类是否可以有多个构造方法?方法重载,指同一个类中多个方法:方法名相同参数列表不同与返回值、访问修饰符无关publicPenguin(){//代码}publicPenguin(Stringname,inthealth,intlove,Stringsex){//代码}示例2System.out.println(45);System.out.println(true);System.out.println(狗在玩耍!);示例1什么是封装面向对象三大特征之一——封装封装的概念封装的好处封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问隐藏类的实现细节只能通过规定方法访问数据方便加入控制语句方便修改实现如何使用封装封装的步骤修改属性的可见性创建getter/setter方法在getter/setter方法中加入属性控制语句设为private用于属性的读写对属性值的合法性进行判断classDog{privateStringname=旺财;//昵称privateinthealth=100;//健康值privateintlove=0;//亲密度privateStringstrain=拉布拉多犬;//品种publicintgetHealth(){returnhealth;}publicvoidsetHealth(inthealth){if(health100||health0){this.health=40;System.out.println(健康值应该在0和100之间,默认值是40);}elsethis.health=health;}//其它getter/setter方法}this代表当前对象1223-name:String-health:int-love:int-strain:StringDog+print():void+setHealth():void+getHealth():String……this的用法this关键字的用法调用属性调用方法调用构造方法this.health=100;this.name=大黄;this.print();this();如果使用,必须是构造方法中的第一条语句this(小黑,100,100,雄);小结分析需求,用封装方式设计类,画出类图汽车销售人员销售汽车,可售款式有凯越、君威每款汽车有款式和编号,款式、编号不能修改汽车销售人员有姓名,姓名不能修改销售人员有两种销售方式:按车辆销售,每次一辆按车型销售(凯越),要同时告诉销售人员购买数量-type:String-id:StringExcelle+Excelle(id:String,type:String)+getType():String+getId():String-type:String-id:StringRegal+Regal(id:String,type:String)+getType():String+getId():String-name:StringSeller+getName():String+setName(name:String):void+sell(car:Excelle):void+sell(car:Regal):void+sell(car:Excelle,num:int):void凯越君威销售员练习——用类图设计Dog和Penguin类需求说明:运用面向对象思想抽象出Dog类和Penguin类,画出对应类图根据类图编写Dog类和Penguin类添加默认构造方法完成时间:20分钟类型属性行为狗昵称健康值亲密度品种输出信息企鹅昵称健康值亲密度性别输出信息指导——打印Dog信息2-1训练要点:类的结构,对象的创建,类的属性和方法的调用类的封装需求说明:根据控制台提示信息选择领养宠物(狗),输入昵称、品种、健康值打印宠物信息要保证健康值的有效性(在1到100之间)讲解需求说明指导——打印Dog信息2-2实现思路:修改Dog类编写Test类完成时间:30分钟从控制台输入宠物信息打印宠物信息保证健康值的有效性,否则取默认值60练习——Dog类的带参构造方法需求说明:增加带参构造方法将setHealth()方法设为私有,注释掉其他setter方法修改Test类,使用带参构造方法创建对象完成时间:20分钟Dog(Stringname,inthealth,intlove,Stringstrain)Penguin(Stringname,inthealth,intlove,Stringsex)练习——操作企鹅性别属性需求说明:给Penguin类提供SEX_MALE和SEX_FEMALE两个静态常量,分别取值“Q仔”或“Q妹”修改Test类,使用静态常量对性别进行赋值修改企鹅的性别只能取值“雄”或“雌”,通过修改静态常量值实现该需求完成时间:15分钟优化电子宠物系统实现汽车租赁系统计价功能为什么使用继承2-1这两个类图有什么问题?-name:String-health:int-love:int-strain:StringDog+print():void+getName():String+getHealth():int+getLove():int+getStrain:String+Dog()-name:String-health:int-love:int-sex:StringPenguin+print():void+getName():String+getHealth():int+getLove():int+getSex():String+Penguin()使用继承优化设计将重复代码抽取到父类中为什么使用继承2-2使用继承优化后:子类与父类是is-a关系减少代码量方便修改代码如何使用继承使用继承编写父类编写子类,继承父类classPet{//公共的属性和方法}classDogextendsPet{//子类特有的属性和方法}classPenguinextendsPet{}只能继承一个父类继承关键字对比C#用“:”理解继承4-4继承后的初始化顺序演示示例:断点追踪初始化过程父类属性子类属性父类构造方法子类构造方法在何处使用继承何时使用继承?继承与真实世界类似只要说“猫是哺乳动物”,猫的很多属性、行为就不言自明了藏獒是一种狗继承是代码重用的一种方式将子类都有的属性和行为放到父类中符合is-a关系的设计使用继承指导——优化电子宠物系统2-1训练要点:继承子类重写父类方法理解继承中的初始化过程需求说明:优化电子宠物系统使用继承实现Dog类和Penguin类打印宠物信息讲解需求说明指导——优化电子宠物系统2-2实现思路:完成时间:20分钟继承抽象类以下代码有什么问题?Java中使用抽象类,限制实例化Petpet=newPet(贝贝,20,40);pet.print();实例化Pet没有意义publicabstractclassPet{}抽象方法以下代码有什么问题?abstract也可用于方法——抽象方法抽象方法没有方法体抽象方法必须在抽象类里抽象方法必须在子类中被实现,除非子类是抽象类publicabstractvoidprint();没有方法体publicabstractclassPet{publicvoidprint(){//…}}每个子类的实现不同指导——抽象Pet类2-1训练要点:抽象类的定义和继承抽象方法定义和重写需求说明:修改Pet类为抽象类修改Pet类的print()方法为抽象方法输出Dog信息讲解需求说明指导——抽象Pet类2-2实现思路修改Pet类为抽象类,修改print()为抽象方法Dog类继承Pet类,实现print()方法运行测试注释掉Dog类中print()方法,运行测试类查看错误信息编写注释final用法Penguin类不希望再被其他类继承?使用final类方法不希望被重写?使用final方法属性值不希望被修改?使用final方法publicfinalclassPenguinextendsPet{//…}最终版的类publicfinalvoidprint(){//…}最终版的方法publicclassPenguin{finalStringhome=南极;//居住地publicvoidsetHome(Stringname){this.home=home;//错误,home不可以再次赋值}}最终版的属性值常见错误请指出下面代码的错误classDog{Stringname;publicDog(Stringname){this.name=name;}}classTest{publicstaticvoidmain(String[]args){finalDogdog=newDog(欧欧);dog.name=美美;dog=newDog(亚亚);}}使用final修饰引用型变量,变量不可以再指向另外的对象使用final修饰引用型变量,变