版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第4 4章章 继承与多态继承与多态 利用继承,可以基于已经存在的类构造新类,还利用继承,可以基于已经存在的类构造新类,还可以在新类中添加一些新的成员或修改继承了的可以在新类中添加一些新的成员或修改继承了的成员,以满足新的需求。成员,以满足新的需求。 而多态是在继承的基础上引出的,可以解决子类而多态是在继承的基础上引出的,可以解决子类父类中的成员重名问题。父类中的成员重名问题。为什么需要继承?为什么需要继承?以下解决方案中有什么问题?以下解决方案中有什么问题?如何解决?4.1 4.1 继继 承承 概概 述述 利用继承可以很好地实现代码重用问题。利用继承可以很好地实现代码重用问题。 在利用已有的
2、类构造新类时,新类保留已有类的在利用已有的类构造新类时,新类保留已有类的属性和行为,并可以根据要求添加新的属性和行属性和行为,并可以根据要求添加新的属性和行为。为。 例如,卡车具有一般汽车的属性,而特有的属性例如,卡车具有一般汽车的属性,而特有的属性就是载货。就是载货。 曾经介绍过类之间的关系:曾经介绍过类之间的关系:“USES-A”USES-A”关系、关系、“HAS-A”HAS-A”关系、关系、“IS-A”IS-A”关系。关系。其中,其中,“IS-A”IS-A”关系是继承的一个特征。关系是继承的一个特征。4.1.1 4.1.1 超类、子类超类、子类 被继承的类一般称为被继承的类一般称为“超类
3、超类”或或“父类父类”,继承,继承的类称为的类称为“子类子类”。 当子类继承超类时,不必写出全部的实例变量和当子类继承超类时,不必写出全部的实例变量和方法,只需声明该类继承了的已定义的超类的实方法,只需声明该类继承了的已定义的超类的实例变量和方法即可。例变量和方法即可。 继承节省了定义新类的大量工作,可以方便地重继承节省了定义新类的大量工作,可以方便地重用代码用代码。 但一个子类不必非要使用继承下来的属性和方法,但一个子类不必非要使用继承下来的属性和方法,一个子类可以选择覆盖已有的属性和方法,或添一个子类可以选择覆盖已有的属性和方法,或添加新的属性和方法。加新的属性和方法。4.1.2 4.1.
4、2 继承层次继承层次 继承关系可以用树形层次表达出来。继承关系可以用树形层次表达出来。 为汽车类的继承层次关系,注意,汽车类定义了品牌、价格、最高时速等属性(成员变量),以及刹车、启动等方法。当定义继承汽车类的子类卡车时,它自动继承汽车类的属性和方法。 继承只是代码重用的一种方式,滥用继承会造成继承只是代码重用的一种方式,滥用继承会造成很严重的后果。很严重的后果。 只有当需要向新类添加新的操作,并且把已存在类的默认行为融合进新类中时,才需要继承已存在的类。4.1.2 4.1.2 继承层次继承层次4.2 Java4.2 Java中的继承中的继承 在在JavaJava中,实际上所有的类均直接或间接
5、继承自中,实际上所有的类均直接或间接继承自java.lang.Objectjava.lang.Object类,也可以说类,也可以说ObjectObject类是类是JavaJava中的总根类。中的总根类。 实际开发中,如不特殊指定,开发人员自己定义实际开发中,如不特殊指定,开发人员自己定义的类均直接继承自的类均直接继承自ObjectObject类。类。4.2.1 派生子类 在在JavaJava中,类的继承通过中,类的继承通过entendsentends关键字实现。关键字实现。在创建新类时,使用在创建新类时,使用extendsextends指明新类的父类,指明新类的父类,具体语法如下。具体语法如下
6、。 class class 子类名子类名 extends extends 父类名父类名 子类类体子类类体 4.2.2 4.2.2 继承规则继承规则 当类当类B B成功继承类成功继承类A A后,就涉及到成员变量的继承后,就涉及到成员变量的继承问题。下面将从两个方面介绍成员变量继承的相问题。下面将从两个方面介绍成员变量继承的相关知识,主要包括成员变量的继承规则与成员变关知识,主要包括成员变量的继承规则与成员变量的隐藏。量的隐藏。 1 1成员变量的继承规则(成员变量的继承规则(取决于访问权限取决于访问权限) 2 2成员变量的隐藏成员变量的隐藏 对于成员变量来说,当子类本身具有与继承自父对于成员变量来
7、说,当子类本身具有与继承自父类的成员变量名称相同的成员变量时,便构成了类的成员变量名称相同的成员变量时,便构成了成员变量的隐藏成员变量的隐藏。其含义是,在子类中直接调用。其含义是,在子类中直接调用该成员变量时,将调用的是子类中本身具有的成该成员变量时,将调用的是子类中本身具有的成员变量,而不是从父类继承的成员变量,员变量,而不是从父类继承的成员变量,例题例题4-1 public4-1 public类型成员变量示例类型成员变量示例1 1例题例题4-2 public4-2 public类型成员变量示例类型成员变量示例2 2例题例题4-3 4-3 成员变量隐藏示例成员变量隐藏示例读程序,看输出结果是
8、多少?读程序,看输出结果是多少?4.2.3 4.2.3 方法的继承与覆盖方法的继承与覆盖 方法继承允许子类使用父类的方法,而覆盖是在子类中重新定义父类中的方法,更显示了继承的灵活性。 1 1方法的继承方法的继承 方法也是一种成员,因此继承规则与成员变量的继承规则完全一样 其是否能被继承同样取决与访问限制。4.2.3 4.2.3 方法的继承与覆盖方法的继承与覆盖2 2方法的覆盖方法的覆盖子类的自身方法中,若与继承过来的方法具有相同的方法子类的自身方法中,若与继承过来的方法具有相同的方法名,便构成了方法的重写名,便构成了方法的重写(有的资料称之为方法的覆盖)。 * 子类的方法名称返回类型及参数签名
9、 必须与父类的一致 * 子类方法不能缩小父类方法的访问权限 * 方法覆盖只存在于子类和父类之间,同一个类中只能重载 * 父类的静态方法不能被子类覆盖为非静态方法 * 父类的非静态方法不能被子类覆盖为静态方法 * 父类的私有方法不能被子类覆盖 public class Vehicle public class Vehicle /startUp /startUp方法表示一般交通工具的启动功能方法表示一般交通工具的启动功能 public void startUp()public void startUp() System.out.println( System.out.println(一般交通工具的
10、启动方法!一般交通工具的启动方法!); ); public class Car extends Vehiclepublic class Car extends Vehicle public void startUp() public void startUp() System.out.println(“ System.out.println(“轿车的启动方法!轿车的启动方法!);); public class Sample4_5 public class Sample4_5 public static void main(String args) public static void main
11、(String args) /创建对象并调用方法创建对象并调用方法Car c=new Car(); Car c=new Car(); System.out.print(System.out.print(实际调用的方法为:实际调用的方法为:););c.startUp();c.startUp(); 4.2.4 this4.2.4 this与与supersuper在在JavaJava中,中,thisthis和和supersuper与继承是密切相关的。与继承是密切相关的。thisthis常用来常用来引用当前对象,而引用当前对象,而supersuper常用来引用父类对象。常用来引用父类对象。1 1thi
12、sthis方法中的某个对象与当前对象的某个成员有相同的名字,方法中的某个对象与当前对象的某个成员有相同的名字,这时为了不至于混淆,可以使用这时为了不至于混淆,可以使用thisthis关键字来指明要使用关键字来指明要使用某个成员,使用方法是某个成员,使用方法是“this.this.成员名成员名”,即使用,即使用thisthis隐式隐式地引用对象的实例变量和方法。地引用对象的实例变量和方法。2 2supersupersupersuper用来引用父类的成员,包含父类的构造函数、属性以用来引用父类的成员,包含父类的构造函数、属性以及方法。使用方法为及方法。使用方法为supersuper变量名或变量名或
13、super.super.方法名(实参)。方法名(实参)。thisthis使用示例使用示例public class Sample4_8 public class Sample4_8 private int x, y;private int x, y;public Sample4_8(int x, int y) public Sample4_8(int x, int y) this.x = x;this.x = x;this.y = y;this.y = y; public Sample4_8() public Sample4_8() this(0, 0); this(0, 0); public
14、static void main(String srgs) public static void main(String srgs) Sample4_8 s = new Sample4_8();Sample4_8 s = new Sample4_8();System.out.println(s.x);System.out.println(s.x);System.out.println(s.y);System.out.println(s.y); 修改程序,演示修改程序,演示supersuper的用法的用法supersuper使用示例使用示例public class Person public c
15、lass Person public String info = public String info = 我是父类我是父类; public static void printMessage(String s) public static void printMessage(String s) System.out.println(s); System.out.println(s); public Person() public Person() printMessage(A Person.); printMessage(A Person.);public Person(String name
16、) public Person(String name) printMessage(A person name is: + name); printMessage(A person name is: + name); public class Sample4_9 extends Person public class Sample4_9 extends Person public Sample4_9() public Sample4_9() super(); super(); printMessage( printMessage(相关信息相关信息:);:); System.out.printl
17、n(); System.out.println();public Sample4_9(String name) public Sample4_9(String name) super(name); super(name); printMessage( printMessage(名字名字: + name);: + name); public Sample4_9(String name, int age) public Sample4_9(String name, int age) this(name); this(name); printMessage(
18、printMessage(年龄年龄: + age);: + age);public static void main(String args) public static void main(String args) Sample4_9 cn = new Sample4_9(); Sample4_9 cn = new Sample4_9(); cn = new Sample4_9( cn = new Sample4_9(张三张三);); cn = new Sample4_9( cn = new Sample4_9(张三张三, 22);, 22); 4.3 4.3 强制类型转换强制类型转换 本节
19、中的本节中的强制类型转换只在继承过程中发生引用强制类型转换只在继承过程中发生引用类型转换类型转换,而不是基本数据类型的转换。,而不是基本数据类型的转换。 引用类型转换指对象引用的强制类型转换,在学引用类型转换指对象引用的强制类型转换,在学习对象引用的强制类型转换之前,先介绍一下对习对象引用的强制类型转换之前,先介绍一下对象引用能指向什么样的对象。通过前面几章的学象引用能指向什么样的对象。通过前面几章的学习,可以知道不管什么类型的对象引用,均能指习,可以知道不管什么类型的对象引用,均能指向其自身类型的对象实例,下面的代码说明了这向其自身类型的对象实例,下面的代码说明了这个问题。个问题。 1 1/
20、汽车类型的引用汽车类型的引用c c指向汽车类型的对象指向汽车类型的对象 2 2Car c=new Car();Car c=new Car(); 3 3/卡车类型的引用卡车类型的引用t t指向卡车类型的对象指向卡车类型的对象 4 Truck t = new Truck();4 Truck t = new Truck(); class Vehicle class Vehicle class Car extends Vehicle class Car extends Vehicle class Truck extends Car class Truck extends Car TruckTruck类
21、继承自类继承自CarCar类,所以类,所以TruckTruck类也是类也是VehicleVehicle类类派生出来的子类。派生出来的子类。Vehicle v = new Car();Vehicle v = new Car();v=new Truck();v=new Truck();Car c = new Truck();Car c = new Truck();4.4 4.4 动动 态态 绑绑 定定 所谓的动态绑定,对象在调用方法的时候能够自所谓的动态绑定,对象在调用方法的时候能够自己判断该调用谁的方法。己判断该调用谁的方法。 所以动态绑定一般发生在继承、方法重载时。所以动态绑定一般发生在继承、
22、方法重载时。 那么发生方法重载时,编译器如何确定调用的方那么发生方法重载时,编译器如何确定调用的方法呢?法呢?4.4 4.4 动动 态态 绑绑 定定 例如,调用例如,调用c.fc.f(argarg)时,首先需要将)时,首先需要将c c声明为声明为B B类的对象。此时,如果在类的对象。此时,如果在B B类中,存在多个类中,存在多个f f方法,方法,只是只是f f的参数类型不同,调用的参数类型不同,调用f f(intint)或者)或者f f(StringString)时,编译器逐一列举)时,编译器逐一列举B B类中所有名为类中所有名为f f的方法以及的方法以及B B类超类中访问权限为类超类中访问权
23、限为publicpublic的名为的名为f f的方法。如果存在与的方法。如果存在与c.fc.f(argarg)中)中argarg类型相匹类型相匹配的方法,那么就调用这个方法。配的方法,那么就调用这个方法。 由此,调用哪个方法依赖于隐式参数的实际类型。由此,调用哪个方法依赖于隐式参数的实际类型。这个过程可以就是一个动态绑定的过程。这个过程可以就是一个动态绑定的过程。4.4 4.4 动动 态态 绑绑 定定 如果如果setName( )setName( )是是privateprivate、static static 或者或者finalfinal类型的,就不用进行动态绑定了,类型的,就不用进行动态绑定
24、了,因为系统编译器可以自己准确的知道要调因为系统编译器可以自己准确的知道要调用哪些方法。用哪些方法。 由于由于JavaJava中允许类型转换,所以要找到合中允许类型转换,所以要找到合适的方法是一个复杂的过程。适的方法是一个复杂的过程。 如果编译器没有找到合适的方法,则直接如果编译器没有找到合适的方法,则直接报错,抛出异常。报错,抛出异常。4.5 4.5 终止继承:终止继承:FinalFinal类和类和FinalFinal方法方法 关键字关键字FinalFinal不但可以用来修饰变量,而不但可以用来修饰变量,而且对类及其方法的继承也有很大的影响。且对类及其方法的继承也有很大的影响。 本节将从类与
25、方法两方面介绍本节将从类与方法两方面介绍finalfinal关键关键字的功能字的功能。4.5.1 Final4.5.1 Final类类 当关键字当关键字finalfinal用来修饰类时,其含义是该类不用来修饰类时,其含义是该类不能再派生子类能再派生子类。 换句话说,任何其他类都不能继承用换句话说,任何其他类都不能继承用finalfinal修饰修饰的类,即使该类的访问限制为的类,即使该类的访问限制为publicpublic类型,也不类型,也不能被继承;否则,将编译报错。能被继承;否则,将编译报错。 那么什么时候应该使用那么什么时候应该使用finalfinal修饰类呢?修饰类呢? 只有当需要确保类
26、中的所有方法都不被重写时才只有当需要确保类中的所有方法都不被重写时才应该建立最终(应该建立最终(finalfinal)类)类注意:只要有注意:只要有FinalFinal这个关键字来修饰类时,这个关键字来修饰类时,子类就不能继承父类子类就不能继承父类4.5.2 Final4.5.2 Final方法方法 当用当用finalfinal关键字修饰方法后,该方法在关键字修饰方法后,该方法在子类中将无法重写,只能继承。子类中将无法重写,只能继承。在在SonSon类中类中show()show()方法覆盖了方法覆盖了FatherFather中的中的show(),show(),被覆被覆盖的方法被盖的方法被fin
27、alfinal修饰,那修饰,那finalfinal方法不能被继承方法不能被继承。4.5.2 Final4.5.2 Final方法方法 要恰当使用要恰当使用finalfinal的方法的方法; ; 只有在子类覆盖某个方法会带来问题时,只有在子类覆盖某个方法会带来问题时,再将此方法设为再将此方法设为finalfinal的方法,一般情况的方法,一般情况下可以不必使用下可以不必使用; ; 因为防止子类覆盖会失去一些面向对象的因为防止子类覆盖会失去一些面向对象的优点,包括通过覆盖实现的可扩展性。优点,包括通过覆盖实现的可扩展性。4.6 4.6 抽抽 象象 类类 在现实世界中,当人们认识世界时,也会把现实在
28、现实世界中,当人们认识世界时,也会把现实世界很多具有相同特征的事物归为一个抽象类。世界很多具有相同特征的事物归为一个抽象类。 例如,水果是很多种具体植物果实的总称(抽象例如,水果是很多种具体植物果实的总称(抽象类),当需要拿出一个水果的实例时,拿出来的类),当需要拿出一个水果的实例时,拿出来的不是苹果就是香蕉等具体种类的实例,拿不出只不是苹果就是香蕉等具体种类的实例,拿不出只是水果的实例。在需要一个抽象类实例时,只能是水果的实例。在需要一个抽象类实例时,只能用某个具体类的实例来代替。用某个具体类的实例来代替。 JavaJava是用来抽象和描述现实世界的,因此也提供是用来抽象和描述现实世界的,因
29、此也提供抽象类,并且其永远不能实例化,其唯一用途是抽象类,并且其永远不能实例化,其唯一用途是用于继承扩展。用于继承扩展。4.6.1 4.6.1 抽象类抽象类 如果从上而下观察类的层次结构,位于上如果从上而下观察类的层次结构,位于上层的类更具有通用性。层的类更具有通用性。 一般情况下,人们这将这些通用的类作为一般情况下,人们这将这些通用的类作为派生其他类的基类。派生其他类的基类。 在在JavaJava中,可以使用中,可以使用abstractabstract关键字声明关键字声明抽象类和抽象方法。抽象类和抽象方法。注意:抽象类不能进行实例化注意:抽象类不能进行实例化 abstractabstract
30、和和finalfinal不能同时使用不能同时使用4.6.2 4.6.2 抽象的方法抽象的方法 抽象方法,其具体实现是在子类中。抽象方法,其具体实现是在子类中。 抽象方法是只有方法声明,没有方法体,使用抽象方法是只有方法声明,没有方法体,使用abstractabstract关键字来声明的方法。关键字来声明的方法。 因为抽象方法没有方法体,因为抽象方法没有方法体,用分号表示声明结束用分号表示声明结束,下面给出了抽象方法的声明。下面给出了抽象方法的声明。 public public abstractabstract void startup void startup ( ( ) )注意:非抽象类注意
31、:非抽象类CarCar中不能有抽象的方法中不能有抽象的方法startUp()startUp()。要正常编译,需将要正常编译,需将CarCar类声明为抽象类类声明为抽象类 abstract class Car abstract class Car / / 定义抽象方法定义抽象方法startUpstartUp public abstract void startUp(); public abstract void startUp(); abstract class Mazda extends Car abstract class Mazda extends Car /定义抽象方法定义抽象方法tur
32、boturbopublic abstract void turbo();public abstract void turbo(); public class Mazda6 extends Mazda public class Mazda6 extends Mazda / / 实现实现startUpstartUp方法方法public void startUp() public void startUp() System.out.println(System.out.println(调用了调用了Mazda6Mazda6的启动功的启动功能!能!);); / / 实现实现turboturbo方法方法p
33、ublic void turbo() public void turbo() System.out.println(System.out.println(调用了调用了Mazda6Mazda6的加速功的加速功能!能!);); public class Mazda3 public class Mazda3 / / 实现实现startUpstartUp方法方法public void startUp() public void startUp() System.out.println(System.out.println(调用了调用了Mazda3Mazda3的启动功的启动功能!能!);); / / 实
34、现实现turboturbo方法方法public void turbo() public void turbo() System.out.println(System.out.println(调用了调用了Mazda3Mazda3的加速功的加速功能!能!);); public class Sample4_17 public class Sample4_17 public static void main(String args) public static void main(String args) / / 创建创建Mazda5Mazda5对象并使该类引用对象并使该类引用a6a6指向该对象指向该
35、对象Mazda6 a6 = new Mazda6();Mazda6 a6 = new Mazda6();/ / 调用调用Audi_A6Audi_A6对象中的方法对象中的方法a6.startUp();a6.startUp();a6.turbo();a6.turbo();/ / 创建创建Mazda38Mazda38对象并使该类引用对象并使该类引用a8a8指向该对象指向该对象Mazda3 a8 = new Mazda3();Mazda3 a8 = new Mazda3();/ / 调用调用Audi_A8Audi_A8对象中的方法对象中的方法a8.startUp();a8.startUp();a8.t
36、urbo();a8.turbo(); 4.7 4.7 多多 态态 多态性(多态性(PolymorphismPolymorphism)就是不同的对象有相同)就是不同的对象有相同的轮廓或形态,但具体执行的过程却大相径庭。的轮廓或形态,但具体执行的过程却大相径庭。 例如,驾驶员在开车时都知道例如,驾驶员在开车时都知道“遇到红灯时刹遇到红灯时刹车车”,这与驾驶员驾驶的是什么型号的车无关,这与驾驶员驾驶的是什么型号的车无关,所有的车都具有相同的轮廓或形态的刹车。所有的车都具有相同的轮廓或形态的刹车。 在在JavaJava开发中,基于继承的多态就是指对象功能开发中,基于继承的多态就是指对象功能的调用者用超
37、类的引用来进行方法调用的调用者用超类的引用来进行方法调用。这样,。这样,可以提高灵活性,因为用超类的引用能调用各种可以提高灵活性,因为用超类的引用能调用各种不同的子类实现,就像汽车驾驶员可以开各种不不同的子类实现,就像汽车驾驶员可以开各种不同的汽车一样。同的汽车一样。 public abstract class Car public abstract class Car /定义抽象方法定义抽象方法brakebrakepublic abstract void brake();public abstract void brake(); public class Truck extends Carp
38、ublic class Truck extends Car / /实现实现brakebrake方法方法public void brake()public void brake() System.out.println(System.out.println(卡车刹车!卡车刹车!);); public class SUV extends Car public class SUV extends Car /实现实现brakebrake方法方法public void brake() public void brake() System.out.println(System.out.println(正在
39、正在SUVSUV上刹车!上刹车!);); public class Sample4_18 public class Sample4_18 public static void main(String args)public static void main(String args) /声明声明CarCar引用引用c c并将其指向并将其指向TruckTruck类的对象类的对象 Car c=new Truck(); Car c=new Truck(); System.out.print( System.out.print(调用的方法为:调用的方法为:););/使用引用使用引用c c调用调用brakebrake方法方法 c.brake(); c.brake();/将引用将引用c c指向指向MiniMini类的对象类的对象 c=new SUV(); c=new SUV();Sys
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年和君职业学院高职单招职业适应性测试参考题库带答案解析
- 2026年广西蓝天航空职业学院高职单招职业适应性考试备考试题带答案解析
- 2026年广东生态工程职业学院高职单招职业适应性测试参考题库带答案解析
- 2026年渤海理工职业学院单招职业技能考试备考题库带答案解析
- 2026年广州科技贸易职业学院高职单招职业适应性考试备考题库带答案解析
- 2026年毕节工业职业技术学院单招职业技能考试模拟试题带答案解析
- 2026年哈尔滨铁道职业技术学院单招职业技能笔试模拟试题带答案解析
- 2026年巴音郭楞职业技术学院高职单招职业适应性考试参考题库带答案解析
- 2026年常州信息职业技术学院高职单招职业适应性考试备考试题带答案解析
- 2026年渤海船舶职业学院高职单招职业适应性考试模拟试题带答案解析
- 2025年全国注册监理工程师继续教育题库附答案
- 锅炉原理培训课件
- 重庆市高新技术产业开发区消防救援支队政府专职消防员招录(聘)114人参考题库附答案
- 2026年林学概论选择试题及答案
- 2026年安全员之A证考试题库500道附参考答案(黄金题型)
- 儿童早教中心接待服务流程
- 肿瘤课件模板
- 云计算环境下中小企业会计信息化建设问题
- 《材料性能学》课件-第四章 材料的断裂韧性
- 超市服务培训课程课件
- 公务出行社会汽车租赁管理规范
评论
0/150
提交评论