抽象类和接口

来源:互联网 发布:黑客和程序员哪个厉害 编辑:程序博客网 时间:2024/05/18 00:56

抽象类和接口


抽象类

抽象类是指被“abstract”关键字修饰的类。与之有关系的就是抽象方法,抽象方法:只有方法声明,没有方法实现的方法叫“抽象方法”,抽象方法也是用关键字“abstract”修饰。

抽象类是对问题领域进行分析后得到的抽象概念,是对一批看上去不同,但本质上相同的具体概念的抽象。 将那些不同定义成抽象方法,让它的子类去实现。 抽象类是对一种事物的抽象,即对类抽象。

定义抽象类和抽象方法的规则:

  • abstract关键字放在class前,指明该类是抽象类;

  • abstract关键字放在方法的返回类型前,指明该方法是抽象方法,抽象方法没有方法体且不能被“private”修饰,同样抽象类也不能用“private”修饰;

  • 抽象类不能被实例化即无法使用new关键字直接创建抽象类的实例,即使抽象类中没有抽象方法也不行;

  • 一个抽象类中可以含有多个抽象方法,也可以含有已实现的方法,甚至可以没有抽象方法(但是没有抽象方法的抽象类没有意义);

  • 抽象类可以包含成员变量以及构造方法,但不能通过构造方法创建实例,可以在子类创建实例时调用;

  • 继承抽象类的子类必须实现抽象类的抽象方法。如果没有实现抽象类的抽象方法,则子类也需定义为抽象类

定义抽象类有三种情况:

  • 直接定义抽象类;

  • 继承一个抽象类,但没有完全实现父类包含的抽象方法;

  • 实现一个接口,但没有实现接口所包含的抽象方法;

    public abstract class Animal {    private String name;    public Animal() {    }    public abstract void action();    public abstract void call();    /**    * abstract关键字不能用来修饰成员变量和构造方法,既没有抽象变量和抽象构造方法的说法,    * abstract关键字修饰的方法必须被子类重写才有意义,否则这个方法永远不会有方法体,    * 因此抽象方法不能定义为private,即private和abstract不能同时修饰方法。    * abstract也不能和static、final或native同时修饰同意方法。    * */    }public class Horse extends Animal {    @Override    public void action() { //实现抽象类中未实现的方法        System.out.println(this.getClass().getName() + "四条腿跑");    }    @Override    public void call() {        System.out.println(this.getClass().getName() + "长啸");    }}

接口

接口定义了一批类所需要遵守的公共行为规范,只规定这些类必须实现的某些方法,而不提供方法的实现。接口是对行为的抽象。

接口体现了规范和实现分离的设计哲学,规范和实现分离可以让系统各模块之间面线接口耦合,是松耦合的设计,从而降低模块之间的耦合,增强系统的可维护型和可扩展性。

接口的使用规则:

  • 接口用“interface”关键字定义,后面不需“class”,直接跟接口名。 接口前若加了 public 修饰符,代表这个接口可以在其它包中使用;若没有加修饰符,则默认为 public abstract 修饰,只能在这个包中使用此接口(包括实现接口和声明接口的引用变量);

  • 接口也不能实例化对象即不能通过new来创建接口的对象,接口实例化的是实现它的子类的对象;

  • 接口中不能有构造方法,并且接口的每个方法都必须是抽象方法(没有访问符和修饰符的方法会被系统默认为 public abstract 方法,若要加上其他的修饰符都会报错);

  • 接口中的所有变量都必须是静态常量(如果变量前没有修饰符,也会被系统默认为 public static final 变量);

  • 接口继承接口可以多继承,但只能继承接口,不能继承了类;

  • 在JDK8+ 版本中,接口中可以有默认方法和类方法,默认方法必须用 default 修饰; 类方法必须用 static 修;

  • 接口中还可以有内部类、内部类接口以及枚举的定义,都默认用 public static 修饰;

    public interface IPresenter {    String name = "this is interface"; //静态常量,而且定义时必须初始化    void run(); //抽象方法,    default void print() { //jdk 8+版本中的默认方法,可以用接口的“实例化对象”调用此方法        System.out.println("This is default function");    }    static String staticString() {//jdk 8+版本中的类方法,通过该接口名称调用此方法        return "接口的类方法";        }}//实现接口 用关键字 implement, 类可以实现多个接口用逗号隔开,实现接口的类拥有接口的常量public class Presenter implements IPresenter{    @Override    public void run() {//实现接口中的抽象方法        System.out.println("Class that implements the interface");    }}public class Test {    public static void main(String[] args) {        //声明接口的引用对象并使它指向实现它子类的实例对象        IPresenter iPresenter = new Presenter();        iPresenter.print();//调用接口的默认方法        System.out.println(IPresenter.staticString());//调用接口的类方法    }}

接口和抽象类的区别

  • 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

  • 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

  • 在设计目的上接口是一种行为规范,而抽象类是一种对象规范。