1.抽象类的基本概念
JAVA中使用abstract关键字来修饰的类是抽象类,一般我们把父类变成抽象类。父类是一个抽象的概念,实例化出来也没有意义,所以把父类变成抽象类后,这个类就不允许实例化了,但是一般可以作为子类对象的接收类型来用。抽象类中可以包含抽象方法也可以不包含,但是具有抽象方法的类一定是抽象类。
抽象方法必须为public或者protected修饰,如果为private,则不能被子类继承,子类便无法实现该方法,缺省情况下默认为public。
简单代码说明:
抽象类-Animal
// 抽象类-Animal public abstract class Animal { //抽象方法run abstract void run(); // 抽象方法,没有方法体,有abstract关键字修饰 //普通方法 public void eat(){ System.out.println("animals are eating"); // 存在方法体 } }
实现类(子类)-Dog
// 实现类(子类)-Dog public class Dog extends Animal { // Dog类是抽象类的子类,是一个普通类 @Override void run() { // Animal的抽象方法run被强制重写,而Animal的普通方法则没有被强制重写 System.out.println("The dog is running..."); } }
测试类-TestAbstract
public class TestAbstract { public static void main(String[] args) { Animal dog = new Dog(); // 多态:向上转型 dog.run(); // 调用被重写的方法 dog.eat(); // 调用父类的普通方法 } }
2.接口的基本概念
接口可以看成是特殊的抽象类。即只包含有抽象方法的抽象类。
interface Animal{ // 通过interface关键字定义接口 public static final int CH_LI = 99; //接口中不可以定义成员变量,但可以定义常量。 void run(); //接口中只可以定义没有实现的方法(默认自带 public abstract) }
一个类可以通过implements关键字实现接口。
一个类实现了某个接口后必须实现该接口中定义的所有的抽象方法。
class Dog implements Animal{ public void run(){ System.out.println("dog is run"); } }
与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔。当然,这个类需要实现这些接口中定义的所有的方法。
Animal runner = new Dog();
接口可以作为一种类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象;通过该变量可以调用该接口中定义的方法。
接口的继承
接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口。子接口继承了父接口中定义的所有方法。
interface Runner{ public void run(); } interface Dog extends Runner{ public void eat(); } class Hashiqi implements Dog(){ ppublic void run(){ ... } public void eat(){ ... } } //哈士奇必须实现Dog接口中的eat方法以及其父类接口Runner中的run方法。
PS:
类与接口之间的关系
类与类之间的关系 使用extends关键字表达继承的关系 支持单继承
类与接口之间的关系 使用implements关键字表达实现的关系 支持多实现
接口与接口之间的关系 使用extends关键字表达继承的关系 支持多继承
3.总结:抽象类和接口之间的区别
(1)定义抽象类的关键字是abstract class, 而定义接口的关键字是 interface.
(2)继承抽象类的关键字是extends, 而实现接口的关键字是implements。
(3)继承抽象类支持单继承,而实现接口可以多实现。
(4)抽象类中可以有构造方法,而接口中不可以有构造方法
(5)抽象类中可以有成员变量,而接口中只可以有常量
(6)抽象类中可以有成员方法,而接口中只可以有抽象方法
(7)抽象类中增加方法可以不影响子类,而接口中增加方法通常都影响子类。
(8)从JDK1.8开始允许接口中出现非抽象方法,但需要使用default关键字修饰。
为什么从1.8开始增加非抽象方法?
为了让接口中增加一个方法不影响实现类。增加这个方法,实现类需要就重写,不需要就不用重写。改变以往在接口中增加抽象方法,实现类都要重写一遍的局面。