继承
通过继承,简化Student类的定义。
public class Person {
public String name;
public int age;
public Date birthDate;
public String getInfo() {...}
}
public class Student extends Person{
public String school;
}
//Student类继承了父类Person的所有属性和方法,并增加了一个属性school。Person中的属性和方法,Student都可以利用。
- 类继承语法规则:
< 修饰符> class < 子类名称> [extends< 父类>]
{
<属性和方法的声明>
}
- Java只支持单继承,不允许多重继承
– 一个子类只能有一个父类
– 一个父类可以派生出多个子类
- 子类继承了父类,就继承了父类的方法和属性。
- 在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
- 因而,子类通常比父类的功能更多。
- 在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。
- 子类不能继承父类中私有的(private)的成员变量和方法。
访问控制
可以对Java类中定义的属性和方法进行访问控制----规定不同的保护等级:public、protected、default、private
覆盖方法
- 在子类中可以根据需要对从父类中继承来的方法进行改造—覆盖方法(方法的重置、重写),在程序执行时,子类的方法将覆盖父类的方法。
- 覆盖方法必须和被覆盖方法具有相同的方法名称、参数列表和返回值类型。
- 覆盖方法不能使用比被覆盖方法更严格的访问权限。
关键字super
- 在Java类中使用super来引用父类的成分
– super可用于访问父类中定义的属性
– super可用于调用父类中定义的成员方法
– super可用于在子类构造方法中调用父类的构造方法
– super的追溯不仅限于直接父类
例:
public class Person {
privateString name;
private int age;
publicString getInfo() {
return "Name: " + name +"\nage: " + age;
}
}
public class Student extends Person {
private String school = "NewOriental";
publicString getSchool(){ return school; }
public String getInfo() {
// 调用父类的方法
return super.getInfo() +"\nschool:" +school;
}
}
构造方法不能继承
- 子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法
- 在一个Java类中可以通过两种方式获得构造方法
– 使用系统默认的无参数构造方法
– 显式定义一个或多个构造方法
- 一旦显式定义了构造方法,则系统不再提供默认构造方法
调用父类构造方法
- 在子类的构造方法中可使用super(参数列表)语句调用父类的构造方法
- 如果子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法
- 如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错
多态
- 多态—在Java中,子类的对象可以替代父类的对象使用
- 一个变量只能有一种确定的数据类型
- 一个引用类型变量可能指向(引用)多种不同类型的对象
Personp = new Student();
Objecto = new Person();//Object类型的变量o,指向Person类型的对象
o= new Student(); //Object类型的变量o,指向Student类型的对象
父类类型的变量可以指向子类的对象
- 一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Studentm = new Student();
m.school= “pku”; //合法,Student类有school成员变量
Persone = new Student();
e.school= “pku”; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,
因而编译错误。
虚拟方法调用
- 正常的方法调用
Persone = new Person();
e.getInfo();
Student e = new Student();
e.getInfo();
- 虚拟方法调用(多态情况下)
Person e = newStudent();
e.getInfo(); //调用Student类的getInfo()方法
- 编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。——动态绑定
例:
- 方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test{
publicvoid method(Person e) {
//……
e.getInfo();
}
publicstatic void main(Stirng args[]){
Test t = new Test();
Student m = new Student();
t.method(m); //子类的对象m传送给父类类型的参数e
}
}
instanceof 操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
如果x属于类A的子类B,x instanceof A值也为true。
public class Person extends Object {…}
public class Student extends Person {…}
public class Graduate extends Person {…}
-------------------------------------------------------------------
public void method1(Person e) {
if(e instanceof Person)
//处理Person类及其子类对象
if(e instanceof Student)
//处理Student类及其子类对象
if(e instanceof Graduate)
//处理Graduate类及其子类对象
}
对象类型转换
- 基本数据类型的Casting:
小的数据类型可以自动转换成大的数据类型
如long g=20; doubled=12.0f
可以把大的数据类型强制转换(casting)成小的数据类型
如 floate f=(float)12.0 inta=(int)1200L
- 对Java对象的强制类型转换称为造型
– 从子类到父类的类型转换可以自动进行
– 从父类到子类的类型转换必须通过造型(强制类型转换)实现
– 无继承关系的引用类型间的转换是非法的
– 在造型前可以使用instanceof操作符测试一个对象的类型
封装类
- 针对八种基本定义相应的引用类型—封装类
基本数据类型 | 封装类 |
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |