c++第7章 抽象类和接口_第1页
c++第7章 抽象类和接口_第2页
c++第7章 抽象类和接口_第3页
c++第7章 抽象类和接口_第4页
c++第7章 抽象类和接口_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

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

文档简介

1、抽象类和接口同济大学同济大学孙丽君孙丽君抽象类抽象类接口接口7.1抽象类语法:语法:public public abstractabstract class/ class/抽象类抽象类abstract abstract void void testAbstrcttestAbstrct();/();/抽象方法抽象方法 使用使用abstractabstract关键字定义关键字定义的方法称为抽象方法,的方法称为抽象方法,抽象方法抽象方法没有方法体没有方法体使用使用abstractabstract关键字定义的类称为抽象关键字定义的类称为抽象类,类,承载承载了抽象方了抽象方法的法的类必须定义为抽象类类必

2、须定义为抽象类。例例:7-7 7-7 抽象类抽象类class class abstract abstract GeometricObjectGeometricObject /定义父定义父类,抽象类类,抽象类private String color=white;private String color=white;private private booleanboolean filled; filled;private private java.util.Datejava.util.Date dateCreateddateCreated; ;GeometricObjectGeometricObj

3、ect(String (String color,booleancolor,boolean filled) filled)/构造方法构造方法this.colorthis.color=color;=color;this.filledthis.filled=filled;=filled;dateCreateddateCreated=new =new java.util.Datejava.util.Date();();String String getColorgetColor() /() /获取私有的数据成员获取私有的数据成员 return color;return color;booleanbo

4、olean getfilledgetfilled()() return filled;return filled;java.util.Datejava.util.Date getCreatedDategetCreatedDate()() return return dateCreateddateCreated;a abstract double bstract double getAreagetArea(); /(); /抽象方法抽象方法abstract double abstract double getPerimetergetPerimeter(); /(); /抽象方法抽象方法 注意:注

5、意: 抽象方法抽象方法没有方法体没有方法体, ,它的它的实现在子类中实现在子类中。 包含了抽象方法的类必须定义成抽象包含了抽象方法的类必须定义成抽象类,类,抽象类必须被继承抽象类必须被继承class Circle extends class Circle extends GeometricObjectGeometricObject private double radiusprivate double radius;/;/新增数新增数据成员据成员Circle(double Circle(double radius,Stringradius,String color,booleancolor,b

6、oolean filled filled)/)/子类构子类构造方法造方法super(super(color,filledcolor,filled););this.radiusthis.radius=radius;=radius;/新增成员方法新增成员方法public double public double getAreagetArea()()return return Math.Math.PIPI* *radiusradius* *radius;radius; public double public double getPerimetergetPerimeter()()return 2re

7、turn 2* *radiusradius* *Math.Math.PIPI; class Rectangle extends class Rectangle extends GeometricObjectGeometricObject private double private double width,heightwidth,height; ;Rectangle(double Rectangle(double w,doublew,double h,Stringh,String color,booleancolor,boolean filled) filled)super(super(co

8、lor,filledcolor,filled);/);/调用父类构造调用父类构造方法方法width=width=w;heightw;height=h=h;public double public double getAreagetArea()()return widthreturn width* *height;height; public double public double getPerimetergetPerimeter()()return 2return 2* *( (width+heightwidth+height);); 和上例和上例7-67-6中的定义相同中的定义相同publ

9、ic class Exp7_7 public class Exp7_7 public public static void static void dispObjectdispObject( (GeometricObjectGeometricObject geoObjgeoObj) System.System.out.printlnout.println(color is:+(color is:+geoObj.getColorgeoObj.getColor()+ filled ()+ filled is:+is:+geoObj.getfilledgeoObj.getfilled()+ crea

10、ted on:+()+ created on:+geoObj.getCreatedDategeoObj.getCreatedDate();(); System.System.out.printlnout.println(“area (“area isis:”+:”+geoObj.getAreageoObj.getArea()();); System.System.out.printlnout.println(perimeter is:+(perimeter is:+geoObj.getPerimetergeoObj.getPerimeter();(); public static void m

11、ain(String public static void main(String argsargs) ) GeometricObjectGeometricObject geoObj1=new Circle(5,“yello”,true geoObj1=new Circle(5,“yello”,true);/);/创建子创建子类对象,类型是类对象,类型是GeometricObjectGeometricObject GeometricObjectGeometricObject geoObj2=new Rectangle(5,10,blue,false); geoObj2=new Rectangl

12、e(5,10,blue,false); dispObjectdispObject(geoObj1); /(geoObj1); /显示园的信息显示园的信息 dispObjectdispObject(geoObj2);/(geoObj2);/显示矩形的信息显示矩形的信息 注意:注意:抽象抽象类不能用类不能用new new 创建创建对象对象GeometricObjectGeometricObject geoObj1=new geoObj1=new GeometricObjectGeometricObject(“(“yelloyello”,true) ”,true) /错误错误但但可引用子可引用子类的

13、类的对象对象 GeometricObjectGeometricObject geoObj1=new Circle(5,“yello”, geoObj1=new Circle(5,“yello”,truetrue) /正确正确说明:说明: 由于使用了抽象类,在父类中定义了抽象方法,由于使用了抽象类,在父类中定义了抽象方法,abstract double abstract double getAreagetArea(); (); abstract abstract double double getPerimetergetPerimeter(); (); 使得在使得在dispObjectdispO

14、bject( (GeometricObjectGeometricObject geoObjgeoObj) )方法中显示面积和周长成为方法中显示面积和周长成为可能,不再需要向下转型可能,不再需要向下转型 JVMJVM根据传递给根据传递给dispObjectdispObject( (GeometricObjectGeometricObject geoObjgeoObj) )方法的参数的方法的参数的类类型动态决定调用型动态决定调用哪个子类中哪个子类中getAreagetArea()()和和getPerimetergetPerimeter()()的方法的方法 dispObjectdispObject(

15、geoObj1(geoObj1); /); /显示园的信息显示园的信息 dispObjectdispObject(geoObj2(geoObj2);/);/显示矩形的显示矩形的信息信息抽象类小结在类在类的设计中,为确保父类包含它的子类的共同特征,一的设计中,为确保父类包含它的子类的共同特征,一般可将父类定义为抽象类,使用这个父类进行继承和多态般可将父类定义为抽象类,使用这个父类进行继承和多态处理处理抽象类必须被继承,被继承后需要实现其抽象类必须被继承,被继承后需要实现其所有所有的抽象方法,的抽象方法,保证方法名称、参数列表、返回值类型保证方法名称、参数列表、返回值类型相同相同继承树中,越往上面

16、的类越抽象继承树中,越往上面的类越抽象。父父类可以定义的非常抽象,以至于可以没有任何方法的实类可以定义的非常抽象,以至于可以没有任何方法的实现现7.2 接口JavaJava语言不支持多重继承,即一个子类只能有一个父类,若子类需要继承语言不支持多重继承,即一个子类只能有一个父类,若子类需要继承多个父类,这时需要使用接口。多个父类,这时需要使用接口。1、接口的定义:语法语法:public ipublic interface nterface 接口名接口名 / / 常量;常量;/抽象方法;抽象方法; 例:例: public interface public interface CalInterfac

17、eCalInterface final float PI = 3.14159f;/ final float PI = 3.14159f;/ 定义用于表示圆周率的常定义用于表示圆周率的常PIPIfloat float getAreagetArea(float r);/ (float r);/ 定义一个用于计算面积的方法定义一个用于计算面积的方法getAreagetArea()()/ / 定义一个用于计算周长方法定义一个用于计算周长方法getCircumferencegetCircumference()()float float getCircumferencegetCircumference(f

18、loat r);(float r); 说明:接口有与接口有与类相似的结构,类相似的结构,只包含常量和只包含常量和抽象方法抽象方法修饰符修饰符:可选,用于指定接口的访问权限,可选值有:可选,用于指定接口的访问权限,可选值有publicpublic,表示任意类均可以使用这个接口。如果省略则使用默认的访问表示任意类均可以使用这个接口。如果省略则使用默认的访问权限,即只有与该接口定义在同一包中的类才可以访问这个接权限,即只有与该接口定义在同一包中的类才可以访问这个接口。口。接口名接口名:必选参数,用于指定接口的名称,接口名必须是合法:必选参数,用于指定接口的名称,接口名必须是合法的的JavaJava语

19、言标识符。一般情况下,要求首字母大写。语言标识符。一般情况下,要求首字母大写。 extendsextends 父父接口名列表接口名列表:可选参数,用于指定要定义的接口:可选参数,用于指定要定义的接口继承于哪个父接口。当使用继承于哪个父接口。当使用extendsextends关键字时,父接口名为必关键字时,父接口名为必选参数。当有多个父类接口时,用逗号选参数。当有多个父类接口时,用逗号“,”分隔。分隔。成员变量的声明形式如下:成员变量的声明形式如下: 即接口中的成员变量都是即接口中的成员变量都是publicpublic权限的权限的staticstatic常量,常量,正因为如此,正因为如此,pub

20、licpublic、staticstatic和和finalfinal都可以省去。都可以省去。成员方法的声明形式如下:成员方法的声明形式如下: 省略省略权限修饰符,它也是权限修饰符,它也是publicpublic abstractabstract,没有方,没有方法体法体与与JavaJava的类文件一样,接口文件的文件名必须的类文件一样,接口文件的文件名必须与与public public 修饰的接口修饰的接口名相同名相同。2 2、接口的实现一个类可以实现接口一个类可以实现接口public class public class 类名类名 extends extends 父类名父类名 implemen

21、ts implements 接接口名口名 或或public class public class 类名类名 extends extends 父类名父类名 implements implements 接口接口1 1,接口,接口2 2,接口,接口n n 在类中实现接口时,方法的名字、返回值类型、参数的个数及类型必须与在类中实现接口时,方法的名字、返回值类型、参数的个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法。接口中的完全一致,并且必须实现接口中的所有方法。/7-8-1 calInterface.java/7-8-1 calInterface.javapublic public i

22、nterface interface CalInterfaceCalInterface final float PI = 3.14159f;/ final float PI = 3.14159f;/ 定义用于表示圆周率的常定义用于表示圆周率的常PIPIfloat float getAreagetArea(float r);/ (float r);/ 定义一个用于计算面积的方法定义一个用于计算面积的方法getAreagetArea()()/ / 定义一个用于计算周长方法定义一个用于计算周长方法getCircumferencegetCircumference()()float float getC

23、ircumferencegetCircumference(float r);(float r); /cire.java/cire.javapublic public class class CireCire implements implements CalInterfaceCalInterface public float public float getAreagetArea(float r) (float r) float area = PI float area = PI * * r r * * r;/ r;/ 计算圆面积并赋值给变量计算圆面积并赋值给变量areaareareturn

24、area;/ return area;/ 返回计算后的圆面积返回计算后的圆面积 public float public float getCircumferencegetCircumference(float r) (float r) float float circumference = 2 circumference = 2 * * PI PI * * r; / r; / 计算圆周长并赋值给计算圆周长并赋值给变量变量circumferencecircumferencereturn circumference; / return circumference; / 返回计算后的圆周长返回计算后

25、的圆周长 public static void main(String public static void main(String argsargs) ) CireCire c = new c = new CireCire();();float f = float f = c.getAreac.getArea(2.0f(2.0f););System.out.printlnSystem.out.println( (Float.Float.toStringtoString(f(f););例7-8 7-8 :interfaceinterface drawTestdrawTest / /定义接口定义

26、接口public void draw();public void draw(); class Rectangle extends class Rectangle extends QuadrangQuadrang implementsimplements drawTestdrawTest public void draw()public void draw() System.System.out.printlnout.println(矩矩形形.draw();.draw(); class Square extends class Square extends QuadrangQuadrang im

27、plementsimplements drawTestdrawTest public void draw()public void draw() System.System.out.out.printlnprintln(正方正方形形.draw();.draw(); public class public class QuadrangQuadrang public public static void main(String static void main(String argsargs) ) /接口也可以定义接口也可以定义数组数组drawTestdrawTest d=new Rectangl

28、e(),new d=new Rectangle(),new SquareSquare(); /(); /向上转型为向上转型为drawTestdrawTest接口接口for(for(intint i i=0;i=0;id.length;id.length;i+)+)ddi i.draw.draw(); /(); /执行时,执行时,JVMJVM根据根据ddi i 的实际类型决定调用那个子类的的实际类型决定调用那个子类的draw()draw()方法方法说明:说明:接口指明多个对象的共同接口指明多个对象的共同特性,在接口中定义的方特性,在接口中定义的方法,可在不同的类中有不法,可在不同的类中有不同的实

29、现同的实现。小结接口接口指明指明多个对象的共同多个对象的共同特性特性, ,接口接口中只包含方法和常量值的定义,没有变量和方法的实中只包含方法和常量值的定义,没有变量和方法的实现,是一种特殊的抽象类现,是一种特殊的抽象类。在在接口中定义的方法,可在不同的类中有不同的实现。接口中定义的方法,可在不同的类中有不同的实现。并且并且这些实现可以具有不同的行为(功能)这些实现可以具有不同的行为(功能)。即即每个每个实现接口的类可以根据各自要求,具体实现接口中声实现接口的类可以根据各自要求,具体实现接口中声明的方法。因此这些方法在实现接口的各类中表现出多态性明的方法。因此这些方法在实现接口的各类中表现出多态

30、性。抽象类与接口变量变量构造方法构造方法方法方法抽象类抽象类无限制无限制子类通过构造方法链调用构子类通过构造方法链调用构造方法造方法不能通过不能通过newnew运算符实例化运算符实例化无限制无限制接口接口只能是只能是public public static static finalfinal没有构造方法,接口不能使没有构造方法,接口不能使用用newnew运算符实例化运算符实例化所有方法必须是公共的所有方法必须是公共的抽象实例方法抽象实例方法 抽象类和接口都是用来明确多个对象的共同特征的抽象类和接口都是用来明确多个对象的共同特征的 一般来讲,描述父子关系的强是关系(一般来讲,描述父子关系的强是关

31、系(is ais a,例如系主任是教师),例如系主任是教师),用类建模,用类建模, 描述类属关系的弱是关系(对象拥有某种属性,例如字符串是可比较描述类属关系的弱是关系(对象拥有某种属性,例如字符串是可比较的),用接口建模的),用接口建模例9-12接口可以定义不相关类的共有父类型,比类更加灵活接口可以定义不相关类的共有父类型,比类更加灵活/animal.java/animal.javaabstract abstract class Animal class Animal public public abstract String abstract String howToEathowToEat(

32、);(); /Chicken.java/Chicken.javapublic public class Chicken extends class Chicken extends Animal Animal public public String String howToEathowToEat()() return return Fry it;Fry it; /Duck.java/Duck.javapublic public class Duck extends class Duck extends AnimalAnimal public public String String howTo

33、EathowToEat()() return return Roast it;Roast it; /TestAbstract.java/TestAbstract.javapublic public class class TestAbstrctTestAbstrct public static void eat(Animal public static void eat(Animal animal)animal) String String s=s=animal.howToEatanimal.howToEat();(); System.System.out.printlnout.println

34、(s(s);); public static void public static void main(String main(String argsargs) ) Animal Animal animal=new animal=new Chicken();Chicken(); eat(animal eat(animal);); animal=new animal=new Duck();Duck(); eat(animal eat(animal);); /Edible.java/Edible.javapublic interface Edible public interface Edible

35、 public public String String howToEathowToEat();(); /Chicken.java/Chicken.javapublic class Chicken implements Ediblepublic class Chicken implements Edible public public String String howToEathowToEat()() return return Fry it;Fry it; /Duck.java/Duck.javapublic class Duck implements Ediblepublic class

36、 Duck implements Edible public public String String howToEathowToEat()() return return Roast it;Roast it; public class Broccoli implements Ediblepublic class Broccoli implements Edible public public String String howToEathowToEat()() return return stir-Fry it;stir-Fry it; public class public class T

37、estInterfaceTestInterface public static void main(String public static void main(String argsargs)Edible stuff=new Chicken();Edible stuff=new Chicken();eat(stuff);eat(stuff);stuff=new Duck();stuff=new Duck();eat(stuff);eat(stuff);stuff=new Broccoli();stuff=new Broccoli();eat(stuff);eat(stuff); public

38、 static void eat(Edible public static void eat(Edible stuff)stuff)String s=String s=stuff.howToEatstuff.howToEat();();System.System.out.printlnout.println(s);(s); 3 3、接口应用举例例例7-97-9/定义接口:定义接口:interface Fight interface Fight void fight(); void fight(); /小胖和小瘦去实现这个接口:小胖和小瘦去实现这个接口:class class xiaopangx

39、iaopang implements Fight implements Fight public void fight() public void fight() System.out.printlnSystem.out.println(小胖打人很痛小胖打人很痛!);!); class class xiaoshouxiaoshou implements Fight implements Fight public void fight() public void fight() System.out.printlnSystem.out.println(小瘦打人一点都不痛!小瘦打人一点都不痛!);

40、); public class InterfaceTest1public class InterfaceTest1public public static void main(String static void main(String argsargs) ) Fight Fight a = new a = new xiaopangxiaopang();/();/向上转型为父接口向上转型为父接口 Fight Fight b = new b = new xiaoshouxiaoshou();(); a.fighta.fight();(); b.fightb.fight();(); 运行结果:运行

41、结果:小胖打人很痛小胖打人很痛! !小瘦打人一点都不痛!小瘦打人一点都不痛!例例7-107-10/定义接口定义接口interface charge interface charge public void public void aircondition_costaircondition_cost();(); interface temperature interface temperature public void public void controlTemperaturecontrolTemperature();(); /实现接口实现接口class class Taxi Taxi im

42、plements charge, temperature implements charge, temperature public void public void aircondition_costaircondition_cost() () System.System.out.printlnout.println(出租车:出租车:1.601.60元每千米,起价元每千米,起价3 3千米千米);); public void public void controlTemperaturecontrolTemperature() () System.System.out.printlnout.pr

43、intln(安装了海尔空调安装了海尔空调);); class Cinema class Cinema implements charge, temperature implements charge, temperature public void public void aircondition_costaircondition_cost() () System.System.out.printlnout.println(电影院:门票,电影院:门票,1010元每张元每张);); public void public void controlTemperaturecontrolTemperat

44、ure() () System.System.out.printlnout.println(安装了中央空调安装了中央空调);); /测试接口public class TestInterface2 public class TestInterface2 public static void main(String public static void main(String argsargs) ) Taxi Taxi taxi1 = new Taxi();taxi1 = new Taxi(); Cinema Cinema cinema1 = new Cinema();cinema1 = new

45、Cinema(); taxi1.aircondition_cost taxi1.aircondition_cost();(); cinema1.aircondition_cost cinema1.aircondition_cost();(); taxi1.controlTemperature taxi1.controlTemperature();(); cinema1.controlTemperature cinema1.controlTemperature();();运行结果:运行结果:出租车:出租车:1.601.60元每千米,起价元每千米,起价3 3千米千米电影院:门票,电影院:门票,10

46、10元每张元每张安装了海尔空调安装了海尔空调安装了中央空调安装了中央空调4、扩展接口和多重继承与类一样,接口也可以使用与类一样,接口也可以使用extendsextends子句扩展接口子句扩展接口,生成子接口,生成子接口。例如:例如:Interface A extends B.Interface A extends B.这条语句表示定义了接口这条语句表示定义了接口A A并继承了接口并继承了接口B B,使,使A A成为成为B B的子的子接口接口接口接口B B称为称为基本基本接口接口(base interfacebase interface)或父接口或父接口(super super interfac

47、einterface),扩展出的),扩展出的接口接口A A称为称为派生接口或子接口派生接口或子接口。通过通过扩展扩展,派生接口不仅可以保有父接口的成员,同时也可以加入新,派生接口不仅可以保有父接口的成员,同时也可以加入新的成员以满足实际问题的需求。的成员以满足实际问题的需求。与类不同的一点就是,与类不同的一点就是,一个接口可以扩展多个接口一个接口可以扩展多个接口,继承它们所有的,继承它们所有的属性,而一个类属性,而一个类只能只能扩展一个类。扩展一个类。BabyBaby接口继承了接口继承了FatherFather、MotherMother两个接口中所有的方法与常量,并增加两个接口中所有的方法与常

48、量,并增加了一个了一个cry()cry()方法,所以在方法,所以在BabyBaby接口中有如下这些常量和抽象方法:接口中有如下这些常量和抽象方法:int age=40;int age=40;long Bankaccount=10000;long Bankaccount=10000;void cook();void cook();void wash();void wash();void cry();void cry();例interface Father int age=40; void wash();interface Mother long Bankaccount=10000; void c

49、ook();interface Baby extends Father,Mother void cry();如果FatherFather、MotherMother两个接口中有重名的方法或常量怎么办?1. 1. 方法重名方法重名如果两个方法一模一样,那么保留一个。因为接口中的方法都是抽象如果两个方法一模一样,那么保留一个。因为接口中的方法都是抽象的,没有实现,所以当两个方法参数个数和类型以及返回值相同时,的,没有实现,所以当两个方法参数个数和类型以及返回值相同时,不存在选择哪一个的问题。不存在选择哪一个的问题。如果重名的两个方法有不同的参数个数或者类型,那么在如果重名的两个方法有不同的参数个数或

50、者类型,那么在BabyBaby接口中接口中两个方法都有,即方法被重载。两个方法都有,即方法被重载。如果两个方法仅在返回类型上不同,那会产生一种无法实现的错误。如果两个方法仅在返回类型上不同,那会产生一种无法实现的错误。2. 2. 常量重名常量重名两个重名常量都保留,使用原来的接口名字作为前缀。两个重名常量都保留,使用原来的接口名字作为前缀。例如,如果例如,如果MontherMonther接口中也有接口中也有“Int age=38;Int age=38;”,javajava要求必须要求必须写明写明Mother.ageMother.age或或F Father.ageather.age。例例7-12

51、7-12常量重名实例。常量重名实例。程序运行结果为:201/Inter1.java/Inter1.javapublic public interface Inter1 interface Inter1 public static final public static final intint A = 0;A = 0; /Inter2 .java/Inter2 .javapublic interface Inter2 public interface Inter2 intint A = 1;A = 1; intint B = 2;B = 2; /Test.java/Test.javaclass class Test implements Inter1, Inter2 Test implements Inter1, Inter2 /ConstentTest.java/ConstentTest.javapublic class public class ConstantTestConstantTest

温馨提示

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

评论

0/150

提交评论