1. 程式人生 > 實用技巧 >11.抽象類和介面

11.抽象類和介面

抽象類

抽象類概述

java中,一個沒有方法體的方法應該定義為抽象方法, 二類中如果有抽象方法, 該類必須定義為抽象類.

特點:

  • 抽象類和抽象方法必須使用abstract關鍵字修飾
    • public abstract class 類名{}
    • public abstract void eat();
  • 抽象類中不一定有抽象方法, 有抽象方法的類一定是抽象類
  • 抽象類不能直接例項化, 可以參照多型的方式, 通過子類物件例項化, 這叫抽象類多型
  • 抽象類的子類: 要麼重寫抽象類的所有抽象方法, 要麼是抽象類

Animal

package abstractClass.abstractDemo;

// 定義抽象類
public abstract class Animal {
    // 定義抽象方法
    public abstract void eat();

    public void sleep() {
        System.out.println("睡覺");
    }

    // 有抽象方法,一定是抽象類, 但是抽象類中不一定有抽象方法
}

Cat

package abstractClass.abstractDemo;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }
}

Dog

package abstractClass.abstractDemo;

public abstract class Dog extends Animal {

}

Demo

package abstractClass.abstractDemo;

public class Demo {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.eat();
        a.sleep();
    }
}

抽象類成員特點

成員變數:

  • 可以是變數
  • 可以是常量

構造方法:

  • 有構造方法, 但不能例項化
  • 用於子類訪問父類資料的初始化

成員方法:

  • 可以有抽象方法: 限定子類必須完成某些動作
  • 也可以有非抽象方法: 提高程式碼複用性

Animal

package abstractClass.member;

public abstract class Animal {
    private int age = 20;
    private final String city = "北京";

    public Animal() {}

    public void show() {
        age = 40;
        System.out.println(age);
        System.out.println(city);
    }

    public abstract void eat();
}

Cat

package abstractClass.member;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }
}

Demo

package abstractClass.member;

public class Demo {
    public static void main(String[] args) {
        Animal a = new Cat();
        a.eat();
        a.show();
    }
}

介面

概述

介面是一種公共的規範, 只要符合規範標準,大家都可以通用

java的介面更多的體現在對行為的抽象.

介面特點

介面用關鍵字interface修飾

  • public interface 介面名 {}

類實現介面用implements表示

  • public class 類名 implements 介面名 {}

介面不能直接例項化

  • 例項化需要參照多臺方式, 通過實現類物件例項化, 稱為介面多型
  • 多型的形式: 具體類多型, 抽象類多型, 介面多型
  • 多型前提: 有繼承或者實現關係; 有方法重寫; 有父(類/介面)引用指向(子/實現)類物件

介面的實現類:

  • 要麼重寫介面中的所有抽象方法
  • 要麼是抽象類

Jumpping

package javaInterface.interfaceDemo;

public interface Jumpping {
    public abstract void jump();
}

Cat

package javaInterface.interfaceDemo;

public class Cat implements Jumpping {  // 介面的繼承使用inplements關鍵字
    @Override
    public void jump() {
        System.out.println("貓跳高");
    }
}

Dog

package javaInterface.interfaceDemo;

public abstract class Dog implements Jumpping {
    // 抽象類繼承介面,可以不重寫方法
}

Demo

package javaInterface.interfaceDemo;

public class Demo {
    public static void main(String[] args) {
        // Jumpping j = new Jumpping();  // 介面是一個抽象類, 不能被例項化
         Jumpping j = new Cat();  // 介面例項化採用多型方式
         j.jump();
    }
}

介面成員的特點

成員變數:

  • 只能是常量
  • 預設修飾父: public static final

構造方法:

  • 介面沒有構造方法, 因為介面主要是對行為進行抽象的, 沒有具體存在
  • 一個類如果沒有父類, 預設繼承自Object類

成員方法:

  • 只能是抽象方法
  • 預設修飾符: public abstract
  • 關於介面中的方法, JDK8和JDK9有一些新特性

Inter

package javaInterface.member;

public interface Inter {
    // 成員變數
    public int num = 10;
    public final int num2 = 20;
    int num3 = 30; // 等價於 public static final int num3 = 30;

    // 構造方法
    // public Inter(){}  // 介面中沒有構造方法

    // 成員方法
    // public void show() {}  // 介面中沒有非抽象方法

    public abstract void method();  // 只能是抽象方法

    void show();  // 預設也是抽象方法

}

InterImpl

package javaInterface.member;

// public class InterImpl implements Inter {
// 上述等價於 public class InterImpl extends Object implements Inter,
// 也就是訪問父類構造方法的時候, 訪問的是object的無參構造方法, 而不是Inter的
public class InterImpl extends Object implements Inter {
    public InterImpl() {
        super();
    }

    @Override
    public void method() {
        System.out.println("method");
    }

    @Override
    public void show() {
        System.out.println("show");
    }
}

Demo

package javaInterface.member;

public class Demo {
    public static void main(String[] args) {
        Inter i = new InterImpl();
        // i.num = 15;  // 介面中的變數預設為final修飾的
        System.out.println(i.num);
        // i.num2 = 30; // 常量不能賦值
        System.out.println(i.num2);
        System.out.println(Inter.num2);  // 介面中的變數預設是靜態的
    }
}

貓和狗案例介面板

Jumpping

package javaInterface.catAndDog;

public interface Jumpping {
    public abstract void jump();
}

Animal

package javaInterface.catAndDog;

public abstract class Animal {
    private String name;
    private int age;

    public Animal() {
    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public abstract void eat();
}

Cat

package javaInterface.catAndDog;

public class Cat extends Animal implements Jumpping {

    public Cat() {
    }

    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }

    @Override
    public void jump() {
        System.out.println("貓可以跳高");
    }
}

Demo

package javaInterface.catAndDog;

public class Demo {
    public static void main(String[] args) {
        // 建立物件,呼叫方法
        Jumpping j = new Cat();
        j.jump();
        System.out.println("--------");

        Animal a = new Cat();
        a.setName("加菲");
        a.setAge(5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();
        // a.jump();

        a = new Cat("加菲", 5);
        System.out.println(a.getName() + "," + a.getAge());
        a.eat();
        System.out.println("--------");

        Cat c = new Cat();
        c.setName("加菲");
        c.setAge(5);
        System.out.println(c.getName() + "," + c.getAge());
        c.eat();
        c.jump();
    }
}

類和介面的關係

類和類的關係

  • 繼承關係, 只能單繼承, 但是可以多層繼承

類和介面的關係

  • 實現關係, 可以單實現, 也可以多實現, 還可以在繼承一個類的同時實現多個介面

介面和介面的關係

  • 繼承關係, 可以單繼承, 也可以多繼承

inter1

package javaInterface.interfaceAndClass;

public interface Inter1 {
}

Inter2

package javaInterface.interfaceAndClass;

public interface Inter2 {
}

Inter3

package javaInterface.interfaceAndClass;

public interface Inter3 extends Inter1, Inter2 {
    // 介面和介面可以多繼承
}

InterImpl

package javaInterface.interfaceAndClass;

public class InterImpl extends Object implements Inter1, Inter2, Inter3 {
    // 類可以實現多個介面
}

抽象類和介面的區別

成員區別

  • 抽象類: 變數,常量; 有構造方法; 有抽象方法, 也有非抽象方法
  • 常量; 抽象方法

關係區別

  • 類與類: 繼承, 單繼承
  • 類與介面: 實現, 單實現, 多實現
  • 介面與介面: 繼承, 單繼承, 多繼承

設計理念

  • 抽象類: 對類抽象, 包括屬性,行為
  • 介面: 對行為抽象, 主要是行為

使用案例:門和報警器

Alarm

package javaInterface.doorAndAlarm;

public interface Alarm {
    void alarm();
}

Door

package javaInterface.doorAndAlarm;

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

AlarmDoor

package javaInterface.doorAndAlarm;

public class AlarmDoor extends Door implements Alarm {
    @Override
    public void open() {
        System.out.println("開門");
    }

    @Override
    public void close() {
        System.out.println("關門");
    }

    @Override
    public void alarm() {
        System.out.println("報警");
    }
}

抽象是對事物的抽象, 介面是對行為的抽象.

形參和返回值

抽象類作為形參和返回值

方法的形參是抽象類名, 其實需要的抽象類的子類物件

方法的返回值是抽象類名, 其實返回的是該抽象類的子類物件

Animal

package paramAndReturn.abstractAndReturn;

public abstract class Animal {
    public abstract void eat();
}

Cat

package paramAndReturn.abstractAndReturn;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("貓吃魚");
    }
}

AnimalOperator

package paramAndReturn.abstractAndReturn;

public class AnimalOperator {
    public void useAnimal(Animal a) {
        a.eat();
    }

    public Animal getAnimal() {
        Animal a = new Cat();
        return a;
    }
}

Demo

package paramAndReturn.abstractAndReturn;

public class Demo {
    public static void main(String[] args) {
        // 建立物件
        AnimalOperator ao = new AnimalOperator();
        Animal a = new Cat();
        ao.useAnimal(a);

        Animal a2 = ao.getAnimal();
        a2.eat();
    }
}

介面作為形參和返回值

方法的形參是介面名, 其實需要的介面的實現類物件

方法的返回值是介面名, 其實返回的是該介面類的實現類物件

Jumpping

package paramAndReturn.interfaceAndReturn;

public interface Jumpping {
    void jump();
}

Cat

package paramAndReturn.interfaceAndReturn;

public class Cat implements Jumpping {
    @Override
    public void jump() {
        System.out.println("貓可以跳躍");
    }
}

JumppingOperator

package paramAndReturn.interfaceAndReturn;

public class JumppingOperator {
    public void useJumpping(Jumpping j) {
        j.jump();
    }

    public Jumpping getJumpping() {
        Jumpping j = new Cat();
        return j;
    }
}

Demo

package paramAndReturn.interfaceAndReturn;

public class Demo {
    public static void main(String[] args) {
        // 建立操作類, 呼叫方法
        JumppingOperator jo = new JumppingOperator();
        Jumpping j = new Cat();
        jo.useJumpping(j);

        Jumpping j2 = jo.getJumpping();
        j2.jump();
    }
}