一、关于抽象类
抽象类的特点:
(1)用abstract作为类修饰符。
(2)构造方法访问类型应该为protected。
(3)抽象方法在子类中若未重写,则必须再次声明为abstract。
(4)若想实例化抽象类,则其子类必须重写父类的所有抽象方法。并且父类要指向子类的实例。
例如:Father f = new Child();//Father为抽象父类,Child为其子类,且已重写父类所有抽象方法。
(5)抽象方法是非静态,非私有的。
(6)抽象方法所在的类必须声明为抽象类,但一个抽象类 可以没有抽象方法,该抽象类仅用于作为定义新子类的基类。
(7)抽象类不能使用new来进行初始化,但抽象类的数组可以,例如A是一个抽象类,那么A[] a = new A[3];这是可以的。
(8)一个非抽象父类可以有抽象子类。父类中的非抽象方法可以在子类中重写为abstract的,相应的此时子类也必须声明为抽象类。
(9)一个类只能继承一个直接父类,如果其父类实现了多个接口,那么子类也间接实现了这些接口。
(10)一个抽象类若实现了接口,不是必须实现该接口的所有方法,换言之,可以不实现该接口的方法。
抽象类存在的意义:
(1)为了将一些相关类中的公共成员方法抽离出来,只声明方法,子类去进行各自不同的实现。所谓相关的类,指的是:父类与子类具有相类似的属性及方法,父类抽象了类的共同属性及方法,子类具化行为。
二、关于接口
接口的特点:
(1)用interface作为修饰符。接口是抽象方法和常量值的定义的集合。接口本质上是一种特殊的抽象类。这种抽象类中只包含方法和常量的定义,没有变量和方法的实现。在JDK8以后,可以声明default方法和静态方法
(2)接口中的数据域(成员变量)默认都是public static final的,所有方法默认都是public abstract。这些修饰符可以省略。
(3) 一个类可以实现多个接口。一个接口可以由多个类实现。
(4)一个接口可以继承多个接口。接口可以实现多重继承这种逻辑并避免C++在实现多重继承时存在的缺陷。接口中的成员变量只能是静态且final的,因此即便多继承,在子接口引用时也能分清调用的是哪个接口中的成员变量。
看这个例子:
public interface MultiInterface extends Play,Work{
}
这里注意:接口Play,Work里可以存在相同的方法定义,但不可以有某些方法名相同但返回值不同的方法,这就好像一个类中不能有这种情况是一个道理,不然无法判断是调用的哪个方法。
(5)接口实际上就是暴露实现类的一部分方法。实现多个接口的一个类可以在接口指向其对象的时候,对象间进行强制转换,从而达到调用不同方法的目的。
public interface Sport{
public void run();
public void jump();
}
public interface Play {
public void playGame();
public void dance();
}
public class InterfaceTest implements Sport,Play{
public static void main(String[] args) {
Sport s = new InterfaceTest();
s.jump();
Play p = (Play)s;
p.dance();
}
}
运行结果:
(4)没有构造方法,因此也不能用new操作符实例化。
因此在某些场合下,可以这样设计类。Animal是抽象父类,定义了抽象方法sound,而它的子类都具有这个行为,也都同属于Animal大类,比如Chicken、Tiger。Fruit是抽象父类,子类是Apple。Fruit与Animal本来没有任何关联,但Animal的子类Chicken与Fruit有一些共同的行为特点,即可食用(Edible),因此可定义接口Edible来专门声明这些原本不同类的共同行为或特征。
注意:java 8关于接口的新特性:
- 引入了使用关键字default的默认接口方法。提供一个默认实现。实现这个接口的类可以使用该默认方法或重写该方法。这一特性可以方便的实现在接口中增加一个新方法而无需将实现类重新编码并增加此方法的实现。
- 接口中可以存在公有静态方法。使用方法与类的公有静态方法一样。以下是关于这两个新特性的例子,接口A的定义:
public interface A{
/**default method*/
public default void doSomething(){
System.out.println("Do something!");
}
/**static method */
public static int getAValue(){
return 1;
}
}
三、抽象类及接口的应用场景
抽象类及接口在设计模式中被经常提到及使用。以下是一个具体的例子:
-
抽象类与接口的抽象层次是不同的
抽象类是对类抽象,接口是对行为抽象。类包含了属性与行为,所以说接口是更具体的抽象
-
抽象类与接口的设计层次是不同的
抽象类是一种自下而上的设计,先有子类才能提取共同的属性与行为,抽象出父类; 接口是一种自上而下的设计,先规定行为方法,只要可以实现这些行为,就可以成为接口的实现类。
-
抽象类与其派生类的关系和接口与其实现类的关系本质是不同的
抽象类与其派生类是一种 is-a 关系,即父类和派生子类在概念上的本质是相同的(父子关系,血缘联系,很亲密)。 接口与其实现类是一种 like-a 关系,即接口与实现类的关系只是实现了定义的行为,并无本质上的联系(契约关系,很淡漠的利益关系)。