java介面回調
1. java里的「回調」是什麼意思
普遍意義上的回調涉及到兩個參與單位,可以是兩個對象,兩個線程,兩個java虛擬機,兩個服務等等。
回調是指,兩個參與單位A與B,A的某個方法(或服務)調用B的方法(或者服務),它需要B的一個回應(數據),但是B不會在方法返回時立即給出回應,可能需要一些耗時的處理,在一段時間後在另一個地方產生這個回應。這時,A需要提供一個回調方法(或服務),來處理這個回應。供B調用,這時的調用的作用類似於方法立即返回回應的作用。
2. Java 什麼是回調
所謂回調,就是客戶程序Client調用服務程序Service中的某個方法A,然後Service又在某個時候反過來調用Client中的某個方法B,對於Client來說,這個B便叫做回調函數
回調實現的步驟
1、定義回調介面和回調方法
2、Client實現回調介面和回調方法,並在Client中包含Service引用,通過引用調用Servie中的方法並且必須傳入一個當前對象Client(因為當前對象實現了CallBack介面所以也屬於介面對象)
3、在Service中定義一個介面對象並在方法中對初始化(將Client傳過來的當前對象賦值給介面對象),通過介面對象調用介面中方法(調用的Client實現的介面方法)
4、測試
3. 有關介面回調的java題,求解。
下面是UnitPrice介面代碼:
public interface UnitPrice {
public double unitprice();
}
下面是電視機類代碼:
public class Television implements UnitPrice {
@Override
public double unitprice() {
return 3500d;
}
}
下面是計算機類代碼:
public class Computer implements UnitPrice {
@Override
public double unitprice() {
return 7800d;
}
}
下面是手機類代碼:
public class Mobile implements UnitPrice {
@Override
public double unitprice() {
return 2500d;
}
}
下面是公共類代碼:
import java.util.Scanner;
public class Common {
static double get(UnitPrice u) {
return u.unitprice();
}
@SuppressWarnings("resource")
public static void main(String[] args) {
System.out.print("請輸入電視機的銷售個數:");
Scanner scanner = new Scanner(System.in);
int television_num = scanner.nextInt();
System.out.print("請輸入計算機的銷售個數:");
scanner = new Scanner(System.in);
int computer_num = scanner.nextInt();
System.out.print("請輸入手機的銷售個數:");
scanner = new Scanner(System.in);
int mobile_num = scanner.nextInt();
double television_price = television_num * (get(new Television()));
System.out.println("電視機的銷額是:" + television_price);
double computer_price = computer_num * (get(new Computer()));
System.out.println("計算機的銷額是:" + computer_price);
double mobile_price = mobile_num * (get(new Mobile()));
System.out.println("手機的銷額是:" + mobile_price);
System.out.println("總銷額是:" + (television_price + computer_price + mobile_price));
scanner.close();
}
}
下面是執行後的效果截圖:
麻煩您看一下,是否能夠滿足要求。
4. java設計模式-回調、事件監聽器、觀察者模式
轉自( https://my.oschina.net/u/923324/blog/792857 )
背景
關於設計模式,之前筆者寫過工廠模式,最近在使用gava ListenableFuture時發現事件監聽模型特別有意思,於是就把事件監聽、觀察者之間比較了一番,發現這是一個非常重要的設計模式,在很多框架里扮演關鍵的作用。
回調函數
為什麼首先會講回調函數呢?因為這個是理解監聽器、觀察者模式的關鍵。
什麼是回調函數
所謂的回調,用於回調的函數。 回調函數只是一個功能片段,由用戶按照回調函數調用約定來實現的一個函數。 有這么一句通俗的定義:就是程序員A寫了一段程序(程序a),其中預留有回調函數介面,並封裝好了該程序。程序員B要讓a調用自己的程序b中的一個方法,於是,他通過a中的介面回調自己b中的方法。
舉個例子:
這里有兩個實體:回調抽象介面、回調者(即程序a)
回調介面(ICallBack )
public interface ICallBack {
public void callBack();
}
回調者(用於調用回調函數的類)
public class Caller {
}
回調測試:
public static void main(String[] args) {
Caller call = new Caller();
call.call(new ICallBack(){
控制台輸出:
start...
終於回調成功了!
end...
還有一種寫法
或實現這個ICallBack介面類
class CallBackC implements ICallBack{
@Override
public void callBack() {
System.out.println("終於回調成功了!");
}
}
有沒有發現這個模型和執行一個線程,Thread很像。 沒錯,Thread就是回調者,Runnable就是一個回調介面。
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("回調一個新線程!");
}}).start();
Callable也是一個回調介面,原來一直在用。 接下來我們開始講事件監聽器
事件監聽模式
什麼是事件監聽器
監聽器將監聽自己感興趣的事件一旦該事件被觸發或改變,立即得到通知,做出響應。例如:android程序中的Button事件。
java的事件監聽機制可概括為3點:
java的事件監聽機制涉及到 事件源,事件監聽器,事件對象 三個組件,監聽器一般是介面,用來約定調用方式
當事件源對象上發生操作時,它將會調用事件監聽器的一個方法,並在調用該方法時傳遞事件對象過去
事件監聽器實現類,通常是由開發人員編寫,開發人員通過事件對象拿到事件源,從而對事件源上的操作進行處理
舉個例子
這里我為了方便,直接使用jdk,EventListener 監聽器,感興趣的可以去研究下源碼,非常簡單。
監聽器介面
public interface EventListener extends java.util.EventListener {
//事件處理
public void handleEvent(EventObject event);
}
事件對象
public class EventObject extends java.util.EventObject{
private static final long serialVersionUID = 1L;
public EventObject(Object source){
super(source);
}
public void doEvent(){
System.out.println("通知一個事件源 source :"+ this.getSource());
}
}
事件源
事件源是事件對象的入口,包含監聽器的注冊、撤銷、通知
public class EventSource {
//監聽器列表,監聽器的注冊則加入此列表
private Vector<EventListener> ListenerList = new Vector<EventListener>();
//注冊監聽器
public void addListener(EventListener eventListener){
ListenerList.add(eventListener);
}
//撤銷注冊
public void removeListener(EventListener eventListener){
ListenerList.remove(eventListener);
}
//接受外部事件
public void notifyListenerEvents(EventObject event){
for(EventListener eventListener:ListenerList){
eventListener.handleEvent(event);
}
}
}
測試執行
public static void main(String[] args) {
EventSource eventSource = new EventSource();
}
控制台顯示:
通知一個事件源 source :openWindows
通知一個事件源 source :openWindows
doOpen something...
到這里你應該非常清楚的了解,什麼是事件監聽器模式了吧。 那麼哪裡是回調介面,哪裡是回調者,對!EventListener是一個回調介面類,handleEvent是一個回調函數介面,通過回調模型,EventSource 事件源便可回調具體監聽器動作。
有了了解後,這里還可以做一些變動。 對特定的事件提供特定的關注方法和事件觸發
public class EventSource {
...
public void onCloseWindows(EventListener eventListener){
System.out.println("關注關閉窗口事件");
ListenerList.add(eventListener);
}
}
public static void main(String[] args) {
EventSource windows = new EventSource();
/**
* 另一種實現方式
*/
//關注關閉事件,實現回調介面
windows.onCloseWindows(new EventListener(){
}
這種就類似於,我們的窗口程序,Button監聽器了。我們還可以為單擊、雙擊事件定製監聽器。
觀察者模式
什麼是觀察者模式
觀察者模式其實原理和監聽器是一樣的,使用的關鍵在搞清楚什麼是觀察者、什麼是被觀察者。
觀察者(Observer)相當於事件監器。有個微博模型比較好理解,A用戶關注B用戶,則A是B的觀察者,B是一個被觀察者,一旦B發表任何言論,A便可以獲得。
被觀察者(Observable)相當於事件源和事件,執行事件源通知邏輯時,將會回調observer的回調方法update。
舉個例子
為了方便,同樣我直接使用jdk自帶的Observer。
一個觀察者
public class WatcherDemo implements Observer {
@Override
public void update(Observable o, Object arg) {
if(arg.toString().equals("openWindows")){
System.out.println("已經打開窗口");
}
}
}
被觀察者
Observable 是jdk自帶的被觀察者,具體可以自行看源碼和之前的監聽器事件源類似。
主要方法有
addObserver() 添加觀察者,與監聽器模式類似
notifyObservers() 通知所有觀察者
類Watched.java的實現描述:被觀察者,相當於事件監聽的事件源和事件對象。又理解為訂閱的對象 主要職責:注冊/撤銷觀察者(監聽器),接收主題對象(事件對象)傳遞給觀察者(監聽器),具體由感興趣的觀察者(監聽器)執行
/**
}
測試執行
public static void main(String[] args) {
Watched watched = new Watched();
WatcherDemo watcherDemo = new WatcherDemo();
watched.addObserver(watcherDemo);
watched.addObserver(new Observer(){
@Override
public void update(Observable o, Object arg) {
if(arg.toString().equals("closeWindows")){
System.out.println("已經關閉窗口");
}
}
});
//觸發打開窗口事件,通知觀察者
watched.notifyObservers("openWindows");
//觸發關閉窗口事件,通知觀察者
watched.notifyObservers("closeWindows");
控制台輸出:
已經打開窗口
已經關閉窗口
總結
從整個實現和調用過程來看,觀察者和監聽器模式基本一樣。
有興趣的你可以基於這個模型,實現一個簡單微博加關注和取消的功能。 說到底,就是事件驅動模型,將調用者和被調用者通過一個鏈表、回調函數來解耦掉,相互獨立。
「你別來找我,有了我會找你」。
整個設計模式的初衷也就是要做到低耦合,低依賴。
再延伸下,消息中間件是什麼一個模型? 將生產者+服務中心(事件源)和消費者(監聽器)通過消息隊列解耦掉. 消息這相當於具體的事件對象,只是存儲在一個隊列里(有消峰填谷的作用),服務中心回調消費者介面通過拉或取的模型響應。 想必基於這個模型,實現一個簡單的消息中間件也是可以的。
還比如gava ListenableFuture,採用監聽器模式就解決了future.get()一直阻塞等待返回結果的問題。
有興趣的同學,可以再思考下觀察者和責任鏈之間的關系, 我是這樣看的。
同樣會存在一個鏈表,被觀察者會通知所有觀察者,觀察者自行處理,觀察者之間互不影響。 而責任鏈,講究的是擊鼓傳花,也就是每一個節點只需記錄繼任節點,由當前節點決定是否往下傳。 常用於工作流,過濾器web filter。
5. JAVA中 介面是什麼 介面的回調是什麼
Java介面是一系列方法的聲明,是一些方法特徵的集合,一個介面只有方法的特徵沒有方法的實現,因此這些方法可以在不同的地方被不同的類實現,而這些實現可以具有不同的行為(功能)。
兩種含義:一,Java介面,Java語言中存在的結構,有特定的語法和結構;二,一個類所具有的方法的特徵集合,是一種邏輯上的抽象。前者叫做「Java介面」,後者叫做「介面」。
介面回調是指:可以把使用某一介面的類創建的對象的引用賦給該介面聲明的介面變數,那麼該介面變數就可以調用被類實現的介面的方法。實際上,當介面變數調用被類實現的介面中的方法時,就是通知相應的對象調用介面的方法,這一過程稱為對象功能的介面回調。看下面示例。interface People{ void peopleList();}class Student implements People{ public void peopleList(){ System.out.println("I』m a student.");}}class Teacher implements People{ public void peopleList(){ System.out.println("I』m a teacher.");}}public class Example{ public static void main(String args[]){ People a; //聲明介面變數a=new Student(); //實例化,介面變數中存放對象的引用a.peopleList(); //介面回調a=new Teacher(); //實例化,介面變數中存放對象的引用a.peopleList(); //介面回調}}結果:I』m a student.I』m a teacher.再來看看向上轉型(upcasting)的概念。
用 Java 介面實現回調函數的等價功能熟悉 MS-Windows 和 X Window System 事件驅動編程模型的開發人員,習慣於傳遞在某種事件發生時調用(即「回調」)的函數指針。Java 的面向對象模型目前並不支持方法指針,Java 的介面支持提供了一種獲得回調的等價功能的機制。其技巧就是:定義一個簡單介面,並在該介面中聲明我們要調用的方法。假定我們希望在某個事件發生時得到通知。我們可以定義一個介面:InterestingEvent.javapackage org.zj.sample;public interface InterestingEvent { public void interestingEvent ();}這使得我們可以控制實現該介面的類的任何對象。因此,我們不必關心任何外部類型信息。發出事件信號的類必須等待實現了 InterestingEvent 介面的對象,並在適當時候調用 interestingEvent() 方法。EventNotifier.javapackage org.zj.sample;public class EventNotifier { private InterestingEvent ie; private boolean somethingHappened; public EventNotifier(InterestingEvent event) { ie = event; // 保存事件對象以備後用。 somethingHappened = false; // 還沒有要報告的事件。 } public void doWork() { if (somethingHappened) { // 檢查設置的謂詞。 ie.interestingEvent();// 通過調用介面的這個方法發出事件信號。 } } public void setHappened(){//設置謂詞。 somethingHappened=true; }}在上例中,使用 somethingHappened 謂詞來跟蹤是否應觸發事件。希望接收事件通知的代碼必須實現 InterestingEvent 介面,並將自身引用傳遞給事件通知程序。CallMe.javapackage org.zj.sample;public class CallMe implements InterestingEvent { @SuppressWarnings("unused") private EventNotifier en; public CallMe() { // 注意 EventNotifier (InterestingEvent event),應該傳遞一個介面類型。 // 而下面將this,即實現了InterestingEvent介面的CallMe實例傳遞給//EventNotifier。也就是所謂的介面回調了。 en = new EventNotifier(this); // 創建事件通知程序,並將自身引用傳遞給它。 } // 為事件定義實際的處理程序。