抽象类和接口这两者有太多相同的地方,也有许多不相同的地方,我们在使用他们的时候一定要注意区分。
抽象类
抽象类就是为了继承而存在的。包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。
class Flower extends Shape{
}
注意点:(与普通类的区别)
1.抽象类不能被实例化
2.如果一个普通类继承了抽象类,那么这个普通类一定要重写抽象类当中的抽象方法
3.抽象方法必须是public或者protected,不能是private(因为如果为private,则不能被子类继承,子类便无法实现该方法)
4.如果一个类(A)继承了抽象类,且不想重写抽象类方法,那么这个类(A)就只能定义为抽象类了。最后,一旦有其他类继承了这个抽象类(A),那么一定要重写这个抽象方法。(出来混总是要还的)
5.抽象类也可以发生向上转型和多态
接口
接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。
class Flower implements IShape{
}
注意点:
1.接口里面的方法默认都是public abstract
2.所有的成员变量一定是public static final的
(以上1,2两种在接口里面都是默认的,一般都不写)
3.接口也是不可以被实例化的
4.类和接口的关系是implements的关系
5.接口也是可以发生向上转型的,也就是可以发生多态
6.一个类可以实现多个接口
7.接口之间可以互相扩展
一旦有类实现了接口ID,那么这个类需要重写的就是IA,IB,ID三个接口的抽象方法
8.接口的出现,弥补了java的缺陷,可以进行多继承了
理解接口
如有一个父类Animal,然后三个接口run,swim,fly
对于Cat,他就可以继承Animal,然后实现run这个接口
(Cat extends Animal implements run)
对于Duck,他就可以继承Animal,然后实现run和swim这两个接口
(Duck extends Animal implements run,swim)
如果要把这些都写到动物里面,但是不是所有的动物都会飞,跑,游泳,所以继承Animal只是为了让其拿到所有Animal的公有属性,而各种动物不同的行为就可以通过接口来实现
让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力。
像在这个写这个walk方法的时候,参数定义为IRunning接口,里面在使用这个参数的时候,不需要知道传进来的具体是什么,只需要知道它是会跑的就行
- 封装让我们忘记类的实现细节
- 继承让我们忘记传进来的是什么类型,只要是子类就行(Animal animal,传入动物的子类)
- 接口让我们忘记所有,只需要知道它有这种特性就行(IRunning irunning,传入会跑的东西,也就是能实现这个接口的东西)
抽象类和接口区别
参数 | 抽象类(abstract class) | 接口(interface) |
结构组成 | 普通类+抽象方法 | 抽象方法+全局常量 |
默认的方法实现 | 它可以有默认的方法实现 | 接口完全是抽象的。它根本不存在方法的实现 |
与Java普通类的区别 | 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 | 接口是完全不同的类型 |
方法的访问修饰符 | 抽象方法可以有public、protected和default这些修饰符(注意不能是private) | 接口方法默认修饰符是public。你不可以使用其它修饰符。 |
变量的访问修饰符 | 可以是修饰符 | 只能是public static fianl(全局常量) |
main方法 | 抽象方法可以有main方法并且我们可以运行它 | 接口没有main方法,因此我们不能运行它。 |
多继承 | 抽象类可以继承一个类并实现多个接口 | 接口只能继承接口(一个或多个,使用extends关键字) |
子类使用 | 使用extends关键字继承抽象类 | 使用implements关键字实现接口 |