第4章类的封装性、继承性、多态性及接口
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
25
构造方法的调用顺序
• ⑴按继承顺序依次调用父类的构造方法, 直到到达本子类。 • ⑵依次执行本子类成员对象的构造方法。
• ⑶最后,执行本子类的构造方法。
26
class Person { public Person() { System.out.print("A"); } public Person(String s) { this(); System.out.print("B"); } } class Student extends Person { public Student() { System.out.print("C"); } } public class Who extends Person { Student student=new Student(); public Who() { super("ok"); System.out.print("E"); } public static void main(String args[]) { Who w = new Who(); } }
– 方法“get”与“set”是 public; – 其它方法需要根据实际的需要而定。
6
4.2 继承性
• 继承也称为派生,是指一个新类可以继承其他 已有类的所有成员,包括成员属性和成员方法。 新类不但保留被继承过来的类的属性和方法, 而且可以根据自身需要对类进行修改,添加新 的成员属性和成员方法。 • 被继承的类称为超类(父类)。
• 从超类派生出来(继承超类)的新类称子类。
• Java只支持单重继承,不支持多重继承。
7
继承的层次结构
人
学生
教师
行政人员
本科生
研究生
8
4.2.1 继承的基本语法
[修饰符] class 子类名 extends 父类名{
……
} • ①在Java中严格规定子类只能拥有一个直接父类;
• ②子类可以继承父类的所有属性和方法;(P95?)
面向对象程序设计
第4章 类的封装性、继承性、多态 性及接口
• 4.1 封装性 • 4.2 继承性 • 4.3 多态性
• 4.4 抽象类
• 4.5 接口
• 4.6 内部类
• 4.7 泛型类
1
4.1 封装性
• 目的
– 限制在类的外部对类内部成员进行访问,只通过公共 接口来访问类的成员数据。
– 屏蔽细节:这是程序设计的基本思想,便于程序功能 的扩展和程序的维护。
– public允许来自任何类的访问; – protected允许来自同一包中的任何类以及该 类的任何地方的任何子类的方法访问; – default允许来自同一个包中的类的访问; – private只允许来自该类内部的方法访问,不允 许任何来自该类外部的访问。
13
• 关于成员变量的继承,父类的任何成员变 量都是会被子类继承下去的。这些继承下 来的私有成员虽对子类来说不可见,但子 类仍然可以用父类的方法操作他们。 • 这样的设计有何意义呢?我们可以用这个 方法将我们的成员保护得更好,让子类的 设计者也只能通过父类指定的方法修改父 类的私有成员,这样将能把类保护得更好, 这对一个完整的继承体系是尤为可贵的。
• 如果在一个源程序文件中,声明了若干个 类的话,只能有一个类的权限关键字是 public。这个类的名字应该和程序文件同 名,main方法也应该在这个类中,否则程 序无法执行。
4
4.1.2 类成员的访问控制
• public:在任何地方,只要能访问到该类,即 可访问到该成员。 • protected:该成员允许同一个包或该类的扩 展子类访问。 • 默认:该成员只能由同一个包中的其它类访问。 • private:类中的该成员只能由该类自己的成 员调用,而无法被该类以外的其它类访问。 • 声明局部变量不能包含访问权限修饰符,否则 编译时将检查出错。
– default(默认)
– public(公共)
– protected(保护)
类 类成员
– private(私有)
• 访问修饰符限定了被修饰者的可见性。
3
4.1.1 类的访问控制
• 类的权限有两种:
– 默认(修饰符为空),该类只能被自身所在的 包中的类使用。
– public,该类能被所有包类的类使用。
public class Test { public static void main(String args[ ]) { Son a=new Son(); System.out.println(a.z); System.out.println(a.x); a.printS(a.s); //System.out.println(a.y); } }
class Son extends Father{ int b; int c; public Son(){ super(1); } public Son(int m,int n,int h){ super(m); b=n; c=h; } public void printSon(){ System.out.println(a+","+b+","+c); } }
24
class Father{ int a; public Father(int e){ a=e; } }
public class Test{ public static void main(String args[]){ Son A=new Son(); Son B=new Son(3,2,5); A.printSon(); B.printSon(); } }
18
• 子类隐藏父类的变量只是使之在子类中不 可见,父类的同名变量在子类中仍然占有 自己独立的内存空间。 • 如要访问被隐藏的父类变量,可通过两条 途径实现: • ①使用super.变量名; • ②调用从父类继承的方法操作的是从父类 继承的变量。
19
class Father{ int x=8; void printF(){ System.out.println(x); } } class Son extends Father{ int x=9; void printS(){ System.out.println(x); System.out.println(super.x); } } public class Test{ public static void main(String args[]){ Son a=new Son(); a.printS(); a.printF(); } }
20
4.2.2 super关键字
• super表示对某个类的超类的引用。 • 如子类和超类有同名的域或方法,则:
– super.变量名
– super.方法名()
• 表示引用超类的成员(如无super则表示子 类中的同名成员)
21
继承关系中对成员的访问
• 就近原则:
– 在子类中访问属性和方法时将优先查找自己定义的属性和方法。 如果该成员在本类存在,则使用本类的,否则,按照继承层次的 顺序到其祖先类查找。
14
子类对象的内存
类A A的变量aM 实例a
类A
a的变量aM
实例b
A a=new A( );
A的方法aF
类B
B b=new B( );
继承自类A
B的变量aM B的方法aF
类B
继承的aM b的变量aM
a.aM
a.aF( )
b.aM b.aF( )
15
例:派生子类
Employee
属性: name age salary 方法: upSalary getInfo
class Son extends Father{ String s="Hello,world!"; }
10.0 8 Hello,world!
10
疑问
• 子类只继承父类的非私有成员。(P95) • 继承:特殊类的对象拥有其一般类的全部 属性与服务,称作特殊类对一般类的继承。
– 李代平. 软件工程. 北京: 冶金工业出版社, 2002.8, 146
5
4.1.3 封装性的设计原则
• 基本思想:提供对外的通讯方式,封装内部的实现机制。
– 增加内部实现部分的可替换性;
– 减小类之间的耦合关系,方便模块划分; – 容易保证类内部数据间的一致性,从而提高软件的可靠性。
• 基本原则:
– 类常常是public; – 成员变量常常是private;
– 构造方法一般是public;
– this关键字特指本类的对象引用,使用this访问成员则首先在本类 中查找,如果没有,则到父类逐层向上找。 – super特指访问父类的成员,使用super首先到直接父类查找匹配 成员,如果未找到,再逐层向上到祖先类查找。
Graduate +toString() Student Person +toString()
• ③子类可以修改从父类继承来的成员; • ④子类在继承父类成员的同时还可以创建自己的新成员。 • ⑤在Java中,一个类的定义中即使没有extends声明, 但这个类仍然是一个类的子类,这个特殊的类是 java.lang.Object。
9
class Father{ int x=8; private int y=9; public double z=10.0; void printS(String s){ System.out.println(s); } }
– 用final说明的成员方法为最终方法。
如:public final void printsuper( )
23
4.2.3 构造方法的"继承"
• Java保证当创建一个类的实例时,一定会调用该类的 构造方法,同时,它还保证当创建子类的实例时,父类 的构造方法也同样要被调用。为了保证第二点,Java 必须确保每个构造方法都会调用它父类的构造方法。 • 父类的构造方法构造对象的父类部分,而子类的构造方 法构造子类部分。 • 所以,如果构造方法的第一条可执行语句没有通过this() 或super()显式地调用其它构造方法,那么Java会默认 插入一条方法调用super(),它调用父类中不带参数的 构造方法。如果父类不包括不带参数的构造方法,那么 这个默认的调用就会导致编译错误。
• 封装类
– 大多数变量都是私有的,变量通过他们自己类的方法 修改,其它类都只与一个类中很少的几部分接口; – 若变量或方法为公有,它就是接口的一部分,其它类 可以访问它;若为私有,它是实现的一部分,只有类 自己的成员可以访问它
2
• Java通过访问控制来实现封装性,访问控 制通过4个访问修饰符实现。
this.toString()
在这里 没有 在这里
22
super.toString()
终止继承
• 出于安全性方面的考虑,要避免子类继承超类 的某个方法,可以使用“final”关键字来使继 承终止。 这样使此方法不会在子类中被覆盖 (即子类中不能有和此方法同名的方法)。
– 不能被继承的类称为最终类。 如:final class Last;
• 一个子类对象将总是包含一个完整的父类 对象,即拥有它的全部数据成员和方法。
– Ivor Horton著, 潘晓雷, 于浚泊等译. Java 2入门经典. 北京, 机械工业出版社, 2006.9, 210
11
class A { private int id;
void setId(int i) { id = i; } int getபைடு நூலகம்d() { return id; }
17
例:
class Father{ int x=8; } class Son extends Father{ int x=9; void printS(){ System.out.println(x); } } public class Test{ public static void main(String args[]){ Son a=new Son(); a.printS(); } }
Engineer
Secretary
Manager
属性: allowance 方法: setAllowance getInfo
Director
属性: telephone department 方法: setTel getInfo
16
域的隐藏
• 如果子类中定义了一个与从父类那里继承 来的成员变量完全相同的变量,则父类那 里继承来的成员变量将被隐藏。
}
class B extends A { }
public class Test { public static void main(String[] args) { B b = new B(); b.setId(8); System.out.println(b.getId()); } }
12
• 实际上,public、protected、default、 private和继承没有关系,他们对类成员的 限制只是在成员的可见性上:
构造方法的调用顺序
• ⑴按继承顺序依次调用父类的构造方法, 直到到达本子类。 • ⑵依次执行本子类成员对象的构造方法。
• ⑶最后,执行本子类的构造方法。
26
class Person { public Person() { System.out.print("A"); } public Person(String s) { this(); System.out.print("B"); } } class Student extends Person { public Student() { System.out.print("C"); } } public class Who extends Person { Student student=new Student(); public Who() { super("ok"); System.out.print("E"); } public static void main(String args[]) { Who w = new Who(); } }
– 方法“get”与“set”是 public; – 其它方法需要根据实际的需要而定。
6
4.2 继承性
• 继承也称为派生,是指一个新类可以继承其他 已有类的所有成员,包括成员属性和成员方法。 新类不但保留被继承过来的类的属性和方法, 而且可以根据自身需要对类进行修改,添加新 的成员属性和成员方法。 • 被继承的类称为超类(父类)。
• 从超类派生出来(继承超类)的新类称子类。
• Java只支持单重继承,不支持多重继承。
7
继承的层次结构
人
学生
教师
行政人员
本科生
研究生
8
4.2.1 继承的基本语法
[修饰符] class 子类名 extends 父类名{
……
} • ①在Java中严格规定子类只能拥有一个直接父类;
• ②子类可以继承父类的所有属性和方法;(P95?)
面向对象程序设计
第4章 类的封装性、继承性、多态 性及接口
• 4.1 封装性 • 4.2 继承性 • 4.3 多态性
• 4.4 抽象类
• 4.5 接口
• 4.6 内部类
• 4.7 泛型类
1
4.1 封装性
• 目的
– 限制在类的外部对类内部成员进行访问,只通过公共 接口来访问类的成员数据。
– 屏蔽细节:这是程序设计的基本思想,便于程序功能 的扩展和程序的维护。
– public允许来自任何类的访问; – protected允许来自同一包中的任何类以及该 类的任何地方的任何子类的方法访问; – default允许来自同一个包中的类的访问; – private只允许来自该类内部的方法访问,不允 许任何来自该类外部的访问。
13
• 关于成员变量的继承,父类的任何成员变 量都是会被子类继承下去的。这些继承下 来的私有成员虽对子类来说不可见,但子 类仍然可以用父类的方法操作他们。 • 这样的设计有何意义呢?我们可以用这个 方法将我们的成员保护得更好,让子类的 设计者也只能通过父类指定的方法修改父 类的私有成员,这样将能把类保护得更好, 这对一个完整的继承体系是尤为可贵的。
• 如果在一个源程序文件中,声明了若干个 类的话,只能有一个类的权限关键字是 public。这个类的名字应该和程序文件同 名,main方法也应该在这个类中,否则程 序无法执行。
4
4.1.2 类成员的访问控制
• public:在任何地方,只要能访问到该类,即 可访问到该成员。 • protected:该成员允许同一个包或该类的扩 展子类访问。 • 默认:该成员只能由同一个包中的其它类访问。 • private:类中的该成员只能由该类自己的成 员调用,而无法被该类以外的其它类访问。 • 声明局部变量不能包含访问权限修饰符,否则 编译时将检查出错。
– default(默认)
– public(公共)
– protected(保护)
类 类成员
– private(私有)
• 访问修饰符限定了被修饰者的可见性。
3
4.1.1 类的访问控制
• 类的权限有两种:
– 默认(修饰符为空),该类只能被自身所在的 包中的类使用。
– public,该类能被所有包类的类使用。
public class Test { public static void main(String args[ ]) { Son a=new Son(); System.out.println(a.z); System.out.println(a.x); a.printS(a.s); //System.out.println(a.y); } }
class Son extends Father{ int b; int c; public Son(){ super(1); } public Son(int m,int n,int h){ super(m); b=n; c=h; } public void printSon(){ System.out.println(a+","+b+","+c); } }
24
class Father{ int a; public Father(int e){ a=e; } }
public class Test{ public static void main(String args[]){ Son A=new Son(); Son B=new Son(3,2,5); A.printSon(); B.printSon(); } }
18
• 子类隐藏父类的变量只是使之在子类中不 可见,父类的同名变量在子类中仍然占有 自己独立的内存空间。 • 如要访问被隐藏的父类变量,可通过两条 途径实现: • ①使用super.变量名; • ②调用从父类继承的方法操作的是从父类 继承的变量。
19
class Father{ int x=8; void printF(){ System.out.println(x); } } class Son extends Father{ int x=9; void printS(){ System.out.println(x); System.out.println(super.x); } } public class Test{ public static void main(String args[]){ Son a=new Son(); a.printS(); a.printF(); } }
20
4.2.2 super关键字
• super表示对某个类的超类的引用。 • 如子类和超类有同名的域或方法,则:
– super.变量名
– super.方法名()
• 表示引用超类的成员(如无super则表示子 类中的同名成员)
21
继承关系中对成员的访问
• 就近原则:
– 在子类中访问属性和方法时将优先查找自己定义的属性和方法。 如果该成员在本类存在,则使用本类的,否则,按照继承层次的 顺序到其祖先类查找。
14
子类对象的内存
类A A的变量aM 实例a
类A
a的变量aM
实例b
A a=new A( );
A的方法aF
类B
B b=new B( );
继承自类A
B的变量aM B的方法aF
类B
继承的aM b的变量aM
a.aM
a.aF( )
b.aM b.aF( )
15
例:派生子类
Employee
属性: name age salary 方法: upSalary getInfo
class Son extends Father{ String s="Hello,world!"; }
10.0 8 Hello,world!
10
疑问
• 子类只继承父类的非私有成员。(P95) • 继承:特殊类的对象拥有其一般类的全部 属性与服务,称作特殊类对一般类的继承。
– 李代平. 软件工程. 北京: 冶金工业出版社, 2002.8, 146
5
4.1.3 封装性的设计原则
• 基本思想:提供对外的通讯方式,封装内部的实现机制。
– 增加内部实现部分的可替换性;
– 减小类之间的耦合关系,方便模块划分; – 容易保证类内部数据间的一致性,从而提高软件的可靠性。
• 基本原则:
– 类常常是public; – 成员变量常常是private;
– 构造方法一般是public;
– this关键字特指本类的对象引用,使用this访问成员则首先在本类 中查找,如果没有,则到父类逐层向上找。 – super特指访问父类的成员,使用super首先到直接父类查找匹配 成员,如果未找到,再逐层向上到祖先类查找。
Graduate +toString() Student Person +toString()
• ③子类可以修改从父类继承来的成员; • ④子类在继承父类成员的同时还可以创建自己的新成员。 • ⑤在Java中,一个类的定义中即使没有extends声明, 但这个类仍然是一个类的子类,这个特殊的类是 java.lang.Object。
9
class Father{ int x=8; private int y=9; public double z=10.0; void printS(String s){ System.out.println(s); } }
– 用final说明的成员方法为最终方法。
如:public final void printsuper( )
23
4.2.3 构造方法的"继承"
• Java保证当创建一个类的实例时,一定会调用该类的 构造方法,同时,它还保证当创建子类的实例时,父类 的构造方法也同样要被调用。为了保证第二点,Java 必须确保每个构造方法都会调用它父类的构造方法。 • 父类的构造方法构造对象的父类部分,而子类的构造方 法构造子类部分。 • 所以,如果构造方法的第一条可执行语句没有通过this() 或super()显式地调用其它构造方法,那么Java会默认 插入一条方法调用super(),它调用父类中不带参数的 构造方法。如果父类不包括不带参数的构造方法,那么 这个默认的调用就会导致编译错误。
• 封装类
– 大多数变量都是私有的,变量通过他们自己类的方法 修改,其它类都只与一个类中很少的几部分接口; – 若变量或方法为公有,它就是接口的一部分,其它类 可以访问它;若为私有,它是实现的一部分,只有类 自己的成员可以访问它
2
• Java通过访问控制来实现封装性,访问控 制通过4个访问修饰符实现。
this.toString()
在这里 没有 在这里
22
super.toString()
终止继承
• 出于安全性方面的考虑,要避免子类继承超类 的某个方法,可以使用“final”关键字来使继 承终止。 这样使此方法不会在子类中被覆盖 (即子类中不能有和此方法同名的方法)。
– 不能被继承的类称为最终类。 如:final class Last;
• 一个子类对象将总是包含一个完整的父类 对象,即拥有它的全部数据成员和方法。
– Ivor Horton著, 潘晓雷, 于浚泊等译. Java 2入门经典. 北京, 机械工业出版社, 2006.9, 210
11
class A { private int id;
void setId(int i) { id = i; } int getபைடு நூலகம்d() { return id; }
17
例:
class Father{ int x=8; } class Son extends Father{ int x=9; void printS(){ System.out.println(x); } } public class Test{ public static void main(String args[]){ Son a=new Son(); a.printS(); } }
Engineer
Secretary
Manager
属性: allowance 方法: setAllowance getInfo
Director
属性: telephone department 方法: setTel getInfo
16
域的隐藏
• 如果子类中定义了一个与从父类那里继承 来的成员变量完全相同的变量,则父类那 里继承来的成员变量将被隐藏。
}
class B extends A { }
public class Test { public static void main(String[] args) { B b = new B(); b.setId(8); System.out.println(b.getId()); } }
12
• 实际上,public、protected、default、 private和继承没有关系,他们对类成员的 限制只是在成员的可见性上: