首頁  >  問答  >  主體

java中没有抽象方法的抽象类有什么意义?仅仅是为了让别人不能创建该类的对象?

怪我咯怪我咯2761 天前705

全部回覆(6)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:47:59

    最常用到的地方就是實作範本方法(Template Method)?
    舉個例子,你要寫一批遠端服務的本地代理。對這批代理來說,取得請求位址、發送請求、取得對應內容的步驟都是公共的。只有定義字元編碼類型、定義回應回呼兩個步驟是差異的。

    這時候就可以定義一個抽象類,把請求過程都寫完。而將差異的部分留給實際的子類別去定義。不是設計者【不讓】抽象類別實例化,而是在知道遠端服務的特性前無法確定一些屬性,因此不可能實例化。

    JDK中的例子就是 java.io.InputStream。它的 read(byte[], int, int) 方法呼叫了 java.io.InputStream.read() 方法。而read()是一個抽象方法,需要在子類別中定義。你可以看源碼學習一下。

     public abstract int read() throws IOException;
    
     public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }
    
        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;
    
        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }
    

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:47:59

    • 你得看看它是否繼承了什麼類別或實作了什麼介面

    • 很有可能放置了一些共用方法

    • 如果沒有,不如改成介面

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-18 10:47:59

    可能提取了一些公共方法和實例欄位。

    回覆
    0
  • 迷茫

    迷茫2017-04-18 10:47:59

    應該不是說沒有抽象方法的抽象類別有特殊的意義,只是抽象類別的普通意義,給出預設實現,比直接實現介面可能會少些部分程式碼。反過來說,硬是要求一個抽象類別保留一個兩個抽象方法有什麼意義?

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:47:59

    說反了,是為了讓這個類別的子類別必須創建這個某些方法。當然這也是介面的要求,但是介面要求所有方法都是抽象方法。但是抽象類別可以預先定義一些不需要子類別必須重載的方法。

    抽象類別和介面都是為了抽象,抽象的好處就不說了。例如我們要實現一個Equal接口或是类,定义两个方法 equalunequal。如果用接口实现,一个类必须实现这两个方法。可是如果用抽象类实现,可以把unequal在抽象类里实现为!equal,这样在其子类里就需要再实现unequal了。

    個人來說更喜歡抽象類別一點兒(可是Java不支持多继承)。比如Compareable接口其实还有一个要求,如果a<b && b < ca < c,接口里不能保证这是正确的。当然抽象类也解决不了,但是对于上面的Equal,抽象類別實現起來更符合額外的要求。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 10:47:59

    範例:
    基於:spring mvc

    public abstract class BaseController {
        protected HttpServletRequest request;
        protected HttpServletResponse response;
        protected HttpSession session;
    
        @ModelAttribute
        public void setReqAndResp(HttpServletRequest request, HttpServletResponse response){
            this.request = request;
            this.response = response;
            this.session = request.getSession();
        }
        protected Map<String,String> getLoginUser(){
            Object loginUser = request.getAttribute(Config.LOGIN_USER);
            Map<String,String> loginUserMap = new HashMap<>();
            loginUserMap.put(Config.USER_CODE,loginUser==null?"":loginUser.toString());
            return loginUserMap;
                //return (User) session.getAttribute(Constants.LOGIN_USER);
        }
    }
    

    通用的全域屬性 request response session
    通用的方法getLoginUser()
    當然 還會有其它的(一些通用的屬性和方法)。
    既然有controller 那麼service dao 也可以。
    我通常都 是把一些重置的程式碼 抽到父類別裡 使用。

    回覆
    0
  • 取消回覆