抽象和接口
前言
对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。
1.掌握抽象类和抽象方法
抽象的特点:
- 被abstract关键字修饰 public abstract class 类名{}
- 抽象类无法创建对象,但是可以通过匿名内部类(它的一个匿名子类)形式委婉创建。
Motor motor = new Motor() {
// 子类中才能重写父类方法
@Override
public double calRent(int day) {
return 0;
};
- 抽象类虽然无法创建对象,但是依然可以有构造方法,同样也依然可以作为子类对象的引用。
构造方法 照样拥有 是为子类提供的。
Motor motor = new Bus(); - 有抽象方法的类一定是抽象类,但是抽象类不一定有抽象方法。
- 子类继承父类之后,一定要重写父类的所有抽象方法,如果不重写,子类也为抽象类。(父债子偿)
- 抽象方法没有方法体,被abstract关键字修饰。
抽象方法:
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。
抽象方法的声明格式为:
// 抽象关键字 默认返回值 方法名();
abstract void play();
抽象类和普通类的区别:
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:
- 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
- 抽象类不能用来创建对象。
- 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
除此三点,在其他方面,抽象类和普通的类并没有区别。
2.理解接口的作用和含义
接口,英文称作interface,在软件工程中,接口泛指供别人调用的方法或者函数。从这里,我们可以体会到Java语言设计者的初衷,它是对行为的抽象。
在Java中,定一个接口的形式如下:
// public interface 接口名
public interface InterfaceName {
// 静态常量,抽象方法
}
注意事项:
- 声明一个接口使用关键字interface,而不是class,class是用来声明一个类,class和interface是属于同一个级别的。
- 接口里面存放的内容只能是静态常量、抽象方法,其它带方法体的方法或普通的属性都不能放到接口里面。
- 接口不能实例化。
引用方法:
接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。
要让一个类遵循某组特地的接口需要使用implements关键字,具体格式如下:
pbulic class ClassName implements Interface1,Interface2,[....]{
}
接口的特点:
- 接口中只能放静态常量、抽象方法。
- java接口是对功能的扩展(父类和抽象类中一般都存放的是通用的属性和方法,我们一般把扩展的功能或特有的功能放到接口里,而不放在父类或抽象类中)。
- 通过实现接口,java类可以实现多实现 (一个类可以实现多个接口,即一个类可以有多种功能) 。
- 一个类只能继承一个父类,即extends关键字后面只能跟一个父类,但可以通过implements关键字实现,多个接口。
- 接口与接口之间可以通过extends关键字来产生继承关系 (即接口继承接口使用关键字extends) 。
3.接口与抽象类的区别
- 抽象类与实现类之间是一种继承关系,也就是说如果采用抽象类的方式,则父类与子类在概念上应该是相同的。
- 接口和实现类在概念上不要求相同,接口只是抽取相互之间没有关系的类的共同特征,而不去关注类之间的关系,它可以使没有层次关系的类具有相同的行为。
- 抽象类是对一组具有相同属性和行为的逻辑上有关系的事物的一种抽象,而接口是对一组具有相同属性和行为的逻辑上不相关的事物的一种抽象。
- 对于接口和抽象类的选择,反映出设计人员看待问题的不同角度。抽象类用于一组相关的事物,表示的是"is-a"(继承)的关系,而接口用于一组不相关的事物,表示的是"like-a"(具备)的关系。