1. 程式人生 > 實用技巧 >多型&&介面

多型&&介面


多型的作用: 提高程式的可擴充套件性

多型的前提: 有層級關係

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Employee {
    private int id;
    private String name;
    private String gender;
    private double salary;
}
public class CalSalary {
    // 使用父類充當形式引數
    public static  void paySalary(Employee employee){
        double total =employee.getSalary();
        System.out.println(employee.getName()+"的工資為:"+total);
    }
}
public class Hr extends Employee{
    public Hr() {
    }

    public Hr(int id, String name, String gender, double salary) {
        super(id, name, gender, salary);
    }
}
public class Pm extends Employee {
    private int exp;

    public int getExp() {
        return exp;
    }

    public void setExp(int exp) {
        this.exp = exp;
    }

    public Pm() {
    }

    public Pm(int id, String name, String gender, double salary) {
        super(id, name, gender, salary);
    }

    public Pm(int exp) {
        this.exp = exp;
    }

    public Pm(int id, String name, String gender, double salary, int exp) {
        super(id, name, gender, salary);
        this.exp = exp;
    }
}
public class Sale extends Employee{
    public Sale() {
    }


    public Sale(int id, String name, String gender, double salary) {
        super(id, name, gender, salary);
    }
}
public class Se extends Employee {
    private int hot;

    public Se() {
    }

    public int getHot() {
        return hot;
    }

    public void setHot(int hot) {
        this.hot = hot;
    }

    public Se(int id, String name, String gender, double salary) {
        super(id, name, gender, salary);
    }

    public Se(int hot) {
        this.hot = hot;
    }

    public Se(int id, String name, String gender, double salary, int hot) {
        super(id, name, gender, salary);
        this.hot = hot;
    }
}
public class EmployeeTest {
    public static void main(String[] args) {
        //對Se 和 Sale進行發放
        Se se=new Se(1,"jim","男",7000,100);
        Sale sale = new Sale();
        sale.setId(2);
        sale.setName("jack");
        sale.setGender("男");
        sale.setSalary(8000);
        CalSalary.paySalary(se);
        CalSalary.paySalary(sale);
    }
}


發生多型的情形:(子類物件的向上轉型)

  1. 父類物件指向任何一個子類的例項(物件)
  2. 編譯時的資料型別(賦值符號左邊)和執行時資料型別(賦值符號右邊)不一致時
public class EmployeeTest {
    public static void main(String[] args) {
        //建立物件時,發生了多型
        Employee employee =new Se(1,"jim","男",7000,100);
        CalSalary.paySalary(employee);
    }
}

向下轉型

父類物件轉換成子類例項:強制轉換instanceof 判斷一個物件是否是一個類的例項

public class CalSalary {
    // 使用父類充當形式引數
    //pm bonus在子類裡
    //必須通過子類物件進行呼叫
    public static void paySalary(Employee employee) {
        double total = employee.getSalary();
        // instanceof 判斷一個物件是否是一個類的例項
        if (employee instanceof Pm) {
            Pm pm = (Pm) employee;
            total += pm.getBonuses();
        }

        System.out.println(employee.getName() + "的工資為:" + total);
    }
}
public class EmployeeTest {
    public static void main(String[] args) {
        Employee employee1 = new Se(1, "jim", "男", 7000, 100);
        Employee employee = new Pm(3, "kim", "男", 10000, 5, 5000);
        CalSalary.paySalary(employee);
        CalSalary.paySalary(employee1);


    }
}


public class Teacher {
    private int tid;
    private String name;

    public void introduce() {
        System.out.println(name+"在自我介紹");

    }

    public void teach() {
        System.out.println(name+"在授課");
    }

}
public class JavaTeacher extends Teacher {
    public JavaTeacher() {
    }

    @Override
    public void teach() {
        System.out.println(super.getName()+"在進行Java授課");
    }

    @Override
    public void introduce() {
        super.introduce();
    }

    public JavaTeacher(int tid, String name) {
        super(tid, name);
    }
}
public class WebTeacher extends Teacher {
    public WebTeacher() {
    }

    public WebTeacher(int tid, String name) {
        super(tid, name);
    }

    @Override
    public void introduce() {
        super.introduce();
    }

    @Override
    public void teach() {
        System.out.println(super.getName() + "在進行Web授課");
    }
}
public class TeachManger {
    public static void evaluateTeacher(Teacher teacher){
        System.out.println("評估開始**********");
        teacher.introduce();
        teacher.teach();
        System.out.println("評估結束**********");

    }
}
public class TeacherApp {
    public static void main(String[] args) {
        Teacher teacher = new JavaTeacher(1,"jim");
        Teacher teacher1 = new WebTeacher(2,"tim");
        TeachManger.evaluateTeacher(teacher);
        TeachManger.evaluateTeacher(teacher1);
    }
}


抽象類 abstract class

所有的子類都重寫了父類的方法的邏輯,父類的方法體就變得沒有意義 父類的方法體就可以宣告成抽象的方法.

訪問許可權修飾符 abstract 返回值型別 方法名(引數){};

如果一個類裡面有抽象方法,那麼這個類就是抽象類

抽象類的核心功能:

​ 抽象類是不能建立物件的 體現在多型上面

​ 抽象類子所以有構造,是為了滿足子類物件的建立,而不是其本身的例項化


介面

class interface enum 都是程式中最小的儲存單元

面向介面程式設計

​ 使用Java語言編寫interface

寫介面:app/ios ,呼叫第三方的介面(路徑)

1. 建立介面
public interface 介面名(){
    
}

在專案中,介面的命名有兩種:

  1. ********Dao/DAO.java

  2. ********Service.java

    對於使用者模組:

    ​ UserDao.java UserService.java

2. 介面內容
public interface MyInterface {
    //成員變數  預設public static final
    //final 修飾符 所修飾的變數是常量,做資料時必須進行初始化操作 
    //常量名全部大寫 常量一旦初始化,它的值就不能發生改變
    String NAME = "admin";

    //成員方法
    //jdk1.8 之前接口裡面的方法全部都是抽象方法 不允許有方法體
    // 預設用 public abstract修飾
    void a(int num);
    
    //沒有構造方法
     //jdk1.8 及其之後可以存在普通的功能方法 加default關鍵字
    public default void demo(){
        System.out.println("demo執行......");
    }
    public static void demo1(){
        System.out.println("demo1執行......");
    }
}
    
3. 介面作用

介面與類:

  1. 類是實現介面的

    public class implements 介面1,介面2,...介面n; //介面的實現類
    
    public class MyInterfaceImpl implements MyInterface{
        @Override
        public void a(int num) {
            System.out.println("a============");
            if (num>0){
                System.out.println(num);
                return;
            }
            System.out.println(NAME);
        }
    }
    
public class MyInterfaceTest {
    public static void main(String[] args) {
        MyInterfaceImpl myInterface=new MyInterfaceImpl();
        myInterface.a(10);
        myInterface.a(-1);
    }
}

介面的核心作用體現在多型上面

​ 父介面 引用指向任何一個實現類物件---->實現了多型

  1. 介面與介面的關係(多繼承)

    一個介面可以繼承多個介面

4. 介面與抽象類的使用場景
  • 共同點:都不能例項化 核心功能都體現在多型上

  • 不同點:

    1. 介面:

      ​ 只能存在常量/抽象方法 或者default/static所修飾的普通功能方法

    2. 抽象類:都可以有


最基本的功能一般用抽象類實現,而特殊的功能一般使用介面實現

public abstract class Door {
    public abstract void open();

    public abstract void close();
}
public class ClassRoomDoor extends Door{
    @Override
    public void open() {

    }

    @Override
    public void close() {

    }
}
public class BedRoomDoor extends Door implements MaoYan{
    @Override
    public void open() {

    }

    @Override
    public void close() {

    }

    @Override
    public String maoYan() {

        return "";
    }
}
public interface MaoYan {
     String maoYan();
}
public interface Ring {
    void ring();
}
public class CompanyRoomDoor extends Door implements MaoYan,Ring{
    @Override
    public void open() {

    }

    @Override
    public void close() {

    }

    @Override
    public String maoYan() {
        return null;
    }

    @Override
    public void ring() {

    }
}

5. 開發中介面的使用

********Dao/DAO.java 放在dao包下 來定義介面

********Dao/DAOImpl.java 放在dao包下 來實現介面

在開發中也可以使用********Const.java來實現對模組中常量的處理


Exercise

public class School implements Detail {
    private String schoolName;

    public String getSchoolName() {
        return schoolName;
    }

    public void setSchoolName(String schoolName) {
        this.schoolName = schoolName;
    }

    @Override
    public void showInfo() {
        System.out.println("資訊是" + this.getSchoolName());
    }
}
public class Teacher implements Detail {
    private String teacherName;

    public String getTeacherName() {
        return teacherName;
    }

    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }

    @Override
    public void showInfo() {
        System.out.println("資訊是"+this.getTeacherName());
    }
}
public interface Detail {
    void showInfo();
}
public class Printer {
    public static void print(Detail detail) {
        System.out.println("列印資訊開始....");
        detail.showInfo();
        System.out.println("列印資訊結束....");

    }

    public static void main(String[] args) {
        School school = new School("北京大學");
        Printer.print(school);
        Teacher teacher =new Teacher("程剛");
        Printer.print(teacher);
        Detail detail = new Teacher("張寶磊");
        Printer.print(detail);

    }
}

列印功能拓展

public class ColorPrinter extends Printer{
    @Override
    public void print(Detail detail) {
        System.out.println("彩色列印開始*****");
        detail.showInfo();
        System.out.println("彩色列印結束*****");
    }
}
public class BlackWhitePrinter extends Printer {

    @Override
    public void print(Detail detail) {
        System.out.println("黑白列印開始*****");
        detail.showInfo();
        System.out.println("黑白列印結束*****");

    }
}
public class PrinterApp {
    public static void main(String[] args) {
        Detail detail = new School("北京大學");
        detail= new Teacher("張寶磊");
//        ColorPrinter colorPrinter = new ColorPrinter();
        Printer colorPrinter = new ColorPrinter();
        colorPrinter.print(detail);

        colorPrinter = new BlackWhitePrinter();
        colorPrinter.print(detail);

    }
}

final 關鍵字(修飾符) 最終的/最後的

可以修飾變數/方法/類

  • final 修飾變數 此變數就變為了常量 注意常量名都大寫

  • final 修飾方法 子類無法重寫此方法

  • final 修飾類 此類不能被繼承