本文纯粹是个人理解和思考总结,如有错误,请帮忙指出,多谢。对应于java8
抽象类和接口之间有没有既生瑜何生亮的问题呢?
一、功能
可以说,抽象类和接口都算是一种抽象,是在某些共有特性上的抽离集成。个人觉得可以简单的理解为对公共行为、功能、属性的一种封装。可以限制继承者的随意性、保证功能一致性,同时也可以简化开发、提高效率、便于管理维护。
二、抽象类和接口是否冗余
不然,可以举个例子来说明一点,如果我们将动物作为抽象类,让熊猫继承动物类
可以理解成:熊猫是动物,这是属于关系
而对于接口,侧重于对行为的抽象,比如一个接口中定义唱歌和跳舞方法,动物和机器人实现该接口。这就不是属于关系了,而是具有关系,表示其继承实现者具有这样的能力或者行为。
从这个区别来看,也就容易理解他们的一个区别:某个子类只能继承一个抽象类,却可以继承多个接口了。熊猫只能是动物,不能是植物。而因为接口体现的是功能和行为表现,当然可以不同,所以可以继承多个。
三、基于以上基本点分析抽象类和接口的异同
1、同
- 抽象类和接口都不能被实例化。
想想看,对于一个只有方法声明的抽象类或者接口,就算让它实例化,又能用来干什么?是不是什么都干不了。 - 都可以被继承
这个无需解释 - 都可以包含方法声明
这个也无需解释,子类根据不同的需要做具体实现,这是其价值的体现
需要注意的是,在抽象类中只进行声明的方法也必须是抽象的。可以看出,抽象方法都是子类必须实现的,这样强制保证了声明的实质性。 - 子类必须实现其所继承的抽象类中或者接口中声明的方法
2、异
- 修饰方式不同,抽象类使用abstract修饰,而接口使用interface修饰。
- 在构造函数上,抽象类可以有构造函数,而接口没有。
这个怎么理解?我们先看看下一个不同,然后再反过来看这一问题。 - 抽象类中可以有普通变量、域,而接口中没有。
因此,上边的问题可以这样理解,构造函数能够创建对象,可以在构造函数中对其属性进行赋值等操作,从而继承抽象类的子类可以根据自身需要,对属性赋予不同的值。而接口中没有这些字段,而且子类与其继承的接口中的行为之间也不是“属于”关系,而是“具有”关系。因此在接口中也就不需要这种需求。 - 接口中的变量默认都是public final static的,而抽象类中不需要这个限定,可以包含非public、final、static的变量。
- 抽象类中可以有方法具体实现,而接口中只能有方法声明(java8之前)。java8中在接口中也能定义方法,不过需要加static或者default修饰。
接口的这个变化,可以解释为允许事物在某些行为上的通性,用来定义一致性具体行为实现。这是合理的。 - 接口中的方法默认都是public abstract的。而抽象类中的方法可以是abstract的,也可以不是abstract的,方法的修饰符也可以是private、protected、public。
- 一个类只能继承一个抽象类,而可以实现多个接口。这在前边已经提到。
- 接口可以继承接口,不能继承类,但抽象类既可以继承接口、也可以继承抽象类。