收藏 分销(赏)

第5章子类与继承.ppt

上传人:二*** 文档编号:12820564 上传时间:2025-12-11 格式:PPT 页数:76 大小:2.64MB 下载积分:5 金币
下载 相关 举报
第5章子类与继承.ppt_第1页
第1页 / 共76页
本文档共76页,全文阅读请下载到手机保存,查看更方便
资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第,5,章子类与继承,主要内容,子类与父类,子类的继承性,子类对象的特点,成员变量的隐藏和方法重写,super,关键字,final,关键字,对象的上转型对象,继承与多态,abstract,类与,abstract,方法,面向抽象编程,开,-,闭原则,难点,成员变量的隐藏和方法重写,开,-,闭原则,导读,当我们准备编写一个类的时候,发现某个类已经有了我们所需要的成员变量和方法,假如我们想复用这个类中的成员变量和方法,即在所编写的类中不用声明成员变量就相当于有了这个成员变量,不用定义方法就相当于有了这个方法,那么我们可以将编写的类声明为这个类的子类。,5.1,子类与父类,在类的声明中,通过使用关键字,extends,来声明一个类的子类,格式如下:,class,子类名,extends,父类名,什么叫继承呢?所谓子类继承父类的成员变量作为自己的一个成员变量,就好像它们是在子类中直接声明一样,可以被子类中自己定义的任何实例方法操作,所谓子类继承父类的方法作为子类中的一个方法,就像它们是在子类中直接定义了一样,可以被子类中自己定义的任何实例方法调用。也就是说,如果子类中定义的实例方法不能操作父类的某个成员变量或方法,那么该成员变量或方法就没有被子类继承。,子类不仅可以从父类继承成员变量和方法,而且根据需要还可以声明它自己的新成员变量、定义新的方法。,5.2,子类的继承性,访问限制修饰符不仅限制了对象对自己成员变量的操作和方法的调用,也限制了继承性。,当子类和父类在同一个包中时,父类中的,private,访问权限的成员变量不会被子类继承,,也就是说,子类继承父类中的除,private,访问权限以外的其他成员变量作为子类的成员变量;同样,子类继承父类中的除,private,访问权限以外的其他方法作为子类的方法。,5.2.1,子类和父类在同一包中的继承性,例,5-1,public class People,double height=170,weight=67.9;,protected void,tellHeightAndWeight,(),System.out.printf,(,我的体重和身高,:%2.2fkg,%2.2fcmn,weight,height);,public class Student,extends,People,int,number;,void,tellNumber,(),System.out.println,(,我的学号是,:+number);,int,add(int,x,int,y),return,x+y,;,int,sub(int,x,int,y),return,x-y,;,public class,UniverStudent,extends,Student,int,multi(int,x,int,y),return x*y;,double,div(double,x,double,y),return,x/y,;,public class Example5_1,public static void,main(String,args,),int,x=12,y=18;,Student,zhang,=new Student();,zhang.weight,=73.8;,zhang.height,=177;,zhang.number,=100101;,zhang.tellHeightAndWeight,();,zhang.tellNumber,();,System.out.print(zhang,会做加减:,);,int,result=,zhang.add(x,y,);,System.out.printf(%d+%d,=%,dt,x,y,result,);,result=,zhang.sub(x,y,);,System.out.printf(%d-%d,=%,dn,x,y,result,);,UniverStudent,geng,=new,UniverStudent,();,geng.number,=6609;,geng.tellHeightAndWeight,();,geng.tellNumber,();,System.out.print(geng,会做加减乘除:,);,result=,geng.add(x,y,);,System.out.printf(%d+%d,=%,dt,x,y,result,);,result=,geng.sub(x,y,);,System.out.printf(%d-%d,=%,dt,x,y,result,);,result=,geng.multi(x,y,);,System.out.printf(%d%d,=%,dt,x,y,result,);,double re=,geng.div(x,y,);,System.out.printf(%d%d,=%,fn,x,y,re,);,当子类和父类不在同一个包中时,父类中的,private,和友好访问权限的成员变量不会被子类继承,,也就是说,子类只继承父类中的,protected,和,public,访问权限的成员变量作为子类的成员变量,;同样,子类只继承父类中的,protected,和,public,访问权限的方法作为子类的方法。,5.2.2,子类和父类不在同一包中的继承性,现在需要对,protected,总结得更全面些:,A-B,B-C,C=200),System.out.println,(,考分,+total+,达到大学最低录取线,);,else,System.out.println,(,考分,+total+,未达到大学最低录取线,);,public class,ImportantUniversity,extends,University,void,enterRule(double,math,double,english,double,chinese,),double total=,math+english+chinese,;,if(total,=245),System.out.println,(,考分,+total+,达到重点大学最低录取线,);,else,System.out.println,(,考分,+total+,未达到重点大学最低录取线,);,public class Example5_4,public static void,main(String,args,),double math=64,english=76.5,chinese=66;,ImportantUniversity,univer,=new,ImportantUniversity,();,univer.enterRule(math,english,chinese,);/,调用重写的方法,math=89;,english,=80;,chinese,=86;,univer,=new,ImportantUniversity,();,univer.enterRule(math,english,chinese,);/,调用重写的方法,class A,float,computer(float,x,float,y),return,x+y,;,public,int,g(int,x,int,y),return,x+y,;,class B extends A,float,computer(float,x,float,y),return x*y;,public class Example5_5,public static void,main(String,args,),B b=new B();,double result=puter(8,9);/b,调用重写的方法,System.out.println,(,调用重写方法得到的结果,:+result);,int,m=b.g(12,8);/b,调用继承的方法,System.out.println,(,调用继承方法得到的结果,:+m);,例,5-5,在,JDK 1.5,版本之后,,允许重写方法的类型可以是父类方法的类型的子类型,即不必完全一致,(,JDK 1.5,版本之前要求必须一致),也就是说,如果父类的方法的类型是,“,类,”,,重写方法的类型可以是,“,子类,”,。,3,JDK 1.5,对重写的改进,例,5-6,public class,HomeEletricity,int,weight;,public void,setWeight(int,w),weight=w;,public void,showMess,(),System.out.println,(,我是家用电器,);,public class,Television,extends,HomeEletricity,public void,showMess,(),System.out.println,(,我是电视机,重量是,+,weight+kg,);,public class,Icebox,extends,HomeEletricity,public void,showMess,(),System.out.println,(,我是冰箱,重量是,+,weight+kg,);,class Factory,public,HomeEletricity,make()/,方法的类型是,HomeEletricity,类,HomeEletricity,machine=new,HomeEletricity,();,return machine;,class,TVFactory,extends Factory,public Television make()/,重写方法的类型是,HomeEletricity,类的子类,:Television,Television,tv,=new Television();,tv.setWeight(21);,return,tv,;,class,IceboxFactory,extends Factory,public Icebox make()/,重写方法的类型是,HomeEletricity,类的子类,:Icebox,Icebox,icebox,=new Icebox();,icebox.setWeight(67);,return icebox;,public class Example5_6,public static void,main(String,args,),TVFactory,factory1=new,TVFactory,();,Television,tv,=factory1.make();/factory1,调用重写的方法,tv.showMess,();,IceboxFactory,factory2=new,IceboxFactory,();,Icebox,icebox,=factory2.make();/factory2,调用重写的方法,icebox.showMess,();,重写父类的方法时,不可以降低方法的访问权限。下面的代码中,,子类重写父类的方法,f,,该方法在父类中的访问权限是,protected,级别,子类重写时不允许级别低于,protected,4,重写的注意事项,class A,protected float,f(float,x,float,y),return,x-y,;,class B extends A,float,f(float,x,float,y),return,x+y,;,5.5.1,用,super,操作被隐藏的成员变量和方法,子类一旦隐藏了继承的成员变量,那么子类创建的对象就不再拥有该变量,该变量将归,关键字,super,所有,,同样子类一旦隐藏了继承的方法,那么子类创建的对象就不能调用被隐藏的方法,,该方法的调用由关键字,super,负责,。因此,,如果在子类中想使用被子类隐藏的成员变量或方法就需要使用关键字,super,。,5.5 super,关键字,例,5-7,public class Bank,int,savedMoney,;,int,year;,double interest;,public double,computerInterest,(),interest=year*0.035*,savedMoney,;,System.out.printf(%d,元存在银行,%d,年的利息,:%f,元,n,savedMoney,year,interest,);,return interest;,public class,ConstructionBank,extends Bank,double year;,public double,computerInterest,(),super.year,=(,int)year,;,double,remainNumber,=year-(,int)year,;,int,day=(,int)(remainNumber,*1000);,interest=,puterInterest()+day,*0.0001*,savedMoney,;,System.out.printf(%d,元存在建设银行,%d,年零,%d,天的利息,:%f,元,n,savedMoney,super.year,day,interest,);,return interest;,public class,BankOfDalian,extends Bank,double year;,public double,computerInterest,(),super.year,=(,int)year,;,double,remainNumber,=year-(,int)year,;,int,day=(,int)(remainNumber,*1000);,interest=,puterInterest()+day,*0.00012*,savedMoney,;,System.out.printf(%d,元存在大连银行,%d,年零,%d,天的利息,:%f,元,n,savedMoney,super.year,day,interest,);,return interest;,public class Example5_7,public static void,main(String,args,),int,amount=5000;,ConstructionBank,bank1=new,ConstructionBank,();,bank1.savedMoney=amount;,bank1.year=5.216;,double interest1=puterInterest();,BankOfDalian,bank2=new,BankOfDalian,();,bank2.savedMoney=amount;,bank2.year=5.216;,double interest2=puterInterest();,System.out.printf,(,两个银行利息相差,%f,元,n,interest2-interest1);,当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,也就是说,,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法,即如果在子类的构造方法中,没有明显地写出,super,关键字来调用父类的某个构造方法,那么默认地有:,super();,子类不继承父类的构造方法,,因此,子类在其构造方法中需使用,super,来调用父类的构造方法,,而且,super,必须是子类构造方法中的头一条语句。,5.5.2,使用,super,调用父类的构造方法,例,5-8,public class Card,String title;,Card(),title=,新年快乐,!;,Card(String,title),this.title,=title;,public String,getTitle,(),return title;,public class,ChristmasCard,extends Card,String content;,/,子类新增的,content,ChristmasCard(String,title,String,content),super(title,);,/,调用父类的构造方法,即执行,Card(title,),this.content,=content;,public void,showCard,(),System.out.println,(*+,getTitle,()+*);,System.out.printf(%s,content,);,public class Example5_8,public static void,main(String,args,),String title=Happy New Year To You;,String content=t,牛年耕耘,nt,谷穗满仓,nt,出生牛犊,nt,喜迎虎年,n;,ChristmasCard,card=new,ChristmasCard(title,content,);,card.showCard,();,final,关键字可以,修饰类,、,成员变量,和方法中的,局部变量。,5.6 final,关键字,可以使用,final,将类声明为,final,类。,final,类不能被继承,即不能有子类,。如:,final class A,A,就是一个,final,类,将不允许任何类声明成,A,的子类。有时候是出于安全性的考虑,将一些类修饰为,final,类。例如,,Java,提供的,String,类,,它对于编译器和解释器的正常运行有很重要的作用,对它不能轻易改变,它被修饰为,final,类。,5.6.1 final,类,如果用,final,修饰父类中的一个方法,那么,这个方法不允许子类重写,,也就是说,不允许子类隐藏可以继承的,final,方法(,老老实实继承,不许做任何篡改,)。,5.6.2 final,方法,如果成员变量或局部变量被修饰为,final,,那么,它就是常量,。常量在声明时没有默认值,所以在,声明常量时必须指定该常量的值,而且不能再发生变化,。,5.6.3,常量,class A,final double PI=3.1415926;/PI,是常量,public double,getArea(final,double r),return PI*r*r;,public final void speak(),System.out.println,(,您好,,Hows everything here?);,public class Example5_9,public static void,main(String,args,),A a=new A();,System.out.println,(,面积:,+a.getArea(100);,a.speak,();,假设,,A,类是,B,类的父类,,,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时,,如:,A a;,a=new B();,或,A a;,B b=new B();,a=b;,这时,,称对象,a,是对象,b,的上转型对象,(就像说:,“,美国人是人,”,)。,对象的上转型对象的实体是子类负责创建的,,但上转型对象会失去原对象的一些属性和功能(上转型对象相当于子类对象的一个,“,简化,”,对象)。,5.7,对象的上转型对象,(,1,),上转型对象不能操作子类新增的成员变量,(失掉了这部分属性);,不能调用子类新增的方法,(失掉了一些功能)。,(,2,)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。,上转型对象操作子类继承的方法或子类重写的实例方法,其作用等价于子类对象去调用这些方法。,因此,如果子类重写了父类的某个实例方法后,当对象的上转型对象调用这个实例方法时一定是,调用了子类重写的实例方法,。,上转型对象具有如下特点(,重要,),例,5-10,public class People,int,height;,double weight;,void,showBodyMess,(),System.out.printf,(*n);,void,mustDoingThing,(),System.out.println,(,吃饭、睡觉,.,饮水,);,public class American,extends People,void,showBodyMess,(),System.out.println(bodyHeight:+height+cm,+,bodyWeight:+weight+kg,);,void,speakEnglish,(),System.out.println(I,am,Amerian,);,public class Chinese,extends People,void,showBodyMess,(),System.out.printf,(,身高,:%5dcmt,体重,:%3.2fkgn,height,weight);,void,speakChinese,(),System.out.println,(,我是中国人,);,public class Example5_10,public static void,main(String,args,),People,people,=null;,American Johnson=new American();,people=Johnson;/people,是,Johnson,对象的上转型对象。,people.height,=187;/,同于,Johnson.height,=187,people.weight,=78.67;,people.showBodyMess,();/,等同于,Johnson,调用重写的,showBodyMess,(),方法,/,people.speakEnglish,();/,非法,因为,speakEnglish,(),是子类新增的方法,people.mustDoingThing,();,Chinese,zhang,=new Chinese();,people=,zhang,;/people,是,zhang,对象的上转型对象。,people.height,=177;/,同于,zhang.height,=187,people.weight,=68.59;,people.showBodyMess,();/,等同于,Johnson,调用重写的,showBodyMess,(),方法,/,people.speakChinese,();/,非法,因为,speakChinese,(),是子类新增的方法,people.mustDoingThing,();,zhang,=(,Chinese)people,;,zhang.speakChinese,();,当一个类有很多子类时,并且这些子类都,重写了,父类中的某个实例方法,那么当我们把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个,上转型对象,,那么这个,上转型对象在调用这个实例方法时就可能具有多种形态,,因为不同的子类在重写父类的实例方法时可能产生不同的行为。,多态性就是指父类的某个实例方法被其子类重写时,可以各自产生自己的功能行为。,5.8,继承与多态,5-11,class,EspecialCar,void,cautionSound,(),class,PoliceCar,extends,EspecialCar,void,cautionSound,(),System.out.println(zhua.zhua.zhua,.);,class,AmbulanceCar,extends,EspecialCar,void,cautionSound,(),System.out.println(jiu.jiu.jiu,.);,class,FireCar,extends,EspecialCar,void,cautionSound,(),System.out.println(huo.huo.huo,.);,public class Example5_11,public static void,main(String,args,),EspecialCar,car=new,PoliceCar,();/car,是警车的上转型对象,car.cautionSound,();,car=new,AmbulanceCar,();/car,是救护车的上转型对象,car.cautionSound,();,car=new,FireCar,();/car,是消防车的上转型对象,car.cautionSound,();,用,关键字,abstract,修饰的类称为,abstract,类,(抽象类)。如:,abstract class A,用关键字,abstract,修饰的方法称为,abstract,方法(抽象方法),,对于,abstract,方法,只允许声明,不允许实现,而且不允许使用,final,和,abstract,同时修饰一个方法,5.9 abstract,类和,abstract,方法,和普通的类相比,,abstract,类可以有,abstract,方法(抽象方法)也可以有非,abstract,方法,。,1,abstract,类中可以有,abstract,方法,abstract,class A,abstract,int,min(int,x,int,y);,int,max(int,x,int,y),return x,y?x:y,;,对于,abstract,类,,我们不能使用,new,运算符创建该类的对象。,如果一个非抽象类是某个抽象类的子类,那么它必须重写父类的抽象方法,给出方法体,,这就是为什么不允许使用,final,和,abstract,同时修饰一个方法的原因。,注:,abstract,类也可以没有,abstract,方法。,注:如果一个,abstract,类是,abstract,类的子类,它可以重写父类的,abstract,方法,也可以继承这个,abstract,方法,。,2,abstract,类不能用,new,运算创建对象,abstract class A,abstract,int,sum(int,x,int,y);,int,sub(int,x,int,y),return,x-y,;,class B extends A,int,sum(int,x,int,y)/,子类必须重写父类的,sum,方法,return,x+y,;,public class Example5_12,public static void,main(String,args,),B b=new B();,int,sum=b.sum(30,20);/,调用重写的方法,int,sub=b.sub(30,20);/,调用继承的方法,System.out.println(sum,=+sum);/,输出结果为,sum=50,System.out.println(sum,=+sub);/,输出结果为,sum=10,在设计程序时,经常会使用,abstract,类,其原因是,,abstract,类只关心操作,,但不关心这些操作具体实现的细节,可以使程序的设计者把主要精力放在程序的设计上,,而不必拘泥于细节的实现,(将这些细节留给子类的设计者),即避免设计者把大量的时间和精力花费在具体的算法上。,在设计一个程序时,可以通过在,abstract,类中声明若干个,abstract,方法,,表明这些方法在整个系统设计中的重要性,,方法体的内容细节由它的非,abstract,子类去完成。,5.10,面向抽象编程,使用多态进行程序设计的,核心技术之一,是使用,上转型对象,,即将,abstract,类声明对象作为其子类的上转型对象,,那么这个上转型对象就可以调用子类重写的方法,。,所谓面向抽象编程,是指当设计一个类时,不让该类面向具体的类,而是,面向抽象类,,即所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。,小例题,public class,Circle,double r;,Circle(double,r),this.r,=r;,public double,getArea,(),return 3.14*r*r;,public class,Pillar,Circle bottom;,dobule,height;,Pillar(Circle,bottom,double,height),this.bottom,=,bottom;this.height,=height;,public double,getVolume,(),return,bottom.getArea,()*height;,分析,当用户要把柱体的底改变的时候,则,Pillar,类无法适应该需求,可以抽象出一个抽象的图像类,public abstract class Geometry,public abstract double,getArea,();,下面重写,Pillar,类和,Circle,类,public class,Pillar,Geometry bottom;,dobule,height;,Pillar(,Geometry,bottom,double,height),this.bottom,=,bottom;this.height,=height;,public double,getVolume,(),return,bottom,.getArea,()*height;,public class,Circle,extends,Geometry,double r;,Circle(double,r),this.r,=r;,public double,getArea,(),return 3.14*r*r;,扩展了一个长方形类,public class,Rectangle,extends,Geometry,double,a,b,;,Rectangle(double,a,double,b),this.a,=,a;this.b,=b;,public double,getArea,(),return a*b;,public class,Application,Pillar,pillar,;,Geometry,bottom;,bottom,=new,Rectangle,(12,22);,pillar=new,Pillar,(bottom,58);,System.out.println,(,矩形圆柱体的体积是,:+,pillar.getVolume,();,bottom=new,Circle,(10);,pillar=new,Pillar,(bottom,58);,System.out.println,(,圆形底圆柱体的体积是,:+,pillar.getVolume,();,所谓,“,开,-,闭原则,”,(,Open-Closed Principle,)就是让设计的系统,应当对扩展开放,对修改关闭。,实际上这句话的本质是指当系统中增加新的模块时,不需要修改现有的模块。在设计系统时,应当首先考虑到用户需求的变化,将应对用户变化的部分设计为对扩展开放,而设计的核心部分是经过精心考虑之后确定下来的基本结构,这部分应当是对修改关闭的,,5.11,开,-,闭原则,例,5-13,public abstract class,Animal,public abstract void cry();,public abstract String,getAnimalName,();,public class,Simulator,public void,playSound(Animal,animal),System.out.print,(,现在播放,+,animal.getAnimalName,()+,类的声音,:);,animal.cry,();,public class,Dog,extends Animal,public void cry(),System.out.println,(,汪汪,.,汪汪,);,public String,getAnimalName,(),return,狗,;,public class,Cat,extends Animal,public void cry(),System.out.println,(,喵喵,.,喵喵,);,public String,getAnimalName,(),return,猫,;,public class,Application,public static void,main(String,args,),Simulator,simulator,=new,Simulator,();,simulator.playSound(new,Dog();,simulator.playSound(new,Cat();,
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 环境建筑 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服