hualinux java 1.14:抽象類和接口類的選擇

目錄

一、什麼是抽象類

二、抽象類的應用場景及例子

2.1 應用場景

2.2 抽象類的例子

2.2.1 目錄結構

2.2.2 實現代碼

2.2.3 效果

2.3 使用模板的優缺點

三、抽象類和接口類的區別


對於初學者來說很多不知道抽象類和接口類是怎麼選擇。 本章做一下簡單的講解

總的來說:接口類是制定標準、抽象類可以作爲模板

一、什麼是抽象類

我們知道類是對物事的抽象,這樣它的範圍可以適合這一類的事物。爲了讓它適應的範圍更廣,能不能對類再進行一次抽象呢?是可以的,那就是抽象類,對類進行二次抽象

抽象類常見的就是模板設計,就像現實中的各種模板,只有模板填寫之後纔會有意義。

      比如我們寫一個車的類,再對它進行抽象呢?那就是交通工具了,它是不是包括得更廣了?反過來,交通工具類à車類,那車類也不是實物,也是一個抽象,不是一個實現,實例化指的是實例,所以抽象類不能直接實例化!

簡單來說抽象類就是:抽象的抽象!

 

二、抽象類的應用場景及例子

2.1 應用場景

a、在某些情況下,某個父類只是知道其子類應該包含怎樣的方法,但無法準確知道這些子類如何實現這些方法。

b.從多個具有相同特徵的類中抽象出一個抽象類,以這個抽象類作爲子類的模板,從而避免了子類設計的隨意性。

2.2 抽象類的例子

我們以登錄爲例子,我們知道一般電商登錄會可以使用用戶名、密碼、郵箱3種登錄方式,前提這些都是唯一的不能重複。

如下圖所示:

我們現在用java命令的方式實現這3種功能,這3種方法基本是一樣的,只是裏面的實現邏輯有所差別,所以我們可以把它抽象成一個模板,每種登錄方式重寫即可。

因爲模板登錄頁肯定有主題(css樣式、js、html等之類)我們打包成一套主題即可,爲了簡單些我再添加一個主題。

2.2.1 目錄結構

AccountValidatorUtil:正則表達式判斷輸入的是手機、郵件、還是用戶名
Login:登錄抽象類,主要是做模板作用
LoginByEmail:實現郵箱登陸功能
LoginByTel:實現電話登陸功能
LoginByUsername:實現用戶名登錄功能
LoginMain:主程序

2.2.2 實現代碼

com.hualinux.login.AccountValidatorUtil.java代碼如下:

package com.hualinux.login;

import java.util.regex.Pattern;

public class AccountValidatorUtil {
    /**
     * 正則表達式:驗證用戶名
     */
    public static final String REGEX_USERNAME = "^[a-zA-Z]\\w{5,20}$";

    /**
     * 正則表達式:驗證密碼
     */
    public static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,20}$";

    /**
     * 正則表達式:驗證手機號
     */
    public static final String REGEX_MOBILE = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";

    /**
     * 正則表達式:驗證郵箱
     */
    public static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";


    /**
     * 校驗用戶名
     *
     * @param username
     * @return 校驗通過返回true,否則返回false
     */
    public static boolean isUsername(String username) {
        return Pattern.matches(REGEX_USERNAME, username);
    }

    /**
     * 校驗密碼
     *
     * @param password
     * @return 校驗通過返回true,否則返回false
     */
    public static boolean isPassword(String password) {
        return Pattern.matches(REGEX_PASSWORD, password);
    }

    /**
     * 校驗手機號
     *
     * @param mobile
     * @return 校驗通過返回true,否則返回false
     */
    public static boolean isMobile(String mobile) {
        return Pattern.matches(REGEX_MOBILE, mobile);
    }

    /**
     * 校驗郵箱
     *
     * @param email
     * @return 校驗通過返回true,否則返回false
     */
    public static boolean isEmail(String email) {
        return Pattern.matches(REGEX_EMAIL, email);
    }

}

com.hualinux.login.Login.java代碼如下:

package com.hualinux.login;

public abstract class Login {
    //登陸頁面主題名,包括css、js、html等一系列外觀,
    String theme="login.vue";
    abstract Boolean login(String loginString,String password);

}

com.hualinux.login.LoginByEmail.java代碼如下:我這裏爲了方便設置密碼爲123則登錄成功

package com.hualinux.login;

public class LoginByEmail extends Login {
    @Override
    public Boolean login(String loginString, String password) {
        if (password.equals("123")){
            return true;
        }else {
            return false;
        }
    }
}

com.hualinux.login.LoginByTel.java代碼如下:

package com.hualinux.login;

public class LoginByTel extends Login{
    @Override
    public Boolean login(String loginString, String password) {
        if (password.equals("123")){
            return true;
        }else {
            return false;
        }
    }
}

com.hualinux.login.LoginByUsername.java代碼如下:

package com.hualinux.login;

public class LoginByUsername extends Login{
    @Override
    public Boolean login(String loginString, String password) {
        if (password.equals("123")){
            return true;
        }else {
            return false;
        }
    }
}

在這裏我得解釋一下,看上面LoginByEmail、LoginByTel、LoginByUsername是一樣的,但實際中是不一樣的

因爲要連接數據庫實現sql查詢,查詢的條件就不同,所以結果是不同的,密碼相同的

com.hualinux.login.LoginMain.java代碼如下:

package com.hualinux.login;

import java.util.Scanner;

public class LoginMain {
    public static void main(String[] args) {

        System.out.print("請輸入 用戶名/手機號/郵箱(回車結束):");
        Scanner scan=new Scanner(System.in);
        // 判斷是否還有輸入
        String loginStr=scan.nextLine();
        System.out.print("請輸入密碼(回車結束):");
        String pwdStr=scan.nextLine();
        scan.close();

        Login login;
        if (AccountValidatorUtil.isMobile(loginStr)){
            System.out.println("tel");
            login=new LoginByTel();
        }else if (AccountValidatorUtil.isEmail(loginStr)){
            System.out.println("email");
            login=new LoginByEmail();

        }else{
            System.out.println("username");
            login=new LoginByUsername();
        }
        //設置網站主題
        login.theme="login-blue.vue";

        if(login.login(loginStr,pwdStr)){
            System.out.println("登陸成功");
        }else {
            System.out.println("登錄失敗");
        }
    }
}

2.2.3 效果

我以郵件爲例子:

先寫郵箱和正確的密碼,看是否判斷出是郵箱、判斷密碼是否正確,如下

我輸入 hua@163、密碼爲123,發現判斷出是email,並提示登錄成功了

我輸入 hua@163、密碼爲456,發現判斷出是email,並提示登錄失敗

 

2.3 使用模板的優缺點

優點:

1、封裝不變部分,擴展可變部分。

2、提取公共代碼,便於維護。

3、行爲由父類控制,子類實現。

缺點:

每一個不同的實現都需要一個子類來實現,導致類的個數增加,使得系統更加龐大。

使用場景: 

1、有多個子類共有的方法,且邏輯相同。 2、重要的、複雜的方法,可以考慮作爲模板方法。

注意事項:

爲防止惡意操作,一般模板方法都加上 final 關鍵詞。

 

三、抽象類和接口類的區別

我這裏直接使用一張圖來說明

重要提示:

在開發中,一個類永遠不要去繼承一個已經實現好的類,要麼繼承抽象類,要麼實現接口,如果兩個類同時都可以使用的話,優先使用接口,避免單繼承的侷限。

 

抽象類和接口類總結

1、抽象類和接口類的實例化,通過多態性(向上轉型,向下轉型)。

2、抽象類表示一個模板,接口表示一個標準。

3、常見的設計模式:模板設計,工廠設計,代理設計,適配器設計

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章