继承分为两种:单一继承和多重继承。
多重继承:一个类可以有多个父类,这多个父类中的属性和方法都会被这个子类继承下来。一个父类可以有多个子类,继承关系不在是一棵树,而变成了网。多重继承比单一继承情况要复杂。C++支持多重继承。
单一继承:一个类只能有一个父类。Java语言实现的是单继承。单继承易于管理,更加安全可靠。
但是现实应用中,需要使用多重继承功能。Java要实现多重继承需要使用到接口来实现。
接口是Java中用来实现多重继承的一种结构。接口可以看成是一种特殊的抽象类。
接口使用关键字interface来定义。接口由成员属性和成员方法两部分组成。接口可以继承其他接口,也可以被其他接口和类实现。类继承接口也可被称为实现。
接口的定义
[访问权限修饰符] interface 接口名 [extends 父接口名1,父接口名2...]{
//定义成员变量
[public] [static] [final] 数据类型 变量名=初始值 ;
....
//定义成员方法
[public] [abstract] 返回类型 方法名([参数列表]);
}
1.interface关键字表明这是一个接口,访问权限修饰符和类的使用一样。默认为包访问权限,一般用public修饰。
2.extends和类中的一样,但是接口只能继承接口。
3.接口中的变量都是常量。默认情况下,接口中的成员变量具有public、static和final所联合规定的属性。static和final不可替代,成员的属性只能是静态的、最终的,也即是静态常量。在接口中不允许出现protected和private,所有的属性都是public。
4.接口中的所有方法都是抽象的方法。在默认情况下,接口中的方法具有public和abstract联合规定的属性。pubic不可变,abstract和static不能联合使用。
5.接口中都是抽象的方法,构造方法不能是抽象方法。因此,接口中国没有构造方法。
接口示例:
BaseColor.java
interface BaseColor{
int RED = 1 ;
int GREEN = 2 ;
int BLUE = 4 ; //静态方法
int getColorValue(int color) ; //抽象的公共方法
}
接口的所在的文件也是.java文件,编译后也能得到.class文件。
接口定义后,可以用这个接口来定义变量,但是不能将这个变量进行实例化(由于接口都是抽象的)。
由于接口中的成员属性都是静态的,因此,可以用“
接口名.变量名”的形式来引用。
int r = BaseColor.RED ;
接口的继承
接口的继承规则同于类,因为接口中的方法都是public,所有的成员变量都是公共的静态常量,因此其继承比较简单。
接口在继承过程中也可以实现方法的覆盖,但是接口中的方法都没有实现,所以这种覆盖没有意义。
在接口中可以实现多继承。
接口的继承:RainbowColor.java
interface RainbowColor extends BaseColor{
int YELLOW = 3 ;
int ORANGE = 5 ;
int INDIGO = 6 ;
int VIOLET = 7 ; //新增加4个变量。
}
RainbowColor接口中继承了BaseColor接口中的三个常量和一个方法。
//再定义一个接口
interface PrintColor extends BaseColor{
int YELLOW = 8 ;
int CYAN = 16 ;
int MAGENTA = 32 ;
int getColorValue(int color); //覆盖了父接口中的方法
int getColorValue(); //在接口中实现了重载。
}
接口是可以实现多继承的。
LostOfColors.java
interface LostOfColors extends RainbowColor, PrintColor{ //多继承的实现
int FUCHSIA = 17 ;
int VERMILION = 43 ;
int CHARTREUSE = RED + 90; //增加了三个成员常量
}
LostOfColor接口从两个父接口中继承,最终合并为一份。YELLOW属性有两个不同的值,虽然YELLOW同名,但是LostOfColor不会将两个属性合并。在通过LostOfColor调用YELLOW时,无法直接使用YELLOW,需要通过接口名才能使用,如RainbowColor.YELLOW或PrintColor.YELLOW。
在接口中继承时,方法名相同时的处理:
(1)当方法的名称,参数,返回值类型都完全相同时,这两个方法将会合并为一个方法。
(2)当返回值类型不同时,这既不是重载又不是覆盖,编译出错。
接口的实现
接口的最终目的是需要类来实现的。类对接口的继承被称为接口的实现。类在实现接口时使用implements。
若干没有继承关系的类可以实现同一个接口,一个类也可以实现多个接口。这些接口都称为该类的父接口或超接口。
接口中的方法都是抽象方法,一个非抽象类继承了接口必须要实现其中的所有的方法。抽象类不受此限制。
[访问权限修饰符] class 类名 [extends 父类名] [implements 接口名1,接口名2...]{
//实现接口中的抽象方法
public [返回值类型] 方法名([参数列表]){
//方法体
}
}
注意:实现接口中的方法时,方法的访问权限一定要是public【因为接口中的方法都是public类型的,所有子类不能缩小方法的访问权限。】
建议将接口名的第一个字母设置为“I”以表明这是一个接口。
子类通过父类继承下来的方法,子类不需要在实现接口时,再实现一遍。
示例:
Colorable.java
package com.leo.interfacetest;
public interface Colorable { //定义一个接口
void setColor(int color) ;
int getColor() ;
}
Paintable.java
package com.leo.interfacetest;
public interface Paintable extends Colorable{
int MATTE = 0 ;
int GLOSSY = 1 ;
void setFinish(int finish);
int getFinish();
}
Point.java
package com.leo.interfacetest;
public class Point {
int x ;
int y ;
}
ColoredPoint.java
package com.leo.interfacetest;
public class ColoredPoint extends Point implements Colorable{
//定义一个成员变量。
int color ;
//实现接口中的所有方法,必须实现。
public void setColor(int color){
this.color = color;
System.out.println("Set Color.");
}
public int getColor(){
System.out.println("Get Color.");
return this.color ;
}
}
PaintedPoint.java
package com.leo.interfacetest;
public class PaintedPoint extends ColoredPoint implements Paintable{
//Paintable接口中有四个抽象方法,但是ColoredPoint已经实现了其中的两个
//PaintedPoint类只需要实现声响的void setFinish(int finish)和int getFinish()
int finish ;
public void setFinish(int finish){
this.finish = finish ;
}
public int getFinish(){
return this.finish ;
}
//通过接口来调用接口中的方法。在调用example()函数时,传入参数为实现了Colorable接口的类对象。
//由此可以看出,Colorable接口可以接受一个实现了其方法的类。
public void example(Colorable e){
e.getColor();
}
public static void main(String args[]){
PaintedPoint oa = new PaintedPoint();
ColoredPoint ob = new ColoredPoint();
//通过实现接口的对象调用接口的方法。
oa.example(ob);
}
}