java 抽象类与接口的区别及其在jdk中的应用
程序员文章站
2024-02-17 17:02:10
...
什么是抽象类
一般而言含有抽象方法的类是抽象类,那什么是抽象方法? 就是只有方法名,没有方法体.
但是,要是没有抽象方法,你写个abstract class xx{} 这个也是抽象类~
那么没有抽象方法的抽象类有什么用呢?
如果你不想该类被实例化,就可以这么写.
抽象类有什么用?
在提取父类的过程中,子类对某一个或多个有共性的方法有不同的实现,父类无法确定如何实现。所以父类就不实现了. 大家干的都是一样的事情,但是具体的实现暂时还不能确定.
举例
//抽象类不能创建对象,专门用作父类的
abstract class Shape{
public abstract double area();//子类有各自的实现方式
}
class Circle_Area extends Shape{
public static final double PI=3.14159;
private double radius;
Circle_Area(double radius){
this.radius=radius;
}
//子类需要重写父类的抽象方法
@Override
public double area() {
return PI*radius*radius;
}
}
抽象类与接口的区别
抽象类中可以有实现了的方法,接口中不可以
如何选择用抽象类还是接口
a. 如果拥有一些方法,并想让他们中的一些有默认的具体实现,请选择抽象类
b. 如果想实现多重继承,那么请使用接口,由于java不支持多继承,子类不能继承多个类,但一个类可以实现多个接口,因此可以使用接口来解决。
c. 如果基本功能在不断变化,那么就使用抽象类,如果使用接口,那么每次变更都需要相应的去改变实现该接口的所有类。
抽象类在源码中的应用
比如,TreeSet的父类,AbstractSet就是个抽象类
- AbstractSet 这个类就是一个没有抽象方法的抽象类~ 因为这里面是有实现了的方法的,所以是不能用接口的
- 抽象类也是可以有构造方法的
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
protected AbstractSet() {
}
public boolean equals(Object o) {
if (o == this)
return true;
...
}
public int hashCode() {
int h = 0;
Iterator<E> i = iterator();
...
}
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
....
}
}
AbstractCollection也是抽象类,其中包含了抽象方法和非抽象方法.
public abstract class AbstractCollection<E> implements Collection<E> {
protected AbstractCollection() {
}
public abstract Iterator<E> iterator();
public abstract int size();
public boolean isEmpty() {
return size() == 0;
}
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
...
}
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
...
}
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
int size = size();
...
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
int i = r.length;
while (it.hasNext()) {
...
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
...
}
public boolean add(E e) {
throw new UnsupportedOperationException();
}
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {
...
}
对比下接口,接口中是不会有实现了的方法的 ,更不会有构造函数
public interface Set<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
Iterator<E> iterator();
Object[] toArray();
boolean add(E e);
boolean remove(Object o);
...
}
抽象类与设计模式
模板方法设计模式.
在一个抽象类中行为方法总是有一个默认行为,子类可以直接使用,也可以覆写。ArrayList继承了AbstractList,没有覆写的方法在使用时,直接使用AbstractList中的方法.
抽象类的缺点
单继承
总结
- 抽象类可以有实现了的方法和构造函数
- 接口中不可以有实现了的方法和构造方法
- 抽象类添加实现了的方法其子类无需改动
- 接口中添加方法其实现必须全部重写
- 抽象类可以用于实现一种设计模式–模板设计模式
下一篇: Java初学——接口interface