一、继承(Inheritence) :
Java 是单继承的,意味着一个类只能从另一个类继承。(被继承的类叫做父类【基类,base class 】,继承的类叫做子类),java中的继承使用 extends 关键字。
语法:
class 父类{} //定义父类
class 子类 extends 父类{}//使用extends关键字实现继承
注意:1. java中,只允许多层继承,而不能多重继承。
在Java中只允许单继承,不能使用多重继承,即一个子类只能继承一个父类。但是允许进行多层继承,即一个子类可以有一个父类,一个父类还可以有一个父类。
2. 子类是不能直接访问父类中的私有成员的,子类可以调用父类中的非私有方法,但是不能直接调用父类中的私有成员。
二、继承的进一步研究
1. 子类对象实例化:子类对象在实例化之前必须首先调用父类中的构造方法后在调用子类自己的构造方法。
例子:
//子类对象实例化过程
class Person{
private String name;
private int age;
public Person(){
System.out.println("父类Person中的构造方法");
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
};
class Student extends Person{
private String school; //Student是Person的子类
public Student(){
//隐藏的super方法,加与不加此语句效果相同。
//此语法表示子类可以直接使用super()调用父类中的无参构造
super();
System.out.println("子类Student中的构造方法。");
}
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school = school;
}
};
public class ExtDemo04{
public static void main(String args[]){
// 子类对象实例化必须先调用父类对象的构造方法,
// 然后再调用子类对象的构造方法
Student stu = new Student();
stu.setName("Jerry"); //此时访问的方法是父类中的,子类中并没有定义
stu.setAge(25); //此时访问的方法是父类中的,子类中并没有定义
stu.setSchool("武汉大学"); //此时的方法是在子类中定义的
System.out.println("姓名:" + stu.getName() +
",年龄:" + stu.getAge() + ",学校:" + stu.getSchool());
}
}
程序运行结果:
>java ExtDemo04
父类Person中的构造方法
子类Student中的构造方法。
姓名:Jerry,年龄:25,学校:武汉大学
2. 方法的覆写
概念:方法覆写是指子类定义了与父类中同名的方法。
·在方法覆写时必须考虑权限,既被子类覆写的方法不能拥有比父类方法更加严格的访问权限,可以是相等的访问权限。
·大小关系:private < default < public。所以,如果在父类中使用public定义方法,则子类的访问权限必须是public。
//方法覆写
class Person{
void print(){ //定义一个默认访问权限的方法
System.out.println("Person --> void print()");
}
}
class Student extends Person{
public void print(){ //覆写父类中的方法,扩大了权限
System.out.println("Student --> void print(){}");
}
}
public class OverrideDemo01{
public static void main(String args[]){
new Student().print(); //此处执行的是被覆盖写过的方法
}
}
程序执行结果:
Student --> void print(){}
3. 使用 super 关键字在子类的方法中访问父类的方法
//调用父类中被子类覆写过的方法
class Person{
void print(){ //定义一个默认访问权限的方法
System.out.println("Person --> void print()");
}
}
class Student extends Person{
public void print(){ //覆写父类中的方法,扩大了权限
super.print(); //调用父类中的print()方法
System.out.println("Student --> void print(){}");
}
}
public class OverrideDemo02{
public static void main(String args[]){
new Student().print(); //此处执行的是被覆盖写过的方法
}
}
程序运行结果:
Person --> void print(){}
Student --> void print(){}
注意:方法覆写是从 private 变成 default 不算是方法的覆写。
4. 属性的覆写
//属性覆写
class Person{
public String info = "MLDN"; //定义一个公共属性
}
class Student extends Person{
public String info = "SDD"; //此属性与父属性中的属性名称一致
public void print(){
System.out.println("父类中的属性:" + super.info); //访问父类中的info属性
System.out.println("子类中的属性:" + this.info); //访问本类中的info属性
}
}
public class OverrideDemo05{
public static void main(String args[]){
new Student().print();
}
}
5. 方法的重载 与 覆写 的区别
作用:使用super关键字可以调用父类中的构造方法、属性、方法方法。
super调用父类中的指定构造方法要求:与this调用构造方法一样,语句必须放在子类构造方法首行。
this和super调用构造方法时不能同时出现,因为两者调用构造方法时都必须放在构造方法的首行。另外还需要注意的是,无论子类如何操作,最终必须先调用父类中的构造方法。
//使用super调用父类中的指定构造方法
class Person{
private String name;
private int age;
public Person(String name, int age){ //通过构造方法设置name和age
this.SetName = name;
this.SetAge = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
public String getInfo(){ //信息输出
return "姓名:" + this.getName() + ",年龄:" + this.getAge();
}
};
class Student extends Person{
private String school; //Student是Person的子类
public Student(String name, int age, String scholl){
super(name, age); //指定调用父类中的构造方法
this.setSchool(scholl);
}
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school = school;
}
public String getInfo(){
return super.getInfo() + ",学校:" + this.getSchool() //扩充父类中的方法
}
};
public class SuperDemo01{
public static void main(Sting args[]){
Student stu = new Student("张三", 30, "清华大学");
System.out.println(stu.getInfo()); //打印信息,调用覆写过的方法
}
}
7. 关于继承的注意事项
a) 构造方法不能被继承;
b) 方法和属性可以被继承;
c) 子类的构造方法隐式地调用父类的不带参数的构造方法;
d) 当父类没有不带参数的构造方法时,子类需要使用super 来显式地调用父类的构造方法,super 指的的父类的引用;
e) super 关键在必须是构造方法中第一行语句。