1. 程式人生 > >java三大特性:繼承

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關鍵字進行的。看下面的例子:

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());  
    }  
}  
student是子類,繼承父類person。複用父類的name、age欄位以及相應的方法欄位。體現了student  is  person 的關係。

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工具,為大家將來檢視類資訊準備。