简单理解Java中的“Abstract 抽象类“和“Interface 接口“

        首先我们需要知道"Abstract 抽象类"(abstract class)和"Interface 接口"(interface)是支持抽象类定义的两种机制.

1、Abstract 抽象类

那么在Java中什么是抽象类呢?

        在Java中由于多态的存在,一个类可以作为父类被多个子类继承,例如:从Person父类派生的Student子类和Teacher子类都可以覆写run()方法。

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

如果父类Person的run()方法没有需要执行的代码逻辑,能否去掉方法体中的执行语句?答案是不行,因为会导致编译错误,因为定义方法的时候,必须实现方法的语句。能不能去掉父类的run()方法?答案还是不行,因为去掉父类的run()方法,就失去了多态的特性。例如,之前定义runTwice()就无法编译!

        所以,如果父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法: 把一个方法声明为abstract,表示它是一个抽象方法,本身不能有方法体。因为这个抽象方法本身是无法执行的,所以,此时的Person类也被视为抽象类,抽象类无法被实例化。编译器会告诉我们,无法编译Person类,因为它包含抽象方法。

我们在代码中来看:

错误:

class Person { //此时编译器会报错
 /*抽象方法 1、没有方法体
  *         2、在修饰符和返回值之间加abstract关键字
  *         3、必须存在于有abstract抽象类中
	              */
 public abstract void run(); 
}

正确: 

abstract class Person {
 /*抽象方法 1、没有方法体
  *         2、在修饰符和返回值之间加abstract关键字
  *         3、必须存在于有abstract抽象类中
	              */
//抽象方法1
 public abstract void run(); 
//抽象方法2
 public abstract void say(); 
}

总结:

        如果一个class中定义了某个方法,该方法没有具体执行代码(方法体)。那么,这个方法就是抽象方法,抽象方法使用abstract修饰。因为无法执行抽象方法,因此这个类也必须定义为抽象类(abstract class )。也可以理解为:抽象方法必须定义在abstract class 抽象类中。(注意:抽象类中不一定存在抽象方法)

2、Interface 接口

        在抽象类中,抽象方法本质上是定义行为规范:规定父类中的抽象行为(抽象方法),要求所有子类必须对该抽象方法进行实现。从而,实现对子类行为规范的约束。主要用于实现多态。  但是,如果一个抽象类没有字段(成员变量),并且所有方法全部都是抽象方法,这时就可以把该抽象类定义为interface接口。在Java中,使用interface关键字声明一个接口:

interface Person {
    void run();
    String getName();
}

        所谓interface接口,就是比抽象类还要更佳抽象的一种纯抽象的代码结构。因为它连字段(成员变量)都不能存在,只能包含常量、抽象方法、默认方法等。另外,接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要显示的定义出来(写或不写效果都一样)。

        当一个具体的class去实现一个interface时,需要使用implements关键字。要求所有子类必须对该抽象方法进行实现,举个例子:

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(this.name + " run");
    }

    @Override
    public String getName() {
        return this.name;
    }
}

        在Java中,一个类只能extends继承自另一个类(单继承)。但是,一个类可以implements实现多个interface接口(多重实现)。例如:

// 实现了两个interface
class Student implements Person, Hello { 
    ...
}

        此外,接口可以定义default方法(JDK版本 >= 1.8),default方法可以包含方法体。default方法和抽象类的普通方法是有所不同的。因为interface没有字段,default方法无法访问字段,而抽象类的普通方法可以访问实例字段。

        实现类可以不必覆写default方法。default方法的目的是,当我们需要给接口新增一个方法时,会涉及到修改全部子类。如果新增的是default方法,那么子类就不必全部修改,只需要在需要覆写的地方去覆写新增方法。例如,把Person接口的run()方法改为default方法:

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

interface Person {
    String getName();
    default void run() {
        System.out.println(getName() + " run");
    }
}

class Student implements Person {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值