<output id="uabzf"></output>
<code id="uabzf"><ol id="uabzf"></ol></code>

        1. 舉個例子告訴你,Java中如何實現回調函數

          發表于:2022-10-21 09:34

          字體: | 上一篇 | 下一篇 | 我要投稿

           作者:趙仝    來源:簡書

          #
          Java
          分享:
            最近工作需要研究了一會別人寫的庫,其中充滿著各種"回調函數",因此把自己理解給記錄下來,存檔。
            首先我們來看看回調函數 這個概念的具體由來,百度百科的示義如下:
            回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數;卣{函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。
            從上面的這段闡述之中,我們不難發現兩點。
            函數回調就是將函數指針的地址當作參數傳遞給另一個函數。
            函數回調的用途簡單來說就是進行事件的響應或者事件觸發。
            既然我們知道回調函數的用途是事件的響應,那么我們就從這里入手。
            假設我們有這樣一個場景,一家人坐在一起吃飯,但是我們中國的規矩是,長輩沒動筷子,小輩們是不能動的,所以必須等著長輩動筷子這一事件完成之后,小輩們才能開始。
            接下來我們就用回調函數來解決。由于java中沒有指針一說,故而也沒了*,但是java提供了 接口幫我們實現 回調函數,俗稱 接口回調。
            首先我們分別創建一個,父親,兒子,姐姐對象。
          package zt;

          /**
           * 接口回調
           */
          public final class App {
              public static void main(String[] args) {
                  
              }
          }
          /**
           * 父親類,里面有個start函數,表示開始動筷子
           */
          class Father{
              private void start(){
                  System.out.print("父親開始動筷子了");
              }
          }
          /**
           * 兒子類,里面有個start函數,表示開始動筷子
           */
          class Son{
              private void start(){
                  System.out.print("兒子可以開始動筷子了");
              }
          }
          /**
           * 姐姐類,里面有個start函數,表示開始動筷子
           */
          class Sister{
              private void start(){
                  System.out.print("姐姐可以開始動筷子了");
              }
          }
            創建好之后,我們要實現,當父親開始動筷子之后,姐姐和弟弟才能開始動筷子。也就是我們必須將父親動筷子這個事件傳遞給姐姐和弟弟對象。
            所以按照邏輯,這個父親有一個兒子,一個女孩,并且父親開始動筷子了,他們兩個才可以動。代碼如下:
          package zt;

          /**
           * 接口回調
           */
          public final class App {
              public static void main(String[] args) {
                  new Father(new Son(),new Sister()).start();;
              }
          }

          interface Start{
              void Fstart(Object obj);
          }

          /**
           * 父親類,里面有個start函數,表示開始動筷子
           */
          class Father{

              private Sister sister;
              private Son son;

              Father(Son son,Sister sister){
                  this.son= son;
                  this.sister = sister;
              }

              public void start(){
                  System.out.println("父親開始動筷子了");
                  son.Fstart("父親動了筷子");
                  sister.Fstart("父親動了筷子");
              }
          }
          /**
           * 兒子類,里面有個start函數,表示開始動筷子
           */
          class Son implements Start{
              private void start(){
                  System.out.println("兒子可以開始動筷子了");
              }

              @Override
              public void Fstart(Object obj) {
                  if(obj.toString().equals("父親動了筷子")){
                      start();
                  }
              }
          }
          /**
           * 姐姐類,里面有個start函數,表示開始動筷子
           */
          class Sister implements Start{
              private void start(){
                  System.out.println("姐姐可以開始動筷子了");
              }

              @Override
              public void Fstart(Object obj) {
                  if(obj.toString().equals("父親動了筷子")){
                      start();
                  }
              }
          }
            然后運行,結果如下:
            這樣看起來是不是很靈活,萬一生個二胎,再加一個就行了。當然上面的代碼并不完美,面向對象的思想告訴我們,我們應該在父親和兒子,姐姐之間再定義一個Children。代碼如下,這樣不管生幾胎就更省事了:
          package zt;

          /**
           * 接口回調
           */
          public final class App {
              public static void main(String[] args) {
                  new Father(new Children[] { new Son(), new Sister() }).start();
              }
          }

          interface Start {
              void Fstart(Object obj);
          }

          /**
           * 父親類,里面有個start函數,表示開始動筷子
           */
          class Father {

              private Children[] childs;

              Father(Children[] childs) {
                  this.childs = childs;
              }

              public void start() {
                  System.out.println("父親開始動筷子了");
                  for (Children ch : this.childs) {
                      ch.Fstart("父親動了筷子");
                  }
              }
          }

          class Children implements Start {

              protected void start() {
                  System.out.println("孩子們開始動筷子");
              }

              @Override
              public void Fstart(Object obj) {
                  if (obj.toString().equals("父親動了筷子")) {
                      this.start();
                  }
              }

          }

          /**
           * 兒子類,繼承孩子類
           */
          class Son extends Children {

              @Override
              protected void start() {
                  System.out.println("兒子可以開始動筷子了");
              }

          }

          /**
           * 姐姐類,繼承孩子類
           */
          class Sister extends Children {
              @Override
              protected void start() {
                  System.out.println("姐姐可以開始動筷子了");
              }
          }
            這就是我最近的一些感受,說實話工作快3年了,我最近第一次感受到了面向對象編程的優美。當然也有不好的地方,面向對象把有些事復雜化了。一句話,實踐是檢驗真理的唯一標準,紙上得來終覺淺,絕知此事要躬行。
            本文內容不用于商業目的,如涉及知識產權問題,請權利人聯系51Testing小編(021-64471599-8017),我們將立即處理
          價值398元的測試課程免費贈送,填問卷領取吧!

          關注51Testing

          聯系我們

          快捷面板 站點地圖 聯系我們 廣告服務 關于我們 站長統計

          法律顧問:上海漕溪律師事務所 項棋律師
          版權所有 上海博為峰軟件技術股份有限公司 Copyright©51testing.com 2003-2022
          投訴及意見反饋:webmaster@51testing.com; 業務聯系:service@51testing.com 021-64471599-8017

          滬ICP備05003035號

          滬公網安備 31010102002173號

          明星乱亚洲合成图com|国产真实破苞视|日本a级不打码按摩片|一本通中文字幕亚洲欧美
          <output id="uabzf"></output>
          <code id="uabzf"><ol id="uabzf"></ol></code>