Upload
edison
View
221
Download
37
Embed Size (px)
DESCRIPTION
第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖 抽象类 接口 难点 内部类与匿名类 学时 6. 面向对象的 3 个特征: 抽象、封装 继承 多态 软件重用 -- 通过继承实现 可以实现:保留原有的功能,并进行功能扩展。 父类的修改,子类自动得到修改. 张三汽车类. 张三汽车类 改造升级. 张三. 卖. 改. 改. 张三汽车类. 里斯汽 车类. 里斯汽 车类 1. - PowerPoint PPT Presentation
Citation preview
1
第 4 章 继承、抽象类和接口 教学内容: 类的继承 覆盖 抽象类 接口 内部类与匿名类 包 重点 类的继承 覆盖 抽象类 接口难点 内部类与匿名类学时 6
2
面向对象的 3 个特征:抽象、封装继承多态
软件重用 -- 通过继承实现可以实现:保留原有的功能,并进行功能扩展。父类的修改,子类自动得到修改
3
张三汽车类张三
张三汽车类里斯
卖
里斯汽车类改
里斯汽车类 1改
张三汽车类 赵新汽车类改赵新
张三汽车类 改造升级
4
windows 窗口
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) ; } };
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); }};
7
人
学生 教师 工人 公务员
本科生 研究生
继承
8
人类: name sex
学生类: 学号 班级
教师类: 工号 教授课程
9
4.1 类的继承通过继承可以实现代码的复用。父类或超类 (superclass) 被继承的类子类( subclass ) 由继承而得到的类
一个父类可以同时拥有多个子类,但由于 Java 中不支持多重继承,所以一个类只能有一个直接父类。
10
4.1 类的继承• 代码的复用• 被继承的类称为父类 (基类、超类 ) • 继承父类的类称为子类 ( 派生类 ) • 继承时,子类将获得父类的属性,并具有自身特有
的属性。 • 单继承• java 类的共同祖先: java.lang.Object
人类: name sex
学生类: 学号 班级
教师类: 工号 教授课程
11
格式:class SubClass extends SuperClass{……} 直接子类,间接子类。 没有 extends ,默认父类为 Object 。 子类继承父类的全部成员,就像是自己的。 子类能访问父类的 public, default, prote
cted 成员
4.1.1 子类的创建
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 对象
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 +” 的学生” ); }}
14
public class app8_1 // 主类{ public static void main(String args[ ]) { Student stu=new Student(); stu.SetNameAge(“ 张小三” ,21); stu.show(); stu.SetDepartment(“ 计算机系” ); }}
【例 8.1 】续
15
说明:(1) 通过 extends 关键字,可将父类的成员继承给子类。 数据成员、成员方法。 老子的,就是儿子的。(但儿子的,老子不能看) (2) 构造方法 : 先自动调用父类中没有参数的构造方法
, 然后子类的构造方法。 (3) 构造方法是不能被继承的,例如父 Person 有一个构
造方法 Person(String,int) ,不能说子类 Student 也自动有一个构造方法 Person(String,int) ,但这并不意味着子类不能调用父类的构造方法。
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);
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); }}
18
2. 调用父类中特定的构造方法 如何初始化父类的数据成员?
super 1 )调用父类的构造方法 子类构造方法的第一句。2 )访问父类中被隐藏的数据成员
super. 成员3 )调用父类中被重写的成员方法
注意:建对象初始化过程先父类,然后子类。 释放对象调用 finalize, 先子类后父类。
注意与 this 的区别
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??
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(); } }
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(“ 调用了学生的有参构造方法” ); }}
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 】续
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; ;}}
可省略 不可省略
24
练习 继承构造方法人: Person ,有属性:姓名,年龄。学生: student, 还有属性 学号,入学年份。教师: teacher,还有属性 工号,职称
本科学生 underGraduate :有属性:专业,特长。研究生 graduate :有属性 专业,方向,导师。测试:本科生: 08101, 张三 ,21,2008 年 , 计算机 ,长跑。研究生: 10101,钱四 ,24,2010 年 , 计算机应用,数据库,王平
。教师: 0901 ,王平, 38 ,副教授
输出 2 个学生、一个教师的信息。
25
4.1.2 在子类中访问父类的成员
格式:super.<变量名 >super.<方法名 >
必须吗?
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(); } }
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 ); } }
28
31 public class app8_3 // 主类32 {33 public static void main(String args[ ])34 {35 Student stu=new Student(“李小四” ,”信息系” );36 }37 }
【例 8.3 】续
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); } }
30
补充:析构函数1 析构函数 protected void finalize () 对象被销毁时执行的方法。每个对象一定有一个析
构函数。(继承 Object 类) 必须捕获异常。 2 可以自己调用对象的 finalize 方法,这种调用与
对象销毁无关。 3 java 的 gc() 负责内存的清理。
调用 gc() 并不保证 gc() 实际执行。 调用 gc 检查 finalize 调用情况。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(); } }
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()); }}
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()); } }
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日 。
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 对象的值。
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) ; }
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); }}
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(); } }
写出程序运行结果?
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(); } }
写出程序运行结果?
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(); } }