Skip to content

抽象类

似是而非,具备某种对象的特征但不具体。例如动物就是抽象类。

使用抽象类的好处:

使用抽象类把一种事物进行抽象,在调用的时候就会灵活很多,你只需要把对应的参数传递进去即可。

同时扩展性也很好,新增的只需要继承父类的抽象类,然后在调用时,把新增的类new出一个实例,把这个实例传进去就可以。

抽象类基本使用的示例:狗狗,动物,人类案例

java
你把狗狗当作动物来看
你把狗狗当作宠物来看

父类中的抽象方法就是对子类中的方法做了约束,也就是说子类中必须要有父类中定义的抽象方法。

抽象类可以对子类方法进行约束,子类方法中必须有这种方法,具体实现看子类个人。

抽象类的规则

  1. 抽象方法没有方法体,必须存在于抽象类,均使用 abstract 修饰。

  2. 抽象类不能直接new对象,必须通过new子类的方式创建对象(多态向上转型)。

  3. 子类必须重写抽象类中的所有抽象方法,除非子类也是抽象类。

  4. 抽象类中可以书写普通属性、普通方法、静态方法、构造方法。

  5. 抽象类作为父类,实现多态的方式与之前一致。

抽象类示例:

结构图

image-20250705104747795

image-20250705104851796

代码

java
package com.abstractClass.Test1;

// 定义一个抽象类
public abstract class Animal {
    // 属性
    private String animalType;
    // 构造方法
    public Animal(){}
    public Animal(String animalType) {
        this.animalType = animalType;
    }
    // 实例方法
    public String getAnimalType() {
        return animalType;
    }
    // 实例方法
    public void setAnimalType(String animalType) {
        this.animalType = animalType;
    }
    // 静态方法
    public static void m1(){
        System.out.println("Animal类中的m1方法 ");
    }
    // 抽象方法
    public abstract void eat();
}
java
package com.abstractClass.Test1;

// 抽象类继承另一个抽象类
public abstract class Pet extends Animal{
    // 定义一个抽象方法
    public abstract void playWithMaster();
}
java
package com.abstractClass.Test1;

public class Tiger extends Animal{
    @Override
    public void eat() {
        System.out.println("老虎吃肉");
    }
}
java
package com.abstractClass.Test1;

public class Dog extends Pet{
    // 重写父类中的抽象方法
    @Override
    public void playWithMaster() {
        System.out.println("狗狗和主人玩飞盘");
    }
    // 重写爷类中的抽象方法
    @Override
    public void eat() {
        System.out.println("狗狗吃骨头");
    }
}
java
package com.abstractClass.Test1;

public class TestAnimal {
    public static void main(String[] args) {
        // 创建一个老虎对象
        Animal tiger = new Tiger();
        tiger.eat(); // 老虎吃肉

        // 创建一个狗狗对象 父类引用是Animal类
        Animal dog = new Dog();
        dog.eat(); // 狗狗吃骨头,调用的是Dog类中重写的方法
        // dog2.playWithMaster(); // 报错,Animal类中没有 playWithMaster() 方法

        // 创建一个狗狗对象 父类引用是Pet类
        Pet dog2 = new Dog();
        dog2.eat(); // 狗狗吃骨头,调用的是Dog类中重写的方法
        dog2.playWithMaster(); // 狗狗和主人玩飞盘,调用的是Dog类中重写的方法
    }
}

抽象类实现多态

父类中的抽象方法就是对子类中的方法做了约束,也就是说子类中必须要有父类中定义的抽象方法。

结构图

image-20250705111919074

代码

java
package com.abstractClass.Test2;

public abstract class Door {
    private String brand;
    private double price;

    public Door(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }

    public Door() {
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    // 定义抽象方法
    public abstract  void open();

    public abstract void close();

    // toString重写

    @Override
    public String toString() {
        return "Door{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}
java
package com.abstractClass.Test2;

public class CommonDoor extends Door{
    @Override
    public void open() {
        System.out.println("普通门开门,插入钥匙,轻轻一转,zhi~ya一声,门开了");
    }

    @Override
    public void close() {
        System.out.println("普通门关门,随手关门,duang的一声,门关了");
    }

}
java
package com.abstractClass.Test2;

public class SecurityDoor extends Door{
    private String password;

    public SecurityDoor(String password) {
        this.password = password;
    }

    public SecurityDoor() {
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public void open() {
        System.out.println("防盗门开门,输入密码,按下指纹,门自动打开");
    }

    @Override
    public void close() {
        System.out.println("防盗门关门,障碍物识别,自动关门");
    }
}
java
package com.abstractClass.Test2;

public class Person {
    // 定义实例方法
    public void openCommonDoor(CommonDoor cd){
        cd.open();
    }

    public void closeCommonDoor(CommonDoor cd){
        cd.close();
    }

    public void openSecurityDoor(SecurityDoor sd){
        sd.open();
    }

    public void closeSecurityDoor(SecurityDoor sd){
        sd.close();
    }

    // 以上方式分别针对不同的门的种类编写了开和关的方法 如果后续有更多的门的种类
    // 还需要继续编写更多的方法 这样设计不合理  不符合开闭原则
    // 使用多态的方式简化

    public void openDoor(Door door){
        door.open();
    }

    public void closeDoor(Door door){ // 向上转型,父类引用指向子类对象,多态
        door.close();
    }
    // 多态的情形2:返回值声明为 父类对象,实际返回值为子类类型
    public Door buyDoor(double money){
        if(money > 300){
            return new SecurityDoor();
        }else{
            return new CommonDoor();
        }
    }
}
java
package com.abstractClass.Test2;

public class TestPersion {
    public static void main(String[] args) {
        Person person = new Person();
        // 创建普通门实例
        CommonDoor commonDoor = new CommonDoor();
        commonDoor.setBrand("小金刚");
        commonDoor.setPrice(200);
        // 创建防盗门实例
        SecurityDoor securityDoor = new SecurityDoor();
        securityDoor.setBrand("大金刚");
        securityDoor.setPrice(500);
        // 人开门
        person.openDoor(commonDoor);
        person.openDoor(securityDoor);
        // 人关门
        person.closeDoor(commonDoor);
        person.closeDoor(securityDoor);
        System.out.println("-------------------------------------------------------");

        // 多态情形1:向上转型,父类引用指向子类对象,多态
        Door door = person.buyDoor(500); //
        door.open(); // 门打开了
        door.close(); // 门关闭了

        // 多态情形3:父类类型数组,子类为元素
        Door [] doors = new Door[2];
        doors[0] = new CommonDoor();
        doors[1] = new SecurityDoor();

        // Door{brand='null', price=0.0}
        // Door{brand='null', price=0.0}
        for (int i = 0; i < doors.length; i++) {
            System.out.println(doors[i].toString());
        }
    }
}