Có 1 hôm, bên cty mình có buổi phỏng vấn dev, ông sếp hôm đó bận nên mình cũng đc oai 1 bữa, thay ổng đc làm người pv. Mình có hỏi 1 câu khá đơn giản


"Làm sao để dùng danh sách(List) với nhiều đối tượng khác kiểu (object)?". Thì cậu kia trả lời là ta cho chúng extends từ chung 1 base class


Mình hỏi tiếp "nếu chúng đã được extends từ các class khác nhau rồi thì sao?" .. Cậu kia bó tay


Mình cũng thấy lạ, vì cái này là OOP cơ bản, tại sao nhiều người học qua rồi mà lại ko sử dụng tới Interface, chỉ việc cho 2 class đó implements chung 1 kiểu interface là cho vào 1 list đc thôi.


Đó chỉ là 1 ví dụ về việc áp dụng Interface rất cơ bản, bây giờ mình nói về 1 cách sử dụng khác (Ref to Object).


Mình sẽ ví dụ trong việc dev android (Mình thích android).


Hồi mình bắt đầu dev android, cứ mỗi lần cần request xài httpclient, mình lại viết mới 1 class asynctask để sử dụng, 1 hôm rảnh rỗi ngồi review code, mình nghĩ xem có cách nào viết chung 1 class không, mỗi lần sau chỉ cần truyền vào các tham số là xài đc.


Mình tạo một cái interface như này, cái này sẽ ref ngược về chỗ gọi asynctask khi kết thúc hàm


public interface HandlerProcess<T> {
    void onComplete(boolean success, T result);
}


Mình tạo tiếp 1 abstract class asynctask xài chung, đọc code sẽ thấy

  • Đầu vào: Mình không truyền cụ thể tham số hay chi tiết gì, mình sẽ tạo 1 abstract method, cái này là nội dung hàm xử lý (mình sẽ override hàm này tại class gọi).
  • ProgressDialog: dialog xuất hiện khi ta chạy xử lý
  • HandlerProcess: cái interface vừa tạo ở trên, nó sẽ gọi khi kết thúc

public abstract class AsyncProcess<T> extends AsyncTask<Void,Void,T> {
    private Exception exception;
    private HandlerProcess<T> handlerProcess;
    protected abstract T executeMethod();
    protected ProgressDialog progressDialog;

    public AsyncProcess(HandlerProcess<T> handlerProcess, ProgressDialog progressDialog){
        this.handlerProcess = handlerProcess;
        this.progressDialog = progressDialog;
    }

    @Override
    protected void onPreExecute() {
        if(progressDialog!=null)
            progressDialog.show();
    }

    @Override
    protected T doInBackground(Void... params) {
        try{
            return executeMethod();
        }catch (Exception e){
            this.exception = e;
            return null;
        }
    }

    @Override
    protected void onPostExecute(T t) {
        if(progressDialog!=null && progressDialog.isShowing()){
            progressDialog.dismiss();
        }
        handlerProcess.onComplete(exception == null,t);
    }
}



Và bây giờ là việc sử dụng, ở tại class bất kì:
- Mình khai bao 1 đối tượng của HandlerProcess:

HandlerProcess<JSONObject> handlerProcess = new HandlerProcess<JSONObject>() {
    @Override
    public void onComplete(boolean success, JSONObject result) {
        if(success&&result!=null){
           //process success no error
        }else {
           //process success with error
        }
    }
};



- Và khai báo tiếp đối tượng asyntask

AsyncProcess<JSONObject> asyncProcessCheckToken = new AsyncProcess<JSONObject>(handlerProcess,null) {
    @Override
    protected JSONObject executeMethod() {
        //do something
    }
};
asyncProcessCheckToken.execute();



Vậy là bạn đã có 1 class asynctask xài đc bất kì chỗ nào luôn rồi phải ko, đỡ mất thời gian phải viết những mã giống nhau.