继承
继承(inheritance)是面向对象程序设计中最为重要的特征之一
子类(subclass),父类或超类(superclass)
父类包括所有直接或间接被继承的类
Java支持单继承:一个类只能有一个直接父类
子类继承父类的状态和行为
可以修改父类的状态或重载父类的行为
可以添加新的状态和行为
好处
可以提高程序的抽象程度
实现代码重用,提高开发效率和可维护性
派生子类
Java中的继承是通过extends关键字来实现的
Class Student extends Person{
…
}
如果没有extends子句,则默认该类为java.lang.Object的子类
所有类都是通过直接或间接地继承java.lang.Object得到的
继承关系
继承关系在UML图中,是用一个箭头来表示子类与父类的关系的
相当于is a
类Student从类Person继承,定义如下:
class Student extends Person{
String school;
int score;
Boolean isGood(){
return score>80;
}
}
字段
1.字段的继承
子类可以继承父类的所有字段
Student自动具有Person的属性(name,age)
2.字段的隐藏
子类重新定义一个与从父类那里继承来的域变量完全相同的变量,成为域的隐藏。域的隐藏在实际编程中用得较少。
3.字段的添加
在定义子类时,加上新的域变量,就可以使子类比父类多一些属性。如:
class Student extends Person{
String school;
int score;
}
方法
1.方法的继承
父类的非私有方法也可以被子类自动继承。如Student自动继承Person的方法sayHello和isOlderThan
2.方法的覆盖(Override)(修改)
子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖(Override)
@Override
@Override//JDK1.5以后可以用这个注记来表示(不用也是可以的)
void sayHello(){
System.out.println(“Hello! My name is ”+name+ “. My school is ”+school);
}
通过方法的覆盖,能够修改对象的同名方法的具体实现方法
3.方法的添加
子类可以添加一些新方法,以针对子类实现相应的功能
如,在类Student中,加入一个方法,对分数进行判断:
boolean isGoodStudent(){
return score>=90;
}
4.方法的重载
一个类中可以有好几个同名的方法,这称为方法的重载(Overload)。同时,还可以重载父类的同名方法。与方法覆盖不同的是,重载不要求参数类型列表相同。重载的方法实际是新加的方法。
如,在类Student中,重载一个名为sayHello的方法:
void sayHello(Student another){
System.out.println(“Hi!”);
if(school.equals(another.school))
System.out.println(“Schoolmates”);
}
super的使用
1.使用super访问父类的域和方法
注意:正是由于继承,使用this可以访问父类的域和方法。但有时为了明确地指出父类的域和方法,就要用关键字super。
例如:父类Student有一个域age,在子类Student中用age,this.age,super.age,来访问时完全一样的:
void testThisSuper(){
int a;
a=age;
a=this.age;
a=super.age;
}
当然,使用super不能访问在子类中添加的域或方法。
有时需要使用super以区别同名的域或方法
- 使用super可以访问被子类所隐藏了的同名变量
- 又如,当覆盖父类的同名方法的同时又要调用父类,就必须使用super。如:
void sayHello(){
super.sayHellpo();
System.out.println(“My school is ”+school);
}
在覆盖父类的方法的同时,又利用已定义好的父类的方法
2.使用父类的构造方法
构造方法是不能继承的
比如,父类Person有一个构造方法Person(String,int),不能说子类Student也自动有一个构造方法Student(String,int)。
但是,子类在构造方法中,可以用super来调用父类的构造方法
Student(String name, int age, String school){
super(name,age);
this.school=school;
}
使用时,super()必须放在第一句
有关构造方法更详细的讨论,参见后面的笔记。
父类对象与子类对象的转换
类似于基本数据类型数据之间的强制类型转换,存在继承关系的父类对象和子类对象之间也可以在一定条件下相互转换。
1.子类对象可以被视为其父类对象的一个对象
如一个Student对象也是一个Person对象
2.父类对象不能被当做其某一个子类的对象
3.如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用其子类对象作为实际参数
4.如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转换(casting)成子类对象的引用
Person p1=new Person(“Liming”,50);
Person p2=new Student(“Zhangyi”,20, “THU”);
Student s2=(Student)p2;
Student s3=(Student)p;//编译可以过,实际运行会出问题。
Person[ ] manypeople=new Person[100];
manypeople[0]=new Person(“Li”,18);
manypeople[1]=new Student(“Wang”,18, “PKU”);