1. 程式人生 > >c的回撥函式與java中抽象函式,介面函式,抽象類簡單理解

c的回撥函式與java中抽象函式,介面函式,抽象類簡單理解

先了解c語言的回撥函式,舉個簡單例項步步深入,比如A程式提供給B程式使用,但是A想要呼叫B的程式碼,這樣各自不同功能由B實現即可。
例項1

A:

extern int get_B_data();
void A_data_handle(){
	printf("%d\n",get_B_data());
}
B:
int get_B_data(void){
	xxx
	return xx;
}
這個程式只是簡單實現到沒有什麼問題,當系統複雜了後問題就會慢慢顯現出來。
1.某天A改了其中一個這樣的函式,B就必須跟著修改,程式碼粘連性太強了
2.B可能只用到其中應這樣的函式,其他用不上,A執行到沒有這樣實現的函式,肯定會crash掉
那麼怎麼改進呢?回撥函式應運而生了
例項2
A:
typedef int (*data_cb_t)(void);
data_cb_t callback = NULL;
void init_cb(data_cb_t cb){
	callback = cb;
}
void A_data_handle(){
	if(callback){
		printf("%d\n",callback());
	}
	else{
		printf("callback()=NULL\n");
	}
}
B:
int create_data(void){
	xxx
	return xx;	
}
inti_cb(create_data);

這樣二者程式就相對獨立些了。


===================================================================
下面說的java的抽象函式和介面,其實基本機理和c語言的回撥函式很相似。下面分析各自有什麼相同和不同之處:


【抽象函式】
先來理解抽象函式,抽象函式中最重要的就是抽象二字,抽象簡單理解為虛的不實在的空的。
1. 需要去填充它的這樣的抽象函式,如何理解填充?也就是由子類來實現它,為什麼要讓子類來實現,原因是這個功能的實現不是統一程式碼,所以將這個自由權交給子類處理。
例項3
abstract class Animal{  
	public abstract void sounds();  
} 

class cat extends Animal{
	@Override
	void sounds() {
		System.out.println("喵喵");
	}
}
class dog extends Animal{
	@Override
	void sounds() {
		System.out.println("旺旺");
	}
} 
2.也可理解為c中的回撥函式。那怎麼理解回撥呢?  也就是父類中要想呼叫子類實現程式碼或者其他程式碼想要呼叫一個統一的方法。
例項4
abstract class Animal{
  abstract void sounds();
  void behavior(String cmd){
  	if(cmd.equals("come here")){
  		sounds();
  	}
  }
}
這樣將程式碼的實現和程式碼呼叫分離開來,各自相互獨立,方便以後的程式碼管理和重構。

【介面函式】
介面函式和抽象函式功能都是類似的,既然有了抽象函式可以實現回撥這樣的功能,為什麼還要有介面函式這樣的東西呢?
原因在於抽象函式實現在子類中,子類只能繼承一個類才能實現抽象函式,那問題來了。
我要實現幾個類中這個抽象函式,那不就不行了嗎? 是的,所以就產生了介面這樣的機制,一個子類可以實現很多個介面。可以這樣理解抽象函式使縱向的,介面函式使橫向的,抽象函式是一條線,介面函式是一個面,抽象函式是父親那裡來的,介面是叔叔伯伯那裡來的。

例項5
class ccc{
	interface a{
		void run();
	}
}
class ddd{
	interface d{
		void action();
	}
}
class test implements ccc.a, ddd.d {
	public void action() {
		
	}
	public void run() {
		
	}
}
【抽象類】
抽象簡單理解為虛的不實在的空的,所以該類當然就不能拿去建立物件了,需要子類繼承他,然後子類建立物件就有了抽象類的屬性和方法了。