1. 程式人生 > >【Java】繼承、介面、抽象類、多型之間的關係和區別 【一】

【Java】繼承、介面、抽象類、多型之間的關係和區別 【一】

時間對於一個追夢的人來說就是黃金,沒有什麼能阻擋前行的腳步。--致所有和我一樣追逐明天太陽的人
介面的理解:介面是對動作的抽象說動作還不如說功能   抽象類理解:抽象類是對根源的抽象  多型的理解:類載入執行時父類的引用指向子類的物件
抽象大小關係:介面>抽象類
先通過一個例子來有個的概率
人 、學生兩個類
首先我們要確定是否有繼承關係,我們一般講 is a或者has a的關係進行判斷,也就是說學生是人,人包含了學生,這一點要明確。
其次我們要定義父類,定義這一類的特性,如姓名、年齡、性別、膚色等等這樣的共性,學生將會繼承這些屬性,但是每類職業都會有屬於自己的工作,這是我們提煉出來的,對其工作抽象出來處理,讓繼承了人這個類的子類去實現自己的工作方式。與此同時每個類別的職業人都有自己的生活方式,比如學生除了上課,他還去做些兼職、公交司機上完班後還去跑滴滴等等,那麼這時候我們需要使用介面去實現,換句話說除了我們設計的職業之外,他還去幹了什麼事兒,身上還有其他什麼功能這些都是由介面決定的,這就是為什麼說介面是實現多繼承的原因。
換句術語來說介面是設計(需要什麼我去設計什麼)的結果 ,抽象類是重構(覆蓋、重寫)的結果
重構(名詞):對軟體內部結構的一種調整,目的是在不改變"軟體之可察行為"前提下,提高其可理解性,降低其修改成本。
比如一個遊戲的版本升級,對某個功能的bug修復,這個時候就會在實現介面的類裡面進行修復。歸根接底是在類載入程式執行時父類的引用指向了子類的例項化物件,就行成了多型,但是由於java中的只能是單繼承,所以擔任就交給了介面。



闡述各自的概念:
繼承:1、主要是優化程式碼  2、類與類的層級關係(語言是面向物件的,任何時候都可以拿生活中的例子去套用,開發大腦吧)
強調一點,繼承是不要亂用,在面向物件的思想裡面,程式碼應該要有體現,一般用 is a或者has a的關係進行判斷
定義一個【人】 類

package com.physical;
//定義一個抽象類,學生類的根源類就是人
public abstract class Person {
	int idcard;//身份證
	String sname;//姓名
	//定義抽象方法的時候一定要使用關鍵字abstract
	//因為抽象類可有可無抽象方法
	//抽象方法不能有完成操作的實體也就是{}
	abstract void toDoThings();
	//定義一個已實現的方法
	void eatFood() {
		System.out.println("每天一日三餐");
	}
}

學生類繼承人類
 

package com.physical;

public class Student extends Person{
	//學生這個群體繼承了人這個類,子類就隱式添加了父類的成員變數
	//定義了兩個成員變數,職業、學生編號
	//此時學生子類就有了四個成員變數
	String profession;
	int stuid;
	//如果父類沒有顯示的建立建構函式,那麼程式會在載入的時候自動建立一個無參的建構函式
	//當建立類的例項化物件的時候,子類隱式的建構函式會的呼叫父類的隱式建構函式  --一般情況下我們稱構造器
	//父類過顯示的建立了無參的建構函式,如果要建立一個預設物件的時候,子類也必須顯示的建立無引數建構函式
	Student(){
		
	}
	//使用有參的構造函對類成員數初始化
	//無論有多少層的繼承關係,程式的執行順序都是從父類一直到Object類,所有沒有顯示新增繼承關係的類都預設是Object的子類
	//現在想想Java之父一定是個哲學家,真是大神中的大神,膜拜三方
	Student(int idcard,String sname){
		super(idcard,sname);
	}
	//繼承了抽象類的子類必須實現父類的抽象方法,除非繼承的子類也是抽象類
	@Override
	void toDoThings() {
		System.out.println("我叫"+sname+"身份證號是:"+idcard+"是一名"+profession+"學生編號是"+stuid+"每天的工作就是學習");
	}
	//寫到這裡的時候我反問了下自己,父類為什麼要去寫已實現的方法
	//給自己的答案是:父類是所有繼承類的超類,對所有超類實現了普適性,也就是說如果子類沒有重寫父類的方法,那麼所有的物件會預設為是子類的行為
	//如果這裡的eatFood方法我沒顯示的建立,父類的eatFood方法不會像變數那樣載入到子類,這裡要的節點在於物件是個引用型別,所以應該解釋為子類的子類的eatFood()變數會指向父類的eatFood方法地址
	//如果顯示的建立eatFood方法,那麼就會指向student類的地址
	void eatFood() {
		System.out.println("我每天上午七點起床,吃早餐喝牛奶");
		System.out.println("八點一刻左右的時候練會兒瑜伽");
		System.out.println("中午吃點牛肉,碳水化合物很少");
		System.out.println("晚上的時候吃個三分飽");
	}
}

實現的方法

package com.physical;

public class Test {
	public static void main(String[] args) {
		Student stu=new Student(123456789,"Joncky");
		stu.eatFood();
		Person p=new Student();
	}
}

輸出的結果是