JAVA-抽象类和接口
1.抽象类
- 抽象类不可以用于创建对象.抽象类可以包含抽象方法,这些方法将在具体的子类中实现.
- 关键词: abstract
1.1 概念
- 抽象类: 类的设计应该确保父类包含其子类的共同特征.有时候一个父类设计的非常抽象,以至于其都没有任何具体的实例.这样的类便称之为抽象类.(不能使用new操作符创建其实例)
- 抽象方法: 有些方法其实现取决于具体的子类对象类型,不能在父类中实现.
用"abstract"进行修饰这样的方法或类. (实现由子类提供) - 一个包含抽象方法的类必须声明为抽象类.
eg.abstract在类或方法中具体修饰位置
abstract class Xxx{
public abstract void xxx(){}
}
1.2 说明
- 抽象方法不能包含在非抽象类中.
抽象类的非抽象子类中必须实现所有的抽象方法. 抽象方法是非静态的. - 抽象类不能使用new操作符来初始化.
但仍可以定义其构造方法,其构造方法在其子类的构造方法中调用. - 包含抽象方法的类必须是抽象的.
但是可以定义一个不包含抽象方法的抽象类用作定义新子类的基类. - 子类可以重写父类的方法并将其定义为抽象的(很少见).
有时候作为父类的方法实现在子类中变得无效很有用.此时子类需定义为抽象的. - 如上,父类是具体的子类也可以是抽象的.(Object类为具体的,其子类可以自定义为抽象/具体)
- 不能使用new操作符为抽象类创建实例,但抽象类可以用作一种数据类型.(创建抽象类对象数组)
2.接口
- 接口是一种与类相似的结构,用于为对象定义共同的操作.(指明相关或不相关的类的对象的共同行为)
- 关键词: interface定义; implements实施
- 空接口(标记接口)不含常量和方法,其用来表示一个类拥有某些希望具有的特征(Cloneable)
eg.具体使用
public interface Edible{
public abstract String howToEat();
}
- 接口被看作特殊的类,与抽象类大致类似,不能使用new操作符创建具体实例.
- 类和接口之间的关系称为接口继承或者继承(接口继承和类继承本质上相同)
2.1 Comparable接口
- Comparable接口定义了compareTo方法,用于比较对象.
- 判断给定对象o的顺序,当这个对象小于/等于/大于给定对象o时,返回负整数/0/正整数
- 为泛型接口<E>, 常见的java类与包装/基本数据类型都含有此接口。
- compareTo应该与equals保持一致。
定义如下
package java.lang;
public interface Comparable<E> {
public int compareTo(E o);
}
//eg.
a.compareTo(b);
2.2 Cloneable接口
protected native Object clone() throws CloneNotSupportedException;
- Cloneable接口指定了一个对象可以被克隆
- 为空接口(标记接口),实现该接口的类型标记为可克隆的,而且其对象可以使用在Object类中定义的clone()方法克隆(clone()需重写).
- 因为Object类中的clone方法针对自身平台(native)完成了克隆对象的任务,所以在子类中的clone方法只需简单调用super.clone()即可,需注意异常处理.
定义如下:
package java.lang;
public interface Cloneable{
}
//eg. 着重注意其clone方法
ArrayList<Double> list1 = new ArrayList<>();
ArrayList<Double> list2 = (ArrayList<Double>)list1.clone();
注:
- 浅复制: Object类中的clone方法将原始对象的每个数据域复制给目标对象.若一个数据域是基本类型,复制的就是它的值.若一个数据域是对象,复制的就是该域的引用.
- 深复制: 数据域也复制其值而非引用.
执行深复制时需要将对应的引用单独拿出来进行复制:(Class)o.clone();
3.抽象类与接口简单比较
- 一个类可以实现多个接口(允许使用接口作多重继承),但是只能继承一个父类
- 接口可以继承其他接口(多个)但不能继承类;一个类可以继承它的父类同时实现多个接口(implement).
- 所有类共享同一个根类Object,但接口没有共同的根.
- 类名只是一个名词,接口名可以是形容词或名词.
主要区别:
变量 | 构造方法 | 方法 | |
---|---|---|---|
抽象类 | 无限制 | 子类通过构造方法链调用构造方法,抽象类不能用new操作符实例化 | 无限制 |
接口 | 所有变量必须是public static final | 没有构造方法.接口不能用new操作符实例化 | 可以包含public的抽象实例方法,public的默认方法以及public的静态方法 |
使用注意:
抽象类和接口都是用来指定多个对象的共同特征的.一般来说,清晰描述父子关系的强(is-a)"是...的一种"关系应该用类建模.弱的"是...的一种"关系也成为类属关系,表明对象拥有某种属性,可以用接口来建模.
通常,推荐使用接口而非抽象类,因为接口可以为不相关类定义共同的父类型.接口比类更灵活.
eg.howToEat方法 详见BasicJava-Edible-Test.java