240 likes | 346 Views
第 6 章 Java 的继承与多态. 软 件 学 院 朱士明副教授. 类的继承 覆盖 重载 应用实例. 6.1 类的继承( inheritance). 6.1.1 概述 继承是面向对象程序设计的另一个重要特色,类继承也称为类派生,是指一个类可以继承其他类的非私有成员,实现代码复用。被继承的类称为父类或超类,父类包括所有直接或间接被继承的类;继承父类或超类后产生的类称为派生类或子类。. 什么是子类 ? 子类是作为另一个类的扩充或修正所定义的一个类. bicycle. (super class). sub class. Tandem bikes.
E N D
第6章 Java的继承与多态 软 件 学 院 朱士明副教授
. • 类的继承 • 覆盖 • 重载 • 应用实例
6.1 类的继承(inheritance) • 6.1.1 概述 • 继承是面向对象程序设计的另一个重要特色,类继承也称为类派生,是指一个类可以继承其他类的非私有成员,实现代码复用。被继承的类称为父类或超类,父类包括所有直接或间接被继承的类;继承父类或超类后产生的类称为派生类或子类。
什么是子类? • 子类是作为另一个类的扩充或修正所定义的一个类. bicycle (super class) sub class Tandem bikes Mountain bikes Racing bikes
6.2.2 类继承的实现 • Java中的继承是通过extends关键字来实现的,在定义新类时使用extends关键字指明新类的父类,就在两个类之间建立了继承关系 • [修饰符] class <子类名> extends <父类名>{ • 类体定义; • }
public, abstract, final或者没有 • 类的严格定义及修饰字 [类的修饰字] class 类名称 [extends 父类名称] { …. } • 方法和变量的定义及修饰字 public、protected、private [变量修饰字] 变量数据类型 变量名1,变量名2[=变量初值]…; [方法修饰字] 方法的返回值类型 方法名称(参数1,参数2,… { …//方法的内容 }
什么是继承? • 继承是子类利用父类中定义的方法和变量就像它们属于子类本身一样. class Car { int color_number; int door_number; int speed; push_break() { … } add_oil() { … } } class Trash_Car extends Car { double amount; fill_trash() { … } }
class TrashCar extends Car { int capacity; void set_capacity(int trash_car_capacity) { capacity=trash_car_capacity;} void show_capacity(); { System.out.println(“My capacity is: ”+ capacity);}} class Car { int car_number; void set_number(int car_num) { car_number=car_num;} void show_number() {System.out.println (“My car No. is :”+car_number); } }
class CarDemo { public static void main(String args[]) { TrashCar DemoTrashCar=new TrashCar(); DemoTrashCar.set_number(4949); DemoTrashCar.set_capacity(20); DemoTrashCar.show_number(); DemoTrashCar.show_capacity(); } } • TrashCar中继承了Car中的两个方法 Car是父类, TrashCar是子类
Java语言中,只允许单继承。 • 所谓单继承是指每个类只有一个父类,不允许有多个父类。但一个类允许同时拥有多个子类,这时这个父类实际上是所有子类的公共成员变量和公共方法成员的集合,而每一个子类则是父类的特殊化,是对公共成员变量和方法成员的功能、内涵方面的扩展和延伸。Java语言的多继承可通过接口来实现。 • 类继承不改变成员的访问权限。 • 父类中的成员为公有的或被保护的,则其子类的成员访问权限也继承为公有的或被保护的。
类继承具有传递性。 • 即子类继承父类的所有非私有成员,也继承父类的父类直至祖先所有的所有非私有成员。 • 若父类名又是某个类的子类,则定义的类也是该类的(间接)子类。若无extends子句,则该类为java.lang.Object的子类。 • [例6.1] P109
6.1.3 派生类的初始化(构造方法) • 在创建派生类的对象时,使用派生类的构造方法对其初始化,不但要对自身的成员变量赋初值,还要对父类的的成员变量赋初值。因为成员变量赋初值通常在构造方法中完成,因此在Java语言中,允许派生类继承父类的构造方法。构造方法的继承遵循如下的原则: • (1)若父类是无参数的构造方法,则子类无条件的继承该构造方法。 • (2)若子类无自己的构造方法,则它将继承父类的无参构造方法作为自己的构造方法;若子类有自己的构造方法,则在创建子类对象时,它将先执行继承自父类的无参构造方法,然后再执行自己的构造方法。
(3)若父类是有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。(3)若父类是有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来调用它,但这个调用语句必须是子类构造方法的第一个可执行语句。 • 【例】继承类RectConstructor时对父类的成员变量赋初值。 • class Cube extends RectConstructor{ • double height; • Cube(double l,double w,double h){ • super(l,w); • height = h; • } • void vol(){ • System.out.println("长方体体积 = "+ area() * height); • } • }
public class CubeDemo { • public static void main(String args[]){ • Cube c = new Cube(7,6,5); • c.vol(); • } • } • 程序运行结果如下: • 长方体体积 = 210.0
6.2 类的成员覆盖 • 6.2.1 成员覆盖概述: • 在类的继承中,若子类(派生类)新增的成员名称与父类(超类)成员相同,则称为成员覆盖(overriding)。 • 在子类中定义与父类同名成员的目的是修改父类的属性和行为。 • 成员变量的覆盖即对父类成员变量的隐藏
什么是方法的覆盖? • 在子类中重新定义父类中已有的方法。 class Car { int color_number; int door_number; int speed; push_break() { speed=0; } add_oil() { … } } class Trash_Car extends Car { double amount; fill_trash() { … } push_break() { speed=speed-10; } }
(1)成员变量的覆盖 • 若子类声明了与父类同名的变量,则父类的变量被隐藏起来,直接使用的是子类的变量,但父类的变量仍占据空间,可通过super或父类名来访问。 • 【例】在子类中定义了与父类同名的变量,从而隐藏了父类成员变量,这种隐藏变量可加super前缀来访问。 • class A{ • int x = 100; • }
class B extends A{ • int x = 200; • void print(){ • System.out.println("Subclass : " + x); • System.out.println("Superclass : " + super.x); • } • public static void main(String args[]){ • (new B()).print(); • } • } • 程序运行结果如下: • Subclass : 200 • Superclass : 100
(2)成员方法覆盖 • 与子类可以定义与父类同名的成员变量,实现对父类成员变量的隐藏的情况一样,子类也可以定义与父类同名的方法,实现对父类方法的覆盖。方法成员的覆盖与成员变量的隐藏的不同之处在于:子类隐藏父类的成员变量只是使得它不可见,父类的同名成员变量在子类对象中仍然占据自己的存储空间; • 而子类成员方法对父类同名方法的覆盖将清除父类方法占用的内存空间,从而使得父类的方法在子类对象中不复存在。 • [例6.3] P113
6.2.3 关键字super和this • 1. Super • 子类中调用父类中被覆盖成员; • 子类调用父类构造方法。 2. this • 访问当前对象; • 调用当前对象的另一构造方法。 • [例6.4] P115、 [例6.5] P116
6.2.4 Object类 • Java语言以Object类作为所有类的父类,所有的类都是直接或间接地继承Object类得到的。Java还提供不同层次的标准类,使用户可根据需要派生自己的类。 • Object类常用方法 toString()、equals()、getClass() hashCode()、notify()、notifyAll()、wait() [例6.7、6.8、6.9、6.10] P119-122
6.3 重载 • 什么是方法的重载(多态性)? • 在同一个类中至少有两个方法用同一个名字,但有不同的参数。 • 成员方法、构造方法的重载[例6.11]P123 void show(int int_num) 123 1.23 void show(double double_num) 类 123,1.23 void show(nit nit_ um, float float_um)