多型&&介面
多型的作用: 提高程式的可擴充套件性
多型的前提: 有層級關係
@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);
}
}
發生多型的情形:(子類物件的向上轉型)
- 父類物件指向任何一個子類的例項(物件)
- 編譯時的資料型別(賦值符號左邊)和執行時資料型別(賦值符號右邊)不一致時
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 介面名(){
}
在專案中,介面的命名有兩種:
-
********Dao/DAO.java
-
********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. 介面作用
介面與類:
-
類是實現介面的
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);
}
}
介面的核心作用體現在多型上面
父介面 引用指向任何一個實現類物件---->實現了多型
-
介面與介面的關係(多繼承)
一個介面可以繼承多個介面
4. 介面與抽象類的使用場景
-
共同點:都不能例項化 核心功能都體現在多型上
-
不同點:
-
介面:
只能存在常量/抽象方法 或者default/static所修飾的普通功能方法
-
抽象類:都可以有
-
最基本的功能一般用抽象類實現,而特殊的功能一般使用介面實現
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 修飾類 此類不能被繼承