java三大特性:繼承
1.什麼是繼承?
2.為什麼繼承?
3.怎麼繼承?
4.繼承需要注意一些什麼?
最後:一個有趣的demo((使用工具classpy.jar))
1.多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那麼多個類無需再定義這些屬性和行為,只要繼承那個類即可。從個人角度看,繼承更多的是描述類與類之間的關係。描述的是一種 is a 的關係,不能為了繼承而繼承。
2.當兩個類在現實世界在上有客觀聯絡,在類中有相同的屬性和方法時,我們可以通過繼承來實現需要的類。這樣做 1.提高了程式碼的複用性2.提高了程式碼的可維護性3.為將來的多型埋下了伏筆(做好了前提)
public class Empolyee { private String name; private int salary; public Empolyee(String name, int salary) { this.name = name; this.salary = salary; } public String getDetails(){ return "Name:"+name+"\nSalary"+salary; } } public class Manager extends Empolyee{ private String department; public Manager(String name, int salary,String department) { super(name, salary); this.department = department; } public String getDetails(){ return super.getDetails()+"\nDepartment"+department; } }
3.繼承是通過extends關鍵字進行的。看下面的例子:
student是子類,繼承父類person。複用父類的name、age欄位以及相應的方法欄位。體現了student is person 的關係。class Person{ private String name; private int age; public void setName(String name){ this.name = name; } public void setInt(int age){ this.age = age; } public String getName(){ return this.name; } public int getAge(){ return this.age; } } class student extends Person{ //此處不新增任何程式碼 } public class ExtDemo{ public static void main(String args[]){ Student stu = new Student(); stu.setName("張三"); set.setAge(30); System.out.println(stu.getName()+stu.getAge()); } }
4.需要注意構造方法、成員許可權和方法重寫。
(1)成員許可權:訪問許可權控制符
作用: 用於控制被修飾變數、方法、類的可見範圍.
public 的訪問級別是最高的,其次是 protected、預設和 private.
成員變數和成員方法可以處於4個訪問級別中的一個:公開、受保護、預設或私有.
存在繼承關係時,父類不可以是 private,因為子類無法繼承
頂層類可以處於公開或預設級別,頂層類不能被 protected 和 private 修飾.
區域性變數不能被訪問控制修飾符修飾 .
下圖是在不同情況下各種許可權修飾符的作用範圍:(子父類的訪問許可權著重看第三行
總結:在不同包下面能夠訪問的許可權修飾符只有:public與protected,但是protected必須要有繼承關係才能訪問。
(2)方法重新(方法覆蓋):注意與方法過載的區別
方法重寫:在繼承關係中,子類重新父類中的某個方法。對於方法的返回值,引數個數,引數型別都和父類一模一樣。
方法過載 : 同一個類中出現同名函式,引數列表不同,返回值型別無關。僅僅是函式名相同而已。
(3)構造方法:java 中的構造方法是分層初始化,看下面的例子。
class Fu {
static {
System.out.println("靜態程式碼塊Fu");
}
{System.out.println("構造程式碼塊Fu");}
public Fu() {
System.out.println("構造方法Fu");
}
}
class Zi extends Fu {
static {
System.out.println("靜態程式碼塊Zi");
}
{System.out.println("構造程式碼塊Zi");}
public Zi() {
System.out.println("構造方法Zi");
}
}
Zi z = new Zi(); 請執行結果。
1.遇到Zi z= new Zi();會先將Fu.class和zi.class分別載入到記憶體,在建立物件,當fu.class載入到記憶體父類的靜態程式碼會隨著Fu.class一起載入,當zi.class載入到記憶體,子類的講臺程式碼會隨著zi.class一起載入。所以第一個輸出,靜態程式碼塊Fu,第二個輸出靜態程式碼快 Zi
2.走zi的構造方法,因為java是分層初始化的,先初始化父類,再初始化子類,所以先走的父類構造,但是在執行父類構造時,發現父類有構造程式碼,構造程式碼塊是優先於構造方法執行的。所以第三個輸出構造程式碼塊Fu,第四個輸出構造方法Fu
3.Fu類初始化結束,子類初始化,第五個輸出構造程式碼塊Zi,構造方法Zi
輸出結果:
靜態程式碼塊:Fu
靜態程式碼塊:Zi
構造程式碼塊:Fu
構造方法:Fu
構造程式碼塊:Zi
構造方法:Zi
5.一個有趣的demo來展示java中的繼承(使用工具classpy.jar)
public class Empolyee {
private String name;
private int salary;
public Empolyee(String name, int salary) {
this.name = name;
this.salary = salary;
}
public String getDetails(){
return "Name:"+name+"\nSalary"+salary;
}
}
public class Manager extends Empolyee{
private String department;
public Manager(String name, int salary,String department) {
super(name, salary);
this.department = department;
}
public String getDetails(){
return super.getDetails()+"\nDepartment"+department;
}
}
public class TestSuper {
public static void main(String[] args) {
Manager m =new Manager("Tom", 100, "IT");
System.out.println(m.getDetails());
}
}
1.Employee的成員變數私有,在Manager類中沒有繼承。如下圖:圖1和圖2是對兩個類位元組碼的詳細解釋。可以看出來對於private成員,並未繼承。
(2)程式能正常執行,輸出項中 姓名、工資、部門資訊健全。是 因為java進行類構造時候,先構造父類再構造子類,我們使用super()呼叫了父類的成員變數和方法。
(3)本demo主要向讀者推薦classpy.jar工具,為大家將來檢視類資訊準備。