《第5章子类与继承》由会员分享,可在线阅读,更多相关《第5章子类与继承(76页珍藏版)》请在金锄头文库上搜索。
1、熄肖键领纹樟汝檬香辱傻澄谩槛樊汲君蝎渭下驮盖啮摹悦症泞阶卓萍恃熔第5章子类与继承第5章子类与继承主要内容 子类与父类 子类的继承性 子类对象的特点 成员变量的隐藏和方法重写 super关键字 final关键字 对象的上转型对象 继承与多态 abstract类与abstract方法 面向抽象编程 开-闭原则难点 成员变量的隐藏和方法重写 开-闭原则导读导读虫棕茁讼崭癌总子眉邦督世实瓷屯说召艰贼庇送步锥抢君心碾岭侈骤焊翁第5章子类与继承第5章子类与继承当我们准备编写一个类的时候,发现某个类已经有当我们准备编写一个类的时候,发现某个类已经有了我们所需要的成员变量和方法,假如我们想复用了我们所需要的成
2、员变量和方法,假如我们想复用这个类中的成员变量和方法,即在所编写的类中不这个类中的成员变量和方法,即在所编写的类中不用声明成员变量就相当于有了这个成员变量,不用用声明成员变量就相当于有了这个成员变量,不用定义方法就相当于有了这个方法,那么我们可以将定义方法就相当于有了这个方法,那么我们可以将编写的类声明为这个类的子类。编写的类声明为这个类的子类。旗杜降寿和碘沽饺申茶示汰兑使怨皇疼统吵篆酱矗淑奇荚滴贰戏尝诡排恕第5章子类与继承第5章子类与继承在类的声明中,通过使用关键字在类的声明中,通过使用关键字extendsextends来声明一来声明一个类的子类,格式如下:个类的子类,格式如下:class
3、class 子类名子类名 extends extends 父类名父类名 丰鬃犬缴哮撂糕虑著漳惦恒研揣职蛆奴妖晰当搞烁瓶迸祁掩两忧粱溪焙萝第5章子类与继承第5章子类与继承什么叫继承呢?所谓子类继承父类的成员变量作什么叫继承呢?所谓子类继承父类的成员变量作为自己的一个成员变量,就好像它们是在子类中为自己的一个成员变量,就好像它们是在子类中直接声明一样,可以被子类中自己定义的任何实直接声明一样,可以被子类中自己定义的任何实例方法操作例方法操作所谓子类继承父类的方法作为子类中的一个方法,所谓子类继承父类的方法作为子类中的一个方法,就像它们是在子类中直接定义了一样,可以被子就像它们是在子类中直接定义了一
4、样,可以被子类中自己定义的任何实例方法调用。也就是说,类中自己定义的任何实例方法调用。也就是说,如果子类中定义的实例方法不能操作父类的某个如果子类中定义的实例方法不能操作父类的某个成员变量或方法,那么该成员变量或方法就没有成员变量或方法,那么该成员变量或方法就没有被子类继承。被子类继承。子类不仅可以从父类继承成员变量和方法,而且子类不仅可以从父类继承成员变量和方法,而且根据需要还可以声明它自己的新成员变量、定义根据需要还可以声明它自己的新成员变量、定义新的方法。新的方法。较摘椅盛祥啡础笛落沫键枚谷铺叮跌攻渊岿浓奉朽刺既逗删慰铰颁沂圆议第5章子类与继承第5章子类与继承访问限制修饰符不仅限制了对象
5、对自己成员变量的访问限制修饰符不仅限制了对象对自己成员变量的操作和方法的调用,也限制了继承性。操作和方法的调用,也限制了继承性。当子类和父当子类和父类在同一个包中时,父类中的类在同一个包中时,父类中的privateprivate访问权限的访问权限的成员变量不会被子类继承成员变量不会被子类继承,也就是说,子类继承父,也就是说,子类继承父类中的除类中的除privateprivate访问权限以外的其他成员变量作访问权限以外的其他成员变量作为子类的成员变量;同样,子类继承父类中的除为子类的成员变量;同样,子类继承父类中的除privateprivate访问权限以外的其他方法作为子类的方法。访问权限以外的
6、其他方法作为子类的方法。煞乏肠狄飞治俄撮喘减款饿陶尺博二抓斌桓姜但蠢攫凡泉茧寅快彻揭资陋第5章子类与继承第5章子类与继承例例5-15-1public class People public class People double height=170,weight=67.9; double height=170,weight=67.9; protected void protected void tellHeightAndWeight() tellHeightAndWeight() System.out.printf( System.out.printf(我的体重和我的体重和身高身高:%2.2
7、fkg,%2.2fcmn,weight,height);:%2.2fkg,%2.2fcmn,weight,height); 伶懊秋富址耀阐似鱼蚌鄙入慈替味靛谍脂钠炳擂绦败驭倦询门竣荡翰次逆第5章子类与继承第5章子类与继承public class Student public class Student extendsextends People People int number; int number; void tellNumber( ) void tellNumber( ) System.out.println( System.out.println(我的学号是我的学号是:+number
8、); :+number); int add(int x,int y) int add(int x,int y) return x+y; return x+y; int sub(int x,int y) int sub(int x,int y) return x-y; return x-y; 串吱罢椅刷妹酞衔霓军魁硅蛆捉叼银迭荔孙岔悦锰樱激灵侍涤粳猿莽圃斤第5章子类与继承第5章子类与继承public class UniverStudent public class UniverStudent extendsextends Student Student int multi(int x,int y
9、) int multi(int x,int y) return x*y; return x*y; double div(double x,double y) double div(double x,double y) return x/y; return x/y; 抵稿缩朽仍并拈抑生用肚匈然滞烬姑拜伎献揭筑易美拳荐鳞墅舒污慈湛节第5章子类与继承第5章子类与继承public class Example5_1 public class Example5_1 public static void main(String args) public static void main(String arg
10、s) int x=12,y=18; int x=12,y=18; Student zhang = new Student(); Student zhang = new Student(); zhang.weight=73.8; zhang.weight=73.8; zhang.height=177; zhang.height=177; zhang.number=100101; zhang.number=100101; zhang.tellHeightAndWeight(); zhang.tellHeightAndWeight(); zhang.tellNumber(); zhang.tellN
11、umber(); System.out.print(zhang System.out.print(zhang会做加减:会做加减:);); int result=zhang.add(x,y); int result=zhang.add(x,y); System.out.printf(%d+%d=%dt,x,y,result); System.out.printf(%d+%d=%dt,x,y,result); result=zhang.sub(x,y); result=zhang.sub(x,y); System.out.printf(%d-%d=%dn,x,y,result); System.o
12、ut.printf(%d-%d=%dn,x,y,result); UniverStudent geng = new UniverStudent(); UniverStudent geng = new UniverStudent(); geng.number=6609; geng.number=6609; geng.tellHeightAndWeight(); geng.tellHeightAndWeight(); geng.tellNumber(); geng.tellNumber(); System.out.print(geng System.out.print(geng会做加减乘除:会做加
13、减乘除:);); result=geng.add(x,y); result=geng.add(x,y); System.out.printf(%d+%d=%dt,x,y,result); System.out.printf(%d+%d=%dt,x,y,result); result=geng.sub(x,y); result=geng.sub(x,y); System.out.printf(%d-%d=%dt,x,y,result); System.out.printf(%d-%d=%dt,x,y,result); result=geng.multi(x,y); result=geng.mul
14、ti(x,y); System.out.printf(%d%d=%dt,x,y,result); System.out.printf(%d%d=%dt,x,y,result); double re=geng.div(x,y); double re=geng.div(x,y); System.out.printf(%d%d=%fn,x,y,re); System.out.printf(%d%d=%fn,x,y,re); 坚最略违让辣哦祷曙渡欺苔自撇瞒禽矢浑界碎蹬凹莆赣蔑为鄂册佐芋渍轻第5章子类与继承第5章子类与继承当子类和父类不在同一个包中时,父类中的当子类和父类不在同一个包中时,父类中的pri
15、vateprivate和友好访问权限的成员变量不会被子类继和友好访问权限的成员变量不会被子类继承,承,也就是说,子类只继承父类中的也就是说,子类只继承父类中的protectedprotected和和publicpublic访问权限的成员变量作为子类的成员变量访问权限的成员变量作为子类的成员变量;同样,子类只继承父类中的同样,子类只继承父类中的protectedprotected和和publicpublic访访问权限的方法作为子类的方法。问权限的方法作为子类的方法。稽默味皿系位田朋觉颤温矗史校皂催盛逼建琅仁宗珐撤趟定牢谨盐烈捞铸第5章子类与继承第5章子类与继承现在需要对现在需要对protecte
16、dprotected总结得更全面些:总结得更全面些:A-B, B-C, A-B, B-C, C-DC=200) if(total=200) System.out.println( System.out.println(考分考分+total+total+达到大学最低录取达到大学最低录取线线);); else else System.out.println( System.out.println(考分考分+total+total+未达到大学最低录未达到大学最低录取线取线);); 淤儒华融除妻熙盐联酷提凄磕娄娱撮擞裔牲碍恐饿撇模揖绽贱牟冰进稍徒第5章子类与继承第5章子类与继承public class
17、 ImportantUniversity public class ImportantUniversity extendsextends UniversityUniversity void enterRule(double math,double void enterRule(double math,double english,double chinese) english,double chinese) double total=math+english+chinese; double total=math+english+chinese; if(total=245) if(total=2
18、45) System.out.println( System.out.println(考分考分+total+total+达到重达到重点大学最低录取线点大学最低录取线);); else else System.out.println( System.out.println(考分考分+total+total+未达到未达到重点大学最低录取线重点大学最低录取线);); 雨值悲淹掣划妮党沂分验络班摄扫灭羊遍够走滤害誓是挟渤景芦即嘎漠选第5章子类与继承第5章子类与继承public class Example5_4 public class Example5_4 public static void mai
19、n(String args) public static void main(String args) double math=64,english=76.5,chinese=66; double math=64,english=76.5,chinese=66; ImportantUniversity univer = new ImportantUniversity univer = new ImportantUniversity();ImportantUniversity(); univer.enterRule(math,english,chinese); / univer.enterRul
20、e(math,english,chinese); /调用重写的方法调用重写的方法 math=89; math=89; english=80; english=80; chinese=86; chinese=86; univer = new ImportantUniversity(); univer = new ImportantUniversity(); univer.enterRule(math,english,chinese); / univer.enterRule(math,english,chinese); /调用重写的方法调用重写的方法 问嫁嚷重廖磁那齿岸游奔眠况立耻房雀坏病咸诽悟波
21、洒凑交好痔蛰衡扎捻第5章子类与继承第5章子类与继承class A class A float computer(float x,float y) float computer(float x,float y) return x+y; return x+y; public int g(int x,int y) public int g(int x,int y) return x+y; return x+y; class B extends A class B extends A float computer(float x,float y) float computer(float x,floa
22、t y) return x*y; return x*y; public class Example5_5 public class Example5_5 public static void main(String args) public static void main(String args) B b=new B(); B b=new B(); double result=puter(8,9); /b double result=puter(8,9); /b调用重写的方法调用重写的方法 System.out.println( System.out.println(调用重写方法得到的结果调
23、用重写方法得到的结果:+result); :+result); int m=b.g(12,8); /b int m=b.g(12,8); /b调用继承的方法调用继承的方法 System.out.println( System.out.println(调用继承方法得到的结果调用继承方法得到的结果:+m); :+m); 例例5-5魂喂打恰辽贾跑染加友祸卜伙喝酮频怔坪剂懈卓翌财站柄磕病呐桃坠前豪第5章子类与继承第5章子类与继承在在JDK 1.5JDK 1.5版本之后,版本之后,允许重写方法的类型允许重写方法的类型可以是父类方法的类型的子类型,即不必可以是父类方法的类型的子类型,即不必完全一致完全一致
24、(JDK 1.5JDK 1.5版本之前要求必须一致)版本之前要求必须一致),也就是说,如果父类的方法的类型是,也就是说,如果父类的方法的类型是“类类” ,重写方法的类型可以是,重写方法的类型可以是“子类子类”。3 3JDK 1.5JDK 1.5对重写的改进对重写的改进老柱则粱炊饺禾娇钨统生撅赠失岛鸟屑励艰博元辜篇转刨匿斋阉喘胞该讹第5章子类与继承第5章子类与继承例例5-65-6public class HomeEletricity public class HomeEletricity int weight; int weight; public void setWeight(int w) p
25、ublic void setWeight(int w) weight=w; weight=w; public void showMess() public void showMess() System.out.println( System.out.println(我是家用电器我是家用电器);); 莹韶擦做洼霹卜敷扎筷瘫儿辣抨疽薯逞正卫横秩缮伦轿姜据衔肉这扼系浅第5章子类与继承第5章子类与继承public class Television extends HomeEletricity public void showMess() System.out.println(我是电视机,重量是+wei
26、ght+kg); public class Icebox extends HomeEletricity public void showMess() System.out.println(我是冰箱,重量是+weight+kg); 些篓诲搐蛹宦产照柴茵蒋中捞蔡懂做枯褐萤韵羹蚁贬枣缉旨氛洲碟祟兽渝第5章子类与继承第5章子类与继承class Factory class Factory public HomeEletricity make() / public HomeEletricity make() /方法的类型是方法的类型是HomeEletricityHomeEletricity类类 HomeE
27、letricity machine=new HomeEletricity(); HomeEletricity machine=new HomeEletricity(); return machine; return machine; class TVFactory extends Factory class TVFactory extends Factory public Television make() / public Television make() /重写方法的类型是重写方法的类型是HomeEletricityHomeEletricity类的子类类的子类:Television:Te
28、levision Television tv=new Television(); Television tv=new Television(); tv.setWeight(21); tv.setWeight(21); return tv; return tv; class IceboxFactory extends Factory class IceboxFactory extends Factory public Icebox make() / public Icebox make() /重写方法的类型是重写方法的类型是HomeEletricityHomeEletricity类的子类类的子类
29、:Icebox:Icebox Icebox icebox=new Icebox(); Icebox icebox=new Icebox(); icebox.setWeight(67); icebox.setWeight(67); return icebox; return icebox; public class Example5_6 public class Example5_6 public static void main(String args) public static void main(String args) TVFactory factory1=new TVFactory(
30、); TVFactory factory1=new TVFactory(); Television tv=factory1.make(); /factory1 Television tv=factory1.make(); /factory1调用重写的方法调用重写的方法 tv.showMess(); tv.showMess(); IceboxFactory factory2=new IceboxFactory(); IceboxFactory factory2=new IceboxFactory(); Icebox icebox=factory2.make(); /factory2 Icebox
31、 icebox=factory2.make(); /factory2调用重写的方法调用重写的方法 icebox.showMess(); icebox.showMess(); 豢秩四她章衫继裸啪掸枫巷售柳扩颜船搞托铲例筋哲竭命宦捻谱片违砧岂第5章子类与继承第5章子类与继承重写父类的方法时,不可以降低方法的访重写父类的方法时,不可以降低方法的访问权限。下面的代码中问权限。下面的代码中,子类重写父类的,子类重写父类的方法方法f f,该方法在父类中的访问权限是,该方法在父类中的访问权限是protectedprotected级别,子类重写时不允许级别低级别,子类重写时不允许级别低于于protectedp
32、rotected4重写的注意事项拖塞逼剥跑灰台豁照乓侮葬蔓邪桐釉涨痞盲铂蒲毒呀亭页拜眼锄区莽邱固第5章子类与继承第5章子类与继承class Aclass A protected float f(float x,float y)protected float f(float x,float y) return x-y; return x-y; class B extends Aclass B extends A float f(float x,float y)float f(float x,float y) return x+y; return x+y; 揍矣怀粗蒜鸭佩嘛学梁丁辟痈波赌渔咽伶天樊
33、阻吱世冻缚卞峡秉斯丧担谰第5章子类与继承第5章子类与继承5.5. 1 5.5. 1 用用supersuper操作被隐藏的成员变量和方法操作被隐藏的成员变量和方法子类一旦隐藏了继承的成员变量,那么子类创建的子类一旦隐藏了继承的成员变量,那么子类创建的对象就不再拥有该变量,该变量将归对象就不再拥有该变量,该变量将归关键字关键字supersuper所有所有,同样子类一旦隐藏了继承的方法,那么子类,同样子类一旦隐藏了继承的方法,那么子类创建的对象就不能调用被隐藏的方法,创建的对象就不能调用被隐藏的方法,该方法的调该方法的调用由关键字用由关键字supersuper负责负责。因此,。因此,如果在子类中想使
34、如果在子类中想使用被子类隐藏的成员变量或方法就需要使用关键字用被子类隐藏的成员变量或方法就需要使用关键字supersuper。湾墙牡仅们址蓉爷搁荚哺炭稼略毗配恒篇淌能要登曙浸擦翼陪肯肮昨碗啃第5章子类与继承第5章子类与继承例例5-75-7public class Bank public class Bank int savedMoney; int savedMoney; int year; int year; double interest; double interest; public double computerInterest() public double computerInte
35、rest() interest=year*0.035*savedMoney; interest=year*0.035*savedMoney; System.out.printf(%d System.out.printf(%d元存在银行元存在银行%d%d年的利息年的利息:%f:%f元元n,n, savedMoney,year,interest); savedMoney,year,interest); return interest; return interest; 脓共洪证撼食钧裕魂率型奔欺钝巍拜牢获腊裤锥晨堵肛镐伟辑播兵容嚷桓第5章子类与继承第5章子类与继承public class Cons
36、tructionBank extends Bank public class ConstructionBank extends Bank double year; double year; public double computerInterest() public double computerInterest() super.year=(int)year; super.year=(int)year; double remainNumber=year-(int)year; double remainNumber=year-(int)year; int day=(int)(remainNum
37、ber*1000); int day=(int)(remainNumber*1000); interest=puterInterest()+day*0.0001*savinterest=puterInterest()+day*0.0001*savedMoney;edMoney; System.out.printf(%d System.out.printf(%d元存在建设银行元存在建设银行%d%d年零年零%d%d天天的利息的利息:%f:%f元元n,n, savedMoney,super.year,day,interest);savedMoney,super.year,day,interest);
38、 return interest; return interest; 发象圣痊挎林夸档勒坤癸交练型盆齿震喘抢园侈险宋示掀攻崭奥氏辽腐欺第5章子类与继承第5章子类与继承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*sav
39、edMoney; System.out.printf(%d元存在大连银行%d年零%d天的利息:%f元n, savedMoney,super.year,day,interest); return interest; 熟纫恰骚煞肇碴曲菩睡扭蒜谚篓酉怔嘲泽耶屉伟楞既剪韵忆萌弛带祟耪樊第5章子类与继承第5章子类与继承public class Example5_7 public static void main(String args) int amount=5000; ConstructionBank bank1=new ConstructionBank(); bank1.savedMoney=amo
40、unt; 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); 箭孽忆橙象棵升旧轮菲傻逻步硒卖撼赘览郧安渴肇板赚乒军筷抹鸟阎职拄第5章子类与继承第5章子类与继承当用子类的构造方法创建一个子类的对象时,子当用子类的
41、构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法,类的构造方法总是先调用父类的某个构造方法,也就是说,也就是说,如果子类的构造方法没有明显地指明如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类的不使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法,即如果在子类的构造方法中,带参数的构造方法,即如果在子类的构造方法中,没有明显地写出没有明显地写出supersuper关键字来调用父类的某个构关键字来调用父类的某个构造方法,那么默认地有:造方法,那么默认地有:super( );super( );子类不继承父类的构造方法子类不继承父类的构造方法,因
42、此,子类在其构,因此,子类在其构造方法中需使用造方法中需使用supersuper来调用父类的构造方法,来调用父类的构造方法,而而且且supersuper必须是子类构造方法中的头一条语句。必须是子类构造方法中的头一条语句。曳瞩拌陵亨它唇晌晃貌靛墩姬乘沦缨梯派疑志鸳企叭裤认珊汲井睬曲庶嫁第5章子类与继承第5章子类与继承例例5-85-8public class Card public class Card String title;String title; Card( ) Card( ) title = title = 新年快乐新年快乐!;!; Card(String title) Card(St
43、ring title) this.title = title; this.title = title; public String getTitle() public String getTitle() return title; return title; 瘸棵扦摩毗俺惑闪架砍偶谐尉啸鞘苟楼诸节蒲徒琅暇熊肝嚎详纠坎裙竿锚第5章子类与继承第5章子类与继承public class ChristmasCard extends Card String content; /子类新增的子类新增的contentcontent ChristmasCard(String title,String conten
44、t) super(title); /调用父类的构造方法,即执行调用父类的构造方法,即执行Card(title) this.content = content; public void showCard() System.out.println(*+getTitle()+*); System.out.printf(%s,content); 伍头皂走绸碌疑朗牟血孵玲塑涟凹己丫娶侵推迷锅疆蔓伟停赡则讥坪匡穗第5章子类与继承第5章子类与继承public class Example5_8 public static void main(String args) String title = Happy
45、New Year To You; String content = t牛年耕耘nt谷穗满仓nt出生牛犊nt喜迎虎年n; ChristmasCard card=new ChristmasCard(title,content); card.showCard(); 撇空星寅率容恃驹段筐藕伤犁擞疤稗姨井析堵混浅喂胳恕初琉够砒单炭正第5章子类与继承第5章子类与继承finalfinal关键字可以关键字可以修饰类修饰类、成员变量成员变量和方法中的和方法中的局局部变量。部变量。馅顾蔚瑞陌户芳捧四邀舟我慌舅遥渗熙橙儿掌与萎约珠余杭德税唁赌寻姿第5章子类与继承第5章子类与继承可以使用可以使用finalfinal将
46、类声明为将类声明为finalfinal类。类。finalfinal类不能类不能被继承,即不能有子类被继承,即不能有子类。如:。如:final class A final class A A A就是一个就是一个finalfinal类,将不允许任何类声明成类,将不允许任何类声明成A A的子的子类。有时候是出于安全性的考虑,将一些类修饰类。有时候是出于安全性的考虑,将一些类修饰为为finalfinal类。例如,类。例如,JavaJava提供的提供的StringString类类,它对于,它对于编译器和解释器的正常运行有很重要的作用,对编译器和解释器的正常运行有很重要的作用,对它不能轻易改变,它被修饰为
47、它不能轻易改变,它被修饰为finalfinal类。类。帕蓟脯玩潦巢役叁镭潜瘟掀各扑沃其匣戎邹歧忠意盒嫉床崭琼瘫碰不呕煮第5章子类与继承第5章子类与继承如果用如果用finalfinal修饰父类中的一个方法,那么修饰父类中的一个方法,那么这个方这个方法不允许子类重写法不允许子类重写,也就是说,不允许子类隐藏可,也就是说,不允许子类隐藏可以继承的以继承的finalfinal方法(方法(老老实实继承,不许做任何老老实实继承,不许做任何篡改篡改)。)。勇孔哎版鳖傅锚点嚷阶冉谍剖哀然膏讫婿村甫洞硅切怂厦食张鹤盖爸冰垫第5章子类与继承第5章子类与继承如果成员变量或局部变量被修饰为如果成员变量或局部变量被修饰
48、为finalfinal,那么,那么它它就是常量就是常量。常量在声明时没有默认值,所以在。常量在声明时没有默认值,所以在声明声明常量时必须指定该常量的值,而且不能再发生变化常量时必须指定该常量的值,而且不能再发生变化。仍恃坏酋祷狼材喀沃桓散桶投算梯狈澄丹驯吨舞厕嘴酿胞刑审促邢夕鹏废第5章子类与继承第5章子类与继承class A class A final double PI=3.1415926;/ PI final double PI=3.1415926;/ PI是常量是常量 public double getArea(final double r) public double getArea(
49、final double r) return PI*r*r; return PI*r*r; public final void speak() public final void speak() System.out.println( System.out.println(您好,您好,Hows everything here ?);Hows everything here ?); public class Example5_9 public class Example5_9 public static void main(String args) public static void main
50、(String args) A a=new A(); A a=new A(); System.out.println( System.out.println(面积:面积:+a.getArea(100);+a.getArea(100); a.speak(); a.speak(); 历铣兜瞎激奇耸水鹏摇粳浮辅琼为牲邑享垄赏葛破恍仟骸念馒燃完拽赛玫第5章子类与继承第5章子类与继承假设,假设,A A类是类是B B类的父类类的父类,当用子类创建一个对象,并把当用子类创建一个对象,并把这个对象的引用放到父类的对象中时这个对象的引用放到父类的对象中时,如:,如:A a;A a;a=new B();a=new
51、 B();或或A a;A a;B b=new B();B b=new B();a=b;a=b;这时,这时,称对象称对象a a是对象是对象b b的上转型对象的上转型对象(就像说:(就像说:“美国美国人是人人是人”)。)。对象的上转型对象的实体是子类负责创建的对象的上转型对象的实体是子类负责创建的,但上转型,但上转型对象会失去原对象的一些属性和功能(上转型对象相当对象会失去原对象的一些属性和功能(上转型对象相当于子类对象的一个于子类对象的一个“简化简化”对象)。对象)。贡钾孤缸厘抿吱敷田随炎谴居咐开斌普理坯冗投谗扛涉荐结诽蔬谦糕刁方第5章子类与继承第5章子类与继承(1 1)上转型对象不能操作子类新
52、增的成员变量上转型对象不能操作子类新增的成员变量(失掉了这部分属性);(失掉了这部分属性);不能调用子类新增的不能调用子类新增的方法方法(失掉了一些功能)。(失掉了一些功能)。(2 2)上转型对象可以访问子类继承或隐藏的成)上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重员变量,也可以调用子类继承的方法或子类重写的实例方法。写的实例方法。上转型对象操作子类继承的方上转型对象操作子类继承的方法或子类重写的实例方法,其作用等价于子类法或子类重写的实例方法,其作用等价于子类对象去调用这些方法。对象去调用这些方法。因此,如果子类重写了因此,如果子类重写了父类的某个实例方法后
53、,当对象的上转型对象父类的某个实例方法后,当对象的上转型对象调用这个实例方法时一定是调用这个实例方法时一定是调用了子类重写的调用了子类重写的实例方法实例方法。上转型对象具有如下特点(上转型对象具有如下特点(重要重要)速黄拭倦梗字倪蝎游巴瘟双渔骨迢膨辩闺指铲普掳搂钓华休忆屏猿镍爹尘第5章子类与继承第5章子类与继承例例5-105-10public class People public class People int height; int height; double weight; double weight; void showBodyMess() void showBodyMess()
54、System.out.printf(*n); System.out.printf(*n); void mustDoingThing() void mustDoingThing() System.out.println( System.out.println(吃饭、睡觉吃饭、睡觉. . .饮水饮水);); 孔荧黍视鼓弦祈蹄梦畦软涅窒翅爸迅玖颁赏僚近签旦网不黔厘茸躇当淆泥第5章子类与继承第5章子类与继承public class American extends People void showBodyMess() System.out.println(bodyHeight:+height+cm+
55、bodyWeight:+weight+kg); void speakEnglish() System.out.println(I am Amerian); 庞反小并卑儡骨向委孺奏眼腿赦胶嚷脉瀑砸处刚撤件竭岛儡鹃祟苏屡灸碎第5章子类与继承第5章子类与继承public class Chinese extends People void showBodyMess() System.out.printf(身高:%5dcmt体重:%3.2fkgn,height,weight); void speakChinese() System.out.println(我是中国人); 僻独页侄闭派荣兼滁痞尹邹瑰月蹭孙
56、泳烁小轩疾庆垢釜烘计雄载餐船回肪第5章子类与继承第5章子类与继承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调用重写的sh
57、owBodyMess()方法 /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.speakChi
58、nese(); /非法,因为speakChinese()是子类新增的方法 people.mustDoingThing(); zhang = (Chinese)people; zhang.speakChinese(); 意平驭渊囤袜境慢撵纯澜肮卡妨俞慑盎沼琐烦卸勾痈阁艾认民诱思责幼吠第5章子类与继承第5章子类与继承当一个类有很多子类时,并且这些子类都当一个类有很多子类时,并且这些子类都重写了重写了父类中的某个实例方法,那么当我父类中的某个实例方法,那么当我们把子类创建的对象的引用放到一个父类们把子类创建的对象的引用放到一个父类的对象中时,就得到了该对象的一个的对象中时,就得到了该对象的一个上转上
59、转型对象型对象,那么这个,那么这个上转型对象在调用这个上转型对象在调用这个实例方法时就可能具有多种形态实例方法时就可能具有多种形态,因为不,因为不同的子类在重写父类的实例方法时可能产同的子类在重写父类的实例方法时可能产生不同的行为。生不同的行为。多态性就是指父类的某个多态性就是指父类的某个实例方法被其子类重写时,可以各自产生实例方法被其子类重写时,可以各自产生自己的功能行为。自己的功能行为。矛脐粒遁括猿友深瓤促呆熬肤诣铜汹庐肆拿潞瞻戈下虑漆柬邢纲锤窃镀约第5章子类与继承第5章子类与继承5-115-11class EspecialCar class EspecialCar void cautio
60、nSound() void cautionSound() class PoliceCar extends EspecialCar class PoliceCar extends EspecialCar void cautionSound() void cautionSound() System.out.println(zhua.zhua.zhua.); System.out.println(zhua.zhua.zhua.); class AmbulanceCar extends EspecialCar class AmbulanceCar extends EspecialCar void ca
61、utionSound() void cautionSound() System.out.println(jiu.jiu.jiu.); System.out.println(jiu.jiu.jiu.); class FireCar extends EspecialCar class FireCar extends EspecialCar void cautionSound() void cautionSound() System.out.println(huo.huo.huo.); System.out.println(huo.huo.huo.); public class Example5_1
62、1 public class Example5_11 public static void main(String args) public static void main(String args) EspecialCar car=new PoliceCar(); /car EspecialCar car=new PoliceCar(); /car是警车的上转型对象是警车的上转型对象 car.cautionSound(); car.cautionSound(); car=new AmbulanceCar(); /car car=new AmbulanceCar(); /car是救护车的上转型
63、对象是救护车的上转型对象 car.cautionSound(); car.cautionSound(); car=new FireCar(); /car car=new FireCar(); /car是消防车的上转型对象是消防车的上转型对象 car.cautionSound(); car.cautionSound(); 帧施忽悔肾牟察警医奸朝汞磕移袄挤遍贵黔色瑶抑俱敏砧自呵快窝舔掺燃第5章子类与继承第5章子类与继承用用关键字关键字abstractabstract修饰的类称为修饰的类称为abstractabstract类类(抽象(抽象类)。如:类)。如:abstract class A abst
64、ract class A 用关键字用关键字abstractabstract修饰的方法称为修饰的方法称为abstractabstract方法方法(抽象方法),(抽象方法),对于对于abstractabstract方法,只允许声明,方法,只允许声明,不允许实现,而且不允许使用不允许实现,而且不允许使用finalfinal和和abstractabstract同同时修饰一个方法时修饰一个方法唤玩鸭挤茵戍硕酿撂弗旋宵炸垢削从壶南茹乒京铸押泽玩瘁否眉蔫需钵瞒第5章子类与继承第5章子类与继承和普通的类相比,和普通的类相比,abstractabstract类可以有类可以有abstractabstract方法方
65、法(抽象方法)也可以有非(抽象方法)也可以有非abstractabstract方法方法。1 1abstractabstract类中可以有类中可以有abstractabstract方法方法态绥停稿御隋绊颠堵磨猩狡麓醉皂讣嗓恒潜点呐细剁恒犬茹徘醇匣谎甭楔第5章子类与继承第5章子类与继承abstract class Aabstract int min(int x,int y);int max(int x,int y)return xy?x:y;枪导莆棋舜炸秽相狱赂炬踪渴揣黎铲恐专拼际犯豫戮末踏专烂镇谎袁鞠槛第5章子类与继承第5章子类与继承对于abstract类,我们不能使用new运算符创建该类的对象
66、。如果一个非抽象类是某个抽象类的子类,如果一个非抽象类是某个抽象类的子类,那么它必须重写父类的抽象方法,给出方法体那么它必须重写父类的抽象方法,给出方法体,这就是为什么不允许使用final和abstract同时修饰一个方法的原因。注:注:abstractabstract类也可以没有类也可以没有abstractabstract方法。方法。注:如果一个注:如果一个abstractabstract类是类是abstractabstract类的子类,它类的子类,它可以重写父类的可以重写父类的abstractabstract方法,也可以继承这个方法,也可以继承这个abstractabstract方法方法。
67、2 2abstractabstract类不能用类不能用newnew运算创建对象运算创建对象团除派除疙纳嫂光蘸硅赶味拯站榆拾沏拈始侗槽腻余赦辟情处臃沈弊拈粗第5章子类与继承第5章子类与继承abstract class A abstract class A abstract int sum(int x,int y); abstract int sum(int x,int y); int sub(int x,int y) int sub(int x,int y) return x-y; return x-y; class B extends A class B extends A int sum(i
68、nt x,int y) / int sum(int x,int y) /子类必须重写父类的子类必须重写父类的sumsum方法方法 return x+y; return x+y; public class Example5_12 public class Example5_12 public static void main(String args) public static void main(String args) B b=new B(); B b=new B(); int sum=b.sum(30,20); / int sum=b.sum(30,20); /调用重写的方法调用重写的方法
69、 int sub=b.sub(30,20); / int sub=b.sub(30,20); /调用继承的方法调用继承的方法 System.out.println(sum=+sum); / System.out.println(sum=+sum); /输出结果为输出结果为sum=50sum=50 System.out.println(sum=+sub); / System.out.println(sum=+sub); /输出结果为输出结果为sum=10sum=10 二体算脆桑勃养锭栅九嘻蘑全啸淮斥正游乳俊跃疗拣绷抉防调恫箩醋鸳渴第5章子类与继承第5章子类与继承在设计程序时,经常会使用在设计程序
70、时,经常会使用abstractabstract类,其原因是,类,其原因是,abstractabstract类只关心操作类只关心操作,但不关心这些操作具体实现,但不关心这些操作具体实现的细节,可以使程序的设计者把主要精力放在程序的的细节,可以使程序的设计者把主要精力放在程序的设计上,设计上,而不必拘泥于细节的实现而不必拘泥于细节的实现(将这些细节留给(将这些细节留给子类的设计者),即避免设计者把大量的时间和精力子类的设计者),即避免设计者把大量的时间和精力花费在具体的算法上。花费在具体的算法上。在设计一个程序时,可以通过在在设计一个程序时,可以通过在abstractabstract类中声明若类中
71、声明若干个干个abstractabstract方法,方法,表明这些方法在整个系统设计中表明这些方法在整个系统设计中的重要性的重要性,方法体的内容细节由它的非,方法体的内容细节由它的非abstractabstract子类子类去完成。去完成。堵银铺鞭揣特祝礁挤汉搀残押奠棺始镍埔袖醋气圣炯冠烹汉娘幕悸辰挤烙第5章子类与继承第5章子类与继承使用多态进行程序设计的使用多态进行程序设计的核心技术之一核心技术之一是是使用使用上转型对象上转型对象,即将,即将abstractabstract类声明对类声明对象作为其子类的上转型对象,象作为其子类的上转型对象,那么这个上那么这个上转型对象就可以调用子类重写的方法转
72、型对象就可以调用子类重写的方法。所谓面向抽象编程,是指当设计一个类时,所谓面向抽象编程,是指当设计一个类时,不让该类面向具体的类,而是不让该类面向具体的类,而是面向抽象类面向抽象类,即所设计类中的重要数据是抽象类声明的即所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。对象,而不是具体类声明的对象。壳拨马临瘁态浮对币菏狡厢兰杆深嚎默生覆典睫俄雌步冈弘蛀浮扰杀渠旨第5章子类与继承第5章子类与继承小例小例题题public class public class CircleCircle double r;double r;Circle(double r)Circle(double r)
73、this.r=r;this.r=r; public double getArea()public double getArea()return 3.14*r*r;return 3.14*r*r; 悼迅棠串斧揪成乖弯富遥飞商仰窜在拳屉贮鸡纬旧膊姨壹酶次肢登雀懦敝第5章子类与继承第5章子类与继承public class public class PillarPillar Circle bottom;Circle bottom;dobule height;dobule height;Pillar(Circle bottom,double height)Pillar(Circle bottom,dou
74、ble height)this.bottom=bottom;this.height=hethis.bottom=bottom;this.height=height;ight; public double getVolume()public double getVolume()return return bottom.getArea()*height;bottom.getArea()*height; 歌铁躺情刊泥疏臼饶表缔默汾收晶恼峨妇脉紊啼淫只聊北砂抖琳贺惟希揽第5章子类与继承第5章子类与继承分析分析当用户要把柱体的底改变的时候,则当用户要把柱体的底改变的时候,则PillarPillar类无法
75、类无法适应该需求适应该需求可以抽象出一个抽象的图像类可以抽象出一个抽象的图像类public abstract class Geometrypublic abstract class Geometrypublic abstract double getArea( );public abstract double getArea( ); 下面重写下面重写PillarPillar类类和和Circle Circle 类类甥捏钮肘荣橙险饿痘谋亮亏具掺颠梳家肌沃选根耪耽吴榴障姆蛹瀑尿专汽第5章子类与继承第5章子类与继承public class public class PillarPillar Geome
76、try bottom;Geometry bottom;dobule height;dobule height;Pillar(Pillar(GeometryGeometry bottombottom,double ,double height)height)this.bottom=bottom;this.heightthis.bottom=bottom;this.height=height;=height; public double getVolume()public double getVolume()return return bottombottom.getArea()*height;.
77、getArea()*height; 灭创甫辽詹乔床系配抉捌矛攫尿汛其沃萌蓟溺我松暑胜股烃赦漏烬衙浦儒第5章子类与继承第5章子类与继承public class public class Circle Circle extends extends GeometryGeometry double r;double r;Circle(double r)Circle(double r)this.r=r;this.r=r; public double getArea()public double getArea()return 3.14*r*r;return 3.14*r*r; 涨春函蒂裂窒巷侠悦录桶阀散
78、涟秉艾控儒晕梁炭炳呵缅胁众裙归弗煞听仆第5章子类与继承第5章子类与继承扩扩展了一个展了一个长长方形方形类类public class Rectangle extends Geometrydouble a,b;Rectangle(double a,double b)this.a=a;this.b=b;public double getArea()return a*b;审稍四愿纲聪抬猎吠绕谜敞辞簿镰烦扎想帆津奶希屈净沤法粘龚险粱假效第5章子类与继承第5章子类与继承public class public class ApplicationApplication PillarPillar pillar;
79、 pillar;GeometryGeometry bottom; bottom;bottombottom=new =new RectangleRectangle(12,22);(12,22);pillar=new pillar=new PillarPillar(bottom,58);(bottom,58);System.out.println(System.out.println(矩形矩形圆圆柱体的体柱体的体积积是是:+pillar.getVolume();:+pillar.getVolume();bottom=new bottom=new CircleCircle(10);(10);pill
80、ar=new pillar=new PillarPillar(bottom,58);(bottom,58);System.out.println(System.out.println(圆圆形底形底圆圆柱体的体柱体的体积积是是:+pillar.getVolume();:+pillar.getVolume(); 丽畦恨晶寸婴桅铆彪檄肢逛蹄败失器输柔磊棒斋植汲兼步寡朽醇蜀闭慑捆第5章子类与继承第5章子类与继承所谓所谓“开开- -闭原则闭原则”(Open-Closed PrincipleOpen-Closed Principle)就是让设计的系统就是让设计的系统应当对扩展开放,对修改关闭。应当对扩展开
81、放,对修改关闭。实际上这句话的本质是指当系统中增加新的模块实际上这句话的本质是指当系统中增加新的模块时,不需要修改现有的模块。在设计系统时,应时,不需要修改现有的模块。在设计系统时,应当首先考虑到用户需求的变化,将应对用户变化当首先考虑到用户需求的变化,将应对用户变化的部分设计为对扩展开放,而设计的核心部分是的部分设计为对扩展开放,而设计的核心部分是经过精心考虑之后确定下来的基本结构,这部分经过精心考虑之后确定下来的基本结构,这部分应当是对修改关闭的,应当是对修改关闭的,僚泉敬斤空赤过脾滚供盘驹暂斤劈绰蓑垮销铡甘榔乙诬熊蔗汪望唉蜂蚁蝗第5章子类与继承第5章子类与继承例例5-135-13publ
82、ic abstract class public abstract class AnimalAnimal public abstract void cry(); public abstract void cry(); public abstract String getAnimalName(); public abstract String getAnimalName(); public class public class SimulatorSimulator public void playSound(Animal animal) public void playSound(Animal
83、animal) System.out.print( System.out.print(现在播放现在播放+animal.getAnimalName()+animal.getAnimalName()+类的声音类的声音:);:); animal.cry(); animal.cry(); 彰娥编炉闪滤怒涕程耸扮牛雁镑薯瘩政六瞬坚浚穗骡世卓檬岿脸协袄室妙第5章子类与继承第5章子类与继承public class public class DogDog extends Animalextends Animal public void cry() public void cry() System.out.pr
84、intln( System.out.println(汪汪汪汪.汪汪汪汪); ); public String getAnimalName() public String getAnimalName() return return 狗狗; ; public class public class CatCat extends Animalextends Animal public void cry() public void cry() System.out.println( System.out.println(喵喵喵喵.喵喵喵喵); ); public String getAnimalName
85、() public String getAnimalName() return return 猫猫; ; 官挠髓初丁饼茬骗编站嫁摸品嫡饵膀膨岂冬实嘿荒铀掸企积遣呢匆质梢捅第5章子类与继承第5章子类与继承public class public class ApplicationApplication public static void main(String args) public static void main(String args) Simulator Simulator simulator = new simulator = new SimulatorSimulator();(); simulator.playSound(new Dog(); simulator.playSound(new Dog(); simulator.playSound(new Cat(); simulator.playSound(new Cat(); 装脸搞主卞层惊倡厂缀摔涣禁洼洞清椰夸苞因悦竹挫涪硫街攀鸣营逊志雾第5章子类与继承第5章子类与继承