40
1 第4第 第第 第第第第第第 第第第第第第第第 第第 第第第 第第 第第第第第第第 第第 第第第第 第第 第第第 第第 第第 第第第第第第第 第第 6

第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

  • Upload
    edison

  • View
    221

  • Download
    37

Embed Size (px)

DESCRIPTION

第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖 抽象类 接口 难点 内部类与匿名类 学时 6. 面向对象的 3 个特征: 抽象、封装 继承 多态 软件重用 -- 通过继承实现 可以实现:保留原有的功能,并进行功能扩展。 父类的修改,子类自动得到修改. 张三汽车类. 张三汽车类 改造升级. 张三. 卖. 改. 改. 张三汽车类. 里斯汽 车类. 里斯汽 车类 1. - PowerPoint PPT Presentation

Citation preview

Page 1: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

1

第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖 抽象类 接口难点 内部类与匿名类学时 6

Page 2: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

2

面向对象的 3 个特征:抽象、封装继承多态

软件重用 -- 通过继承实现可以实现:保留原有的功能,并进行功能扩展。父类的修改,子类自动得到修改

Page 3: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

3

张三汽车类张三

张三汽车类里斯

里斯汽车类改

里斯汽车类 1改

张三汽车类 赵新汽车类改赵新

张三汽车类 改造升级

Page 4: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

4

windows 窗口

Page 5: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

5

class Student { // 继承的好处? private int num ; private String name, sex; Student(int _num,String _name,String _sex){ num = _num ; name = _name; sex=_sex; } void display(){ System.out.print(num+”,”+name+”,”+sex); }};

class Student1 { // 复制代码 private int num ; // 学号 private String name,sex; // 性别 private int age ; private String addr; Student1(int _num,String _name,String _sex,int _age,String _addr){ num = _num ; name = _name; sex=_sex; age=_age;addr=_addr;} void display(){ System.out.print(num+”,”+name+”,”+sex+”,”+ age+”,”+addr) ; } };

Page 6: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

6

class Student1 extends student { private int age ; private String addr; Student1(int _num,String _name,String _sex, int _age,String _addr){ super(_num,_name,_sex); age=_age;addr=_addr;} void display(){ super.display(); // 调用父类的 display() System.out.print(age+” “+addr); }};

Page 7: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

7

学生 教师 工人 公务员

本科生 研究生

继承

Page 8: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

8

人类: name sex

学生类: 学号 班级

教师类: 工号 教授课程

Page 9: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

9

4.1 类的继承通过继承可以实现代码的复用。父类或超类 (superclass) 被继承的类子类( subclass ) 由继承而得到的类

一个父类可以同时拥有多个子类,但由于 Java 中不支持多重继承,所以一个类只能有一个直接父类。

Page 10: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

10

4.1 类的继承• 代码的复用• 被继承的类称为父类 (基类、超类 ) • 继承父类的类称为子类 ( 派生类 ) • 继承时,子类将获得父类的属性,并具有自身特有

的属性。 • 单继承• java 类的共同祖先: java.lang.Object

人类: name sex

学生类: 学号 班级

教师类: 工号 教授课程

Page 11: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

11

格式:class SubClass extends SuperClass{……} 直接子类,间接子类。 没有 extends ,默认父类为 Object 。 子类继承父类的全部成员,就像是自己的。 子类能访问父类的 public, default, prote

cted 成员

4.1.1 子类的创建

Page 12: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

12

class A{ // 继承 private int x; int y; void setX(int i){x=i;} int getX(){return x;}}class B extends A{ private int z; void setZ(int i){ z=i; y = 2*i; } void show(){ System.out.prin

t( x+”,”+y+”,”+z); } }

class C extends B { private int w; void setW(int i){ w=i; } void print(){ show(); System.out.println(w); } }B b1 = new B(); b1.setZ(3); b1.setX(2);

z : 3

X : 2y : 6

b1 对象

Page 13: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

13

1. 子类的构建方法class Person { //Person 类是 Object 类的子类 private String name; private int age; Person(){ System.out.println(“ 调用了个人构造方法 Person()”); } public void SetNameAge(String name, int age) { this.name=name; this.age=age; } public void show(){ System.out.println(“ 姓名:“ +name+” 年龄:” +age);}}class Student extends Person{ private String department; Student(){ System.out.println(“ 调用了学生构造方法 Student()”); } void SetDepartment(String dep){ department=dep; System.out.println(“ 我是” +department +” 的学生” ); }}

Page 14: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

14

public class app8_1 // 主类{ public static void main(String args[ ]) { Student stu=new Student(); stu.SetNameAge(“ 张小三” ,21); stu.show(); stu.SetDepartment(“ 计算机系” ); }}

【例 8.1 】续

Page 15: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

15

说明:(1) 通过 extends 关键字,可将父类的成员继承给子类。 数据成员、成员方法。 老子的,就是儿子的。(但儿子的,老子不能看) (2) 构造方法 : 先自动调用父类中没有参数的构造方法

, 然后子类的构造方法。 (3) 构造方法是不能被继承的,例如父 Person 有一个构

造方法 Person(String,int) ,不能说子类 Student 也自动有一个构造方法 Person(String,int) ,但这并不意味着子类不能调用父类的构造方法。

Page 16: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

16

class A { //A 继承谁? 构造方法 protected int x; A(){ x=-1; System.out.print(“A0”);} A(int i) { x = i; System.out.print(“A1”);} }class B extends A { protected int y ; B(){y=-1; System.out.print(“B0”);} B(int j){ y = j; System.out.print(“B1”); }}class C extends B { private int z ; C(){z=-1; System.out.print(“C0”);} C(int k){ z = k; System.out.print(“C1”); }}

C c1 = new C(3);

Page 17: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

17

class A { // 改错 构造方法 private int x; protected int y; A(int i) { x = i; } void printA(){ System.out.print(x+” “+y); } }class B extends A { private int z ; B(int j){ z = j; } void printB(){ System.out.print (x+” “+y+” “+z); }}

Page 18: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

18

2. 调用父类中特定的构造方法 如何初始化父类的数据成员?

super 1 )调用父类的构造方法 子类构造方法的第一句。2 )访问父类中被隐藏的数据成员

super. 成员3 )调用父类中被重写的成员方法

注意:建对象初始化过程先父类,然后子类。 释放对象调用 finalize, 先子类后父类。

注意与 this 的区别

Page 19: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

19

class A{ private int x , y; A(){ x=-1;y=-1;} A(int i, int j){ x=i; y = j;} void show(){System.out.print( x+”,”+y);}}

class B extends A{ private int z; B(){ } B(int i, int j , int k){ z=k; }}class hello2 {public static void main(String

args[]) { B b1=new B(); b1.show(); B b2=new B( 1,2,3); b2.show

(); } }

内存示意??

x,y 如何为 1 , 2??

Page 20: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

20

// super 在构造方法中 class A{ private int x , y; A(){ x=-1;y=-2;}

A(int i, int j){ x=i; y = j; }

void show(){System.out.print( x+”,”+y);}}

class B extends A{ private int z;

B(){ } B(int i, int j , int k){ super(i ,j); //完成父类的初始化 z=k; }}class hello2 {public static void main(String args[])

{ B b1=new B(); b1.show(); B b2=new B( 1,2,3); b2.show(); } }

Page 21: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

21

class Person { // 调用父类中的特定构造方法 private String name; private int age; Person(){ System.out.println(“ 调用 Person 无参构造方法” ); } Person(String name, int age) { System.out.println(“ 调用了 Person 的有参构造方法” ); this.name=name; this.age=age; } void show() { System.out.println(“ 姓名:“ +name+” 年龄:” +age);}}

class Student extends Person { private String department; Student(){System.out.println(“ 调用学生无参构造” );} Student (String name,int age,String dep) { super(name,age); department=dep; System.out.println(“ 调用了学生的有参构造方法” ); }}

Page 22: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

22

public class app8_2 // 主类 { public static void main(String args[ ]) { Student stu1=new Student(); Student stu2=new Student(“李小四” ,23,”信息系” );

stu1.show(); stu2.show(); } }

【例 8.2 】续

Page 23: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

23

class A{ //this int x=1; int y=2; void setXY(int i,int j){ x = i; this.y = j;} void f1(){ setXY(3,4);}}

// 成员变量与局部变量class A{ //this int x=1; int y=2; void f1(){ int x=9; this.x = x; ;}}

可省略 不可省略

Page 24: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

24

练习 继承构造方法人: Person ,有属性:姓名,年龄。学生: student, 还有属性 学号,入学年份。教师: teacher,还有属性 工号,职称

本科学生 underGraduate :有属性:专业,特长。研究生 graduate :有属性 专业,方向,导师。测试:本科生: 08101, 张三 ,21,2008 年 , 计算机 ,长跑。研究生: 10101,钱四 ,24,2010 年 , 计算机应用,数据库,王平

。教师: 0901 ,王平, 38 ,副教授

输出 2 个学生、一个教师的信息。

Page 25: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

25

4.1.2 在子类中访问父类的成员

格式:super.<变量名 >super.<方法名 >

必须吗?

Page 26: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

26

super 调用父类方法class A{ int x=1; int y=2; void show(){ System.out.print( x+”,”+y);}}

class B extends A{ int x=7; void show(){ System.out.print(super.x); } System.out.print(x +” ,“ +y); } void fun( ){ super.show(); } }class hello2 { public static void main(String args[])

{ B b=new B(); b.fun( ); b.show(); } }

Page 27: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

27

class Person { // super关键字访问父类的成员 protected String name; protected int age; Person() {} Person(String name, int age) { name=name; age=age; } protected void show() { System.out.println(“ 姓名:“ +name+” 年龄:” +age); } }class Student extends Person { private String department; int age=20; Student (String xm,String dep) { name=xm; department=dep; super.age=25; System.out.println(“ 子类 Student 中的成员变量 age=”+age); super.show(); System.out.println(“ 系别:” + department ); } }

Page 28: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

28

31      public class app8_3 // 主类32      {33       public static void main(String args[ ])34       {35       Student stu=new Student(“李小四” ,”信息系” );36       }37      }

【例 8.3 】续

Page 29: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

29

class Person { //找错,并改正 private String name; private int age; Person (){} Person( String pname, int page): name=pname; age=page ;} void Print(){ System.out.print(name+’,’+age); }}class Student extends Person { private String no ; int year ; Student(String pno,String pname,int page,int pYear){ super(pname,page); no=pno; year = pYear;} void print(){ System.out.print(no+”,”+year); System.out.print(name+”,”+age); } }

Page 30: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

30

补充:析构函数1 析构函数 protected void finalize () 对象被销毁时执行的方法。每个对象一定有一个析

构函数。(继承 Object 类) 必须捕获异常。 2 可以自己调用对象的 finalize 方法,这种调用与

对象销毁无关。 3 java 的 gc() 负责内存的清理。

调用 gc() 并不保证 gc() 实际执行。 调用 gc 检查 finalize 调用情况。4 析构函数执行:先子类,后父类。

Page 31: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

31

class A { private int x;

A(int i) { x = i; System.out.print("A1");} protected void finalize() throws Throwable {

System.out.println("~A"); } }

class B extends A { private protected int y ; B(int j){ y = j; System.out.print("B1"); } protected void finalize() throws Throwable { System.out.println("~B");

//super.finalize(); } }

public class test1 { static void f1(){ B c1 = new B(3); } public static void main(String[] args) { f1();

System.gc(); } }

Page 32: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

32

可以记录当前类创建了多少对象,但有漏洞。class A { private static int nCount ; private int x ; static { nCount=0;} A(){ x = -1 ; nCount++;} A(int i ){ x = i ; nCount++;} static int getCount(){ return nCount;} }class hello{ public static void main(String args[]) { A a1=new A(); A a2 = new A(2); A a3= new A(4); System.out.print( A.getCount()); a1=null; // 释放了 a1 还有? System.out.println( A.getCount()); }}

Page 33: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

33

class A { //完善的记录对象个数 private static int nCount ; private int x ; static { nCount=0;} A(){ x = -1 ; nCount++;} A(int i ){ x = i ; nCount++;} protected void finalize() throws Throwable {

System.out.println("~A"); nCount--; } static int getCount(){ return nCount;} }class hello{ public static void main(String args[]) { A a1=new A(); A a2 = new A(2); A a3= new A(4); System.out.print( A.getCount()); a1=null; System.gc(); for(int i=0;i<10000;i++){ //延时 } System.out.println( A.getCount()); } }

Page 34: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

34

继承练习1 完成一个能表达日期时间的类: JDateTime 类。

1 )建立 JDate 类 , 有私有属性 year,month,day ; 有一个公有方法 show ,输出日期,格式如: 2004 年 3月2日。

2) 建立 JDateTime 类,该类有私有属性时、分、秒 ( hour, minute, second) , 有公有方法 show ,输出时间 ,格式如: 2005年 3月 2日 11:20:22 。

3) 测试:建立对象 d1 , 表示 2005年 10月 21日 , 输出 d1建立对象 t1, 表示 2005年 10月 22日 11:20:22,输出 t1 日期部分 格式为: 2005年 10月 22日 。

Page 35: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

35

2 人: 私有成员变量:姓名 name 、性别 sex 、年龄 age 成员方法 print :输出姓名、性别、年龄 学生: 私有成员变量:学号 no 、班级 class 成员方法 print: 输出学号、姓名、性别、年龄、班级 教师: 私有成员变量:工号 no 、所教课程 course 。 成员方法 print: 输出工号、姓名、性别、年龄、课程 学生、教师继承人,写出此 3 个类,

测试程序 :1 )建立学生对象: student1 : 学号 =101 、姓名 =王利

、性别 =男、年龄 =22 、班级 =1 班2 )建立教师对象: teacher1 : 工号 =A01 、姓名 =高丽

、性别 =女、年龄 =35、课程 = 数据库3 )输出 student1 , teacher1 对象的值。

Page 36: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

36

class A { 构造方法 protected int x; A(){ x=-1; System.out.print(“A0”);} A(int i) { x = i; System.out.print(“A1”);} }class B extends A { protected int y ; B(){y=-1; System.out.print(“B0”);} B(int j){ y = j; System.out.print(“B1”); }}class C extends B { private int z ; C(){z=-1; System.out.print(“C0”);} C(int k){ z = k; System.out.print(“C1”); }}public class Test { public static void main(String args[ ]){ C c1 = new C( ); C c2 = new C(5) ; }

Page 37: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

37

class A { // 改错 构造方法 private int x; protected int y; A(int i) { x = i; } void printA(){ System.out.print(x+” “+y); } }class B extends A { private int z ; B(int j){ z = j; } void printB(){ System.out.print (x+” “+y+” “+z); }}

Page 38: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

38

//super 调用父类方法class A{ int x=1; int y=2; void setX(int i){x=i;} void show(){System.out.println( x+”,”+y);}}

class B extends A{ int x=5; void show(){ int y =7; System.out.println(super.x);} System.out.println(x); System.out.println(y); } void fun( ){ show(); super.show(); } }class hello2 { public static void main(String args[])

{ B b=new B(); b.fun( ); b.setX(9); b.show(); } }

写出程序运行结果?

Page 39: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

39

class A{ //super 调用方法 int x=1; int y=2; void set(int i){ x = i; y =2*i; }

void show(){System.out.print(x+”,”+y);}}

class B extends A{ int x=7; void set( int i ){ x = i;}

void fun(int i , int j){ super.set( i ); set( j ); } void show(){ System.out.print(x); System.out.p

rint(super.x+”,”+y);}}class hello2 {public static void main(String args[])

{ B b=new B(); b.fun(1 , 2); b.show(); } }

写出程序运行结果?

Page 40: 第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖

40

class A{ // 改错 [ super 在构造方法中 ] private int x=-1 , y=-1; A(int i, int j){ x=i; y = j; } public void show(){ System.out.print(x+”,”+y);}} class B extends A{ private int z; B(){ } B(int i, int j , int k){ z=k; super(i ,j); }}class hello2 {public static void main(String args[]) { B b1=new B(); b1.show(); B b2=new B( 1,2,3); b2.show(); } }