翻译翻译,什么叫抽象类!

440 阅读4分钟

1 什么是抽象类

我们都知道类是抽象的对象是具体的。那抽象类是什么玩意?是比抽象的类还要抽象的类叫抽象类?

其实可以这样理解。

我们都知道如果一些对象具有一些相同的特征,我们可以把这些相同的特征抽取出来放到一个类里面。

比如李白、杜甫、白居易都属于诗人类,鲁迅、巴金、钱钟书都属于作家类

而把诗人类、作家类相同的特征抽取出来,再往上一层都属于人类,人类其实就是抽象类

你可能还是有点懵逼,一定要看到最后。

2. 抽象类的定义和使用

2.1 抽象类和抽象方法

    1. 用 abstract 关键字修饰的类是抽象类。
    1. 抽象类中用 abstract 修饰的方法是抽象方法。
    1. 抽象方法没有方法体。

例如:

// 抽象动物类
public abstract class Animal {
    // 名字
    String name;
    // 抽象方法
    abstract void eat();
}

2.2 抽象类无法创建对象

从上面图中我们知道类可以实例化对象,把一些类提取相同的特征往上抽象一层是抽象类

类实例化为对象是从上往下,而抽象类的下一层还是类。类只能实例化对象,不能实例化类,所以抽象类不能创建对象,只能被子类继承。

但是,抽象类可以有构造方法:

//诗人类
public abstract class Poet {
    
    // 构造方法
    public Poet() {
    }
}

你可能会说这不扯淡吗?构造器不就是用来创建对象的?

其实抽象类中的构造方法主要是为了创建子类时初始化属性用的。

我们都知道,子类继承父类之后,创建子类对象的时候默认会先调用父类的构造方法。例如:

//诗人类
public abstract class Poet {
    String name;
    // 父类构造方法
    public Poet() {
        System.out.println("父构造器被调用了");
    }
}
// 五言诗人类
public class FivePoet extends Poet{

}
public class AbstractTest {
    public static void main(String[] args) {
        FivePoet fivePoet = new FivePoet();
        System.out.println(fivePoet.name);
    }
}

运行结果:

如果父类没有给属性赋默认值,那么子类在继承父类之后,获取的属性值也是空的,例如上面打印的 name 值为 null。那么父类就可以在构造方法里面为属性赋值,例如:

//诗人类
public abstract class Poet {
    String name;
    // 父类构造方法
    public Poet(String name) {
        this.name = name;
        System.out.println("父构造器被调用了");
    }

2.3 抽象方法只能出现在抽象类中

如果一个类中含有抽象方法,那么这个类必须定义成抽象类。

下面才是正确的写法:

//诗人类
public abstract  class Poet {
    // 抽象方法没有方法体,只用提供声明
    public abstract void write();
}

2.4 抽象类中可以没有抽象方法

抽象类中可以不用设置抽象方法,设置的普通方法必须要有方法体。

//诗人类
public abstract  class Poet {
    // 普通方法
    public void read(){
        System.out.println("诗人喜欢读书");
    }
}

2.5 抽象类的子类必须重写抽象方法

如果一个抽象类声明了抽象方法,那么他的子类必须重写这个抽象方法。

// 诗人类
public abstract  class Poet {
    // 抽象方法没有方法体,只用提供声明
    public abstract void write();
    // 普通方法
    public void read(){
        System.out.println("诗人喜欢读书");
    }
}

抽象类的子类可以是抽象类,也可以不是抽象类。

2.6 抽象类不能被 final 修饰

因为抽象类设计的初衷就是为了让子类继承的,而 final 修饰的类不能被子类继承,所以 abstract 和 final 不能一起使用,俩人是冤家。

2.7 抽象方法不能被 final 修饰

子类继承了抽象类必须要实现抽象的方法,而 final 修饰的方法不能被重写,所以 abstract 和 final 不能一起使用,俩人是冤家。

3. 理解抽象类

上面讲了那么多可能还是有些人不理解抽象类的用处。

你说抽象类是专门用来继承的,那普通类也可以被继承啊,普通类的方法也可以被子类实现啊,为什么还要专门搞个抽象类?那不还是“脱裤子放屁,多此一举吗?”

子类继承了一个普通类可以不用实现父类的方法,但是抽象类的核心就在:继承抽象类的子类必须实现抽象方法。

必须是什么意思?是强制性的,是必须要遵守的规范!

就像加盟店必须要挂总店的招牌,外设要想被电脑识别必须要实现 USB 接口标准,这就是规范!

所以在开发过程中,如果遇到子类必须重写父类的方法的场景,可以用抽象类。

其实抽象类是为后面要学的接口做铺垫的,诸位看官欲知详情,可以进一步说话,我们在接口那篇文章见。