返回顶部
扩大
缩小

Yeap

抽象 abstract

由于多态的存在,每个子类都可以重写父类的方法。

class Person {
    public void run() { … }
}

class Student extends Person {
    @Override
    public void run() { … }
}

class Teacher extends Person {
    @Override
    public void run() { … }
}

Person类的子类StudentTeacher都可以重写 run()方法。

如果父类的方法本身不需要实现任何功能,仅仅为了定义方法签名,目的是让子类去重写它,那么可以把父类的方法声明为抽象方法:

class Persion(){
  	public abstract void run();
  
}

把一个方法声明为abstract,表示这是一个抽象方法,本身没有任何的语句。因为这个抽象方法本身是无法执行的。所以,perosn类无法执行被实例化。

必须把person类本身也声明为abstract.

abstract class Person {
    public abstract void run();
}

抽象类

如果一个class定义了方法,但是没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract 修饰。

因为无法执行抽象方法,因此这个类必须申明为抽象类(abstract class)。

使用 abstract修饰的类是抽象类。我们无法实例化一个抽象类:

Person p = new Person();//编译错误

抽象类本身设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。抽象方法实际上是定义了一个规范。

也就是说,父类定义了一个抽象的方法,那么它的子类句必须要重写这个抽象的方法:

public class Main {
    public static void main(String[] args) {
        Person p = new Student();
        p.run();
    }
}

abstract class Person {
    public abstract void run();
}

class Student extends Person {
    @Override
    public void run() {
        System.out.println("Student.run");
    }
}

面向抽象编程

当定义了抽象类,和它的子类的时候,可以通过抽象类的类型入引用一个具体的子类的实例

Person s = new Student();
Person t = new Teacher();

这种引用抽象类的好处在于,我们对其进行方法调用,并不关心变量的具体子类型

// 不关心Person变量的具体子类型:
s.run();
t.run();

同样的代码,如果引用的是一个新的子类,我们仍然不关心具体类型:

// 同样不关心新的子类是如何实现run()方法的:
Person e = new Employee();
e.run();

这种尽量引用高层类型,避免引用实际子类型的方式,称之为面型抽象编程。

面向抽象编程的本质是:

  • 上层代码只定义规范

  • 不需要子类就可以实现业务逻辑

  • 具体的业务逻辑由不同的子类实现,调用者并不关心。

posted on 2020-11-24 12:40  YP泡泡  阅读(105)  评论(0)    收藏  举报

导航