Java基礎之:OOP——繼承
面向物件編程OOP(Object Oriented Programming)的三大特征之二:繼承
首先看一個案例,分別創建小學生與研究生類,輸出他們的資訊:
小學生類:
public class Pupil { //小學生類
?
String name;
double score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public void testing() {
System.out.println("小學生考語文...");
}
public void showScore() {
System.out.println("學生名" + name + " 成績=" + score);
}
}
研究生類:
public class Graduate { //研究生
?
String name;
double score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public void testing() {
System.out.println("研究生考的是微積分...");
}
public void showScore() {
System.out.println("學生名 " + name + " 成績=" + score);
}
}
可以看到 在小學生類與研究生類中 ,有大量的內容是重復的,只有 testing() 方法不同,所以我們可以將它們兩個類中共同的屬性或方法抽象出來創建一個Student類,再繼承Student,
繼承介紹
繼承可以解決代碼的復用性問題,讓編程更解決我們人類的思維邏輯,多個類出現相同的屬性/方法時,可以將這些屬性/方法抽象出來,放在一個父類中來定義,所有的子類都不需要再定義這些屬性/方法,只需要繼承(extends)父類即可,

繼承語法
class 子類名 extends 父類名 {}
說明:
1) 子類就會自動擁有父類定義的屬性和方法
2) 父類又叫 超類,基類,
3) 子類又叫派生類,
簡單案例
對上面的小學生類和研究生類進行改進,
Student類:
public class Student { //父類
?
String name;
double score;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public void showScore() {
System.out.println("學生名 " + name + " 成績=" + score);
}
}
Pupil類:
public class Pupil extends Student { //小學生類, 子類
?
public void testing() {
System.out.println("小學生考語文...");
}
}
?
Graduate類:
public class Graduate extends Student{ //研究生 子類
?
public void testing() {
System.out.println("研究生考的是微積分...");
}
}
繼承優點
-
代碼復用性提高了,
-
代碼的擴展性和維護性提高了,
繼承使用細節與注意事項
-
子類繼承了所有的屬性和方法,只是私有的屬性不能直接訪問,需要通過公共方法進行訪問,(封裝的體現)
-
子類沒有繼承父類的構造器,但在子類的構造器中必須呼叫父類的構造器,完成父類的初始化,(例:肯定是先有爺爺再有爸爸最后有兒子)
-
當創建子類時,不管你使用子類的哪個構造方法,默認情況下總會去呼叫父類的無參建構式,如果父類沒有提供無參建構式,則必須在子類的建構式中用 super 去指定使用父類的哪個建構式完成對父類的初始化作業,否則,編譯不會通過,
-
如果希望指定呼叫父類的某個構造方法,需要使用super關鍵字顯式呼叫,
-
無參構造器:super();
-
有一個引數:super(引數);
-
要注意super在使用時,需要放在方法體的第一句位置,
-
-
super() 和 this() 都只能放在構造方法句首,因此這兩個方法不能共存在一個方法中
-
java中所有的類都是Object類的子類
-
子類最多只能有一個直接父類,也就是只能繼承一個父類,(若需要A類繼承B類和C類,則A繼承B,B繼承C),
-
父類構造器的呼叫不限于直接父類!將一直往上追溯直到Object類,同樣的,若子類呼叫父類提供的方法,也不限于直接父類,

簡單案例
import java.util.ArrayList;
?
public class ExtendsDetail {
?
public static void main(String[] args) {
BB bb = new BB();
bb.m1();
}
}
?
class DD {
public DD() {
System.out.println("DD() 被呼叫");
}
}
?
// 子類繼承了所有的屬性和方法,只是私有的屬性不能直接訪問,需要通過公共的方法去訪問
class AA extends DD {
// 屬性
public int n1 = 10;
protected int n2 = 20;
int n3 = 30;
private int n4 = 40;
public int getN4() {
return n4;
}
// public AA() {
// System.out.println("AA() 構造器..");
// }
public AA(String name) {
}
public AA() {
}
public AA(int num) {
//super();
}
}
?
//類的BB繼承 ctrl+t
class BB extends AA { //子類BB 繼承 AA
public void m1() {
System.out.println(n1 + " " + n2 + " " + n3 + " " /*+ n4 */);
System.out.println(getN4());
}
//子類沒有繼承父類的構造器,但必須呼叫父類的構造器, 完成父類的初始化.
//至于呼叫父類的哪個構造器,無所謂,但是一定要呼叫一個
public BB() {
//默認有一句話 super(), 父類的無參構造器
//如果希望指定去呼叫父類的某個構造方法,則顯示的呼叫一下
//super在使用時,需要放在方法體的第一句位置
//super() 和 this() 都只能放在構造方法句首,因此這兩個方法不能共存在一個方法中
super(10);
System.out.println("BB() 構造器..");
}
}
記憶體分析案例
public class ClassTest {
public static void main(String[] args) {
son son = new son();
}
}
?
class Guandpa {
private String name;
public Guandpa(String name) {
super(); //指向 Object();
this.name = name;
}
?
public Guandpa() {
//默認存在super(); 即使不顯式的寫出
this.name = "爺爺";
}
public void show() {
System.out.println("Guandpa:" + name);
}
}
?
class father extends Guandpa{
private String name;
?
public father(String name) {
super();
this.name = name;
}
?
public father() {
super();// 指向 Guandpa();
this.name = "父親";
}
public void show(){
System.out.println("father"+name);
}
}
?
class son extends father{
private String name;
public son(String name) {
super();
//默認存在super();即使不顯式的寫出,
//當我們在father類中 無參構造方法被覆寫時, son子類的構造方法就會報錯,
//因為son子類在構造時 ,會首先呼叫super();
this.name = name;
}
?
public son() {
super(); //指向 father();
this.name = "兒子";
}
public void f1() {
show();
}
}

super關鍵字
super代表父類的參考,用于訪問父類的屬性、方法、構造器
基本語法
-
訪問父類的屬性 , 不能訪問父類的private屬性 [案例] super.屬性名;
-
訪問父類的方法,不能訪問父類的private方法
super.方法名(引數串列);
-
訪問父類的構造器(這點前面用過): super(引數串列);只能放在構造器的第一句,而且只能出現一句
細節說明
-
呼叫父類的構造器 (分工明確, 父類屬性由父類初始化,子類的屬性由子類初始化)
-
當子類中有和父類中的成員(屬性和方法)重名時,為了訪問父類的成員,必須通過super,如果沒有重名,使用super、this、直接訪問是一樣的效果!
-
super的訪問不限于直接父類,如果爺爺類和本類中有同名的成員,也可以使用super去訪問爺爺類的成員;如果多個基類中都有同名的成員,使用super訪問遵循就近原則,A->B->C
super與this

繼承應用案例1
為了代碼方便閱讀這里將各個類寫在了一起,但在實際開發中應該保證一個類一個檔案,所有類在同一個包下,
/**
*
* 撰寫Computer類,包含CPU、記憶體、硬碟等屬性,getDetails方法用于回傳Computer的詳細資訊
* 撰寫PC子類,繼承Computer類,添加特有屬性【品牌brand】 撰寫NotePad子類,繼承Computer類,添加特有屬性【演示color】
* 撰寫Test類,在main方法中創建PC和NotePad物件,分別給物件中特有的屬性賦值,
* 以及從Computer類繼承的屬性賦值,并使用方法并列印輸出資訊
*
*/
public class Test {
public static void main(String[] args) {
PC pc = new PC("intel_i9", "16GB", "1TB", "PCbrand");
NotePad notePad = new NotePad("cpu", "8GB", "128GB", "NotePadcolor");
System.out.println(pc.getDetails());
System.out.println(notePad.getDetails());
}
}
?
//撰寫Computer類,包含CPU、記憶體、硬碟等屬性,getDetails方法用于回傳Computer的詳細資訊
class Computer {
//private + set & get 方法,體現封裝
private String CPU;
private String memory;
private String disk;
public String getCPU() {
return CPU;
}
?
public void setCPU(String cPU) {
CPU = cPU;
}
?
public String getMemory() {
return memory;
}
?
public void setMemory(String memory) {
this.memory = memory;
}
?
public String getDisk() {
return disk;
}
?
public void setDisk(String disk) {
this.disk = disk;
}
?
public String getDetails() {
return "Computer [CPU=" + CPU + ", memory=" + memory + ", disk=" + disk + "]";
}
?
public Computer(String cPU, String memory, String disk) {
super();
CPU = cPU;
this.memory = memory;
this.disk = disk;
}
?
public Computer() {
super();
}
}
?
//撰寫PC子類,繼承Computer類,添加特有屬性【品牌brand】
class PC extends Computer {
private String brand; //private + set & get 方法,體現封裝
public String getBrand() {
return brand;
}
?
public void setBrand(String brand) {
this.brand = brand;
}
?
@Override
public String getDetails() {
return super.getDetails() + "\nPC [brand=" + brand + "]";
}
?
public PC(String cPU, String memory, String disk, String brand) {
super(cPU, memory, disk);
this.brand = brand;
}
}
?
//撰寫NotePad子類,繼承Computer類,添加特有屬性【演示color】
class NotePad extends Computer {
private String color; //private + set & get 方法,體現封裝
public String getColor() {
return color;
}
?
public void setColor(String color) {
this.color = color;
}
?
@Override
public String getDetails() {
return super.getDetails() + "\nNotePad [color=" + color + "]";
}
?
public NotePad(String cPU, String memory, String disk, String color) {
super(cPU, memory, disk);
this.color = color;
}
}

繼承應用案例2
為了代碼方便閱讀這里將各個類寫在了一起,但在實際開發中應該保證一個類一個檔案,所有類在同一個包下,
/**
* 定義一個ManKind類: 成員變數int sex和int salary; ?要求加上兩個引數有參構造
* 方法void manOrWomen():根據sex的值顯示“man”(sex==1)或者“women”(sex==0);
* 方法void employeed():根據salary的值顯示“no job”(salary==0)或者“ job”(salary!=0),
* 定義類Kids繼承ManKind,并包括成員變數int yearsOld; 方法printAge()列印yearsOld的值,
* 在Kids類的main方法中實體化Kids的物件someKid,用該物件訪問其父類的成員變數及方法,
*/
public class HomeWork {
?
public static void main(String[] args) {
Kids kids = new Kids(2,-100,18);
kids.manOrWomen();
kids.employeed();
kids.printAge();
?
}
?
}
?
class ManKind {
private int sex;
private int salary;
public int getSex() {
return sex;
}
?
public void setSex(int sex) {
this.sex = sex;
}
?
public int getSalary() {
return salary;
}
?
public void setSalary(int salary) {
this.salary = salary;
}
?
// 方法void manOrWomen():根據sex的值顯示“man”(sex==1)或者“women”(sex==0);
public void manOrWomen() {
if (sex == 1) {
System.out.println("man");
} else{
System.out.println("women");
}
}
?
// 方法void employeed():根據salary的值顯示“no job”(salary==0)或者“ job”(salary!=0),
public void employeed() {
if (salary == 0) {
System.out.println("no job!");
} else {
System.out.println("job!");
}
}
?
public ManKind(int sex, int salary) {
super();
if(sex != 0 && sex !=1) {
System.out.println("性別輸入內容錯誤,0表示女,1表示男!");
this.sex = 0;
}else {
this.sex = sex;
}
if (salary < 0) {
System.out.println("輸入工資錯誤,默認值1000");
this.salary = 1000;
} else {
this.salary = salary;
}
}
?
public ManKind() {
super();
}
?
}
?
//定義類Kids繼承ManKind,并包括成員變數int yearsOld; ?方法printAge()列印yearsOld的值,
class Kids extends ManKind{
private int yearsOld;
public int getYearsOld() {
return yearsOld;
}
?
public void setYearsOld(int yearsOld) {
this.yearsOld = yearsOld;
}
?
public void printAge() {
System.out.println("年齡:"+yearsOld);
}
?
public Kids(int sex, int salary, int yearsOld) {
super(sex, salary);
this.yearsOld = yearsOld;
}
public static void main(String[] args) {
//在另外一個非public類中 也有一個main時,點擊Run As 會詢問執行哪一個main
Kids kids = new Kids(1,2000,18);
kids.setSex(0);
kids.manOrWomen();
kids.employeed();
kids.printAge();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/228378.html
標籤:Java
