關鍵字 extends 表示 繼承。
- 已存在的類 稱為 超類(superclass)、基類(base class)、父類(parent class)
- 新類 稱為 子類(subclass)、派生類(derived class)、孩子類(child class)
子類比超類擁有的功能更加豐富。在通過擴充超類定義子類的時候,僅需要指出子類與超類的不同之處。
- 子類能繼承父類中由public、protected修飾的執行個體域和方法;
- 當在同一個包下,子類可以繼承父類中的default修飾的執行個體域和方法;
- 子類不能繼承父類中private修飾的執行個體域和方法。
子類執行個體化時會先在記憶體中開辟其從父類中繼承的所需空間。
示例:
建立People類
public class People {
private String name;
private int age;
private int sex;
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 int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public void run(){
System.out.println("people run");
}
public People(String name, int age, int sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public People() {
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
建立Student類
public class Student extends People{
private String studentNum;
private String schoolName;
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getStudentNum() {
return studentNum;
}
public void setStudentNum(String studentNum) {
this.studentNum = studentNum;
}
public Student(String studentNum, String schoolName, String name, int age, int sex) {
super(name, age, sex);
this.studentNum = studentNum;
this.schoolName = schoolName;
}
public Student(){
}
public void run() {
System.out.println("student run");
}
@Override
public String toString() {
return "Student{" +
"studentNum='" + studentNum + '\'' +
", schoolName='" + schoolName + '\'' +
'}' + super.toString();
}
}
示例一:
建立一個Main類
public class Main {
public static void main(String[] args) {
People people = new People("zhangsan",20,1);
Student student = new Student("111111","xiaoxue","xiaoming",15,1);
people.run();
student.run();
}
}
執行結果:
people run
student run
結果分析:
在main方法中,通過
People people = new People();
可以建立一個People對象,通過
Student student = new Student();
可以建立一個Studeng對象。Student類繼承了People類,此時對象student在記憶體中有從People類繼承過來的name,age,sex這三個執行個體域(不能直接通路,在類中定義方法時,也不能通路,隻能通過通路器、構造器),同時擁有Student類中的studentNum、schoolName這兩個執行個體域(在類中定義方法時,可以直接通路);對象student可以調用能從People類中繼承來的方法,也可以調用Student類定義的方法;有一點需要注意,在People類中定義了run方法,在Student類中也定義了run方法,此時Student類中的run方法将重寫(覆寫)父類中的run方法,對象student調用run方法将調用Student類中的run方法。
示例二:
在main方法中,寫這麼一段代碼
People people = new Student();
對象people隻能調用People類中的方法,不會報錯。這是因為父類類型對象可以引用子類類型對象,反之
Student student = new People();
,編譯器将報錯。但對象people在記憶體卻開辟一個Student對象的空間,卻隻能使用People類中的方法,而通路不到Student類中的方法。
Main方法:
public class Main {
public static void main(String[] args) {
People people = new Student();
people.setName("zhangsan");
people.setAge(20);
people.setSex(1);
System.out.println(people);
}
}
執行結果:
Student{studentNum='null', schoolName='null'}People{name='zhangsan', age=20, sex=1}
結果分析:
在main方法中,如果對象people調用Student中自己的方法,将會報錯。因為它隻能調用People類定義的方法,而toString方法在People類中進行了重寫,在Student類中也進行了重寫,而people對象所引用的是一個Student對象,是以它所調用的toString方法将是被Student類重寫的方法。
示例三:
在main方法中,對上一個示例的對象people進行強制轉換
Student student = (Student)people;
此時對象student将可以調用Student類中的方法,也可以調用People類中的方法。因為對象people實際指向的是Student對象,是以可以将其強制轉化成Student對象。
但是,當對象people指向的是People對象時,再對對象people對象進行Student強制轉換将會報錯。
總結:
簡單來說,
People people = new Student();
就是将對People的描述應用到Student上,該描述不包括Student中自有的部分,是以對象people調用不了。在對它做強制轉換之後,
Student student = (Student)people;
也就是将Student的描述應用到對象people上,因為對象people本身就引用的是Student對象,是以該描述将可以完全描述,對象student也就可以調用到Student類的方法。
而
Student student = new People();
相當于是用對Student的描述來描述People,因為Student繼承People,故對Student的描述多于對People的描述,故編譯器将會報錯。