接口
抽象类和抽象方法
public enum Note{
MIDDLE_C,C_SHARP,B_FLAT;
}
class Instrument(){
public void play(Note n){
System.out.println("Instrument.play()");
}
}
public class Wind extends Instrument(){
public void play(Note n){
System.out.println("wind.play()"+n);
}
}
public class Music{
public static void tune(Instrument i){
i.play(Note.MIDDLE_C);
}
public static void main(String[] args){
Wind flute = new Wind();
//向上转型
tune(flute);
}
}
//wind.play() MIDDLE_C
上面的代码父类Instrument,可以创建它的对象,并且调用它的方法,但是这么做是没有任何意义的。我们创建父类Instrument的目的只是为了它所有的子类的创建一个通用的接口。这时我们可以将Instrument创建为抽象类。
public abstract class Instrument{
.....
}
这样Instrument只是表示一个接口,没有具体的实现内容。
有抽象类就会有抽象方法。它是一种只有声明没有方法体的方法。
abstract void f();
包含抽象方法的就是抽象类,抽象类中不一定有抽象方法。
如果继承一个抽象类,并且想要创建子类对象,必须为父类抽象类中所有的抽象方法提供方法定义,如果不这么做,那么子类也将是抽象类。
抽象类是一个很有用的重构工具,它使我们可以很容易地将公共方法沿着继承层次结构向上移动。
接口
interface关键字使抽象的概念更进一步,它产生一个完全抽象类的类,根本没有提供任何具体的实现。
接口表示:所有实现了该特定接口的类看起来像这样。接口被用来建立类与类之间的协议。想要创建接口,需要用interface关键字来替代class,接口也可以包含域,但是这些域都是隐式地static和final。
interface Instrument{...}
类实现接口需要用到Implements关键字。
public class A implements B{...}
实现类需要重写接口中的方法,接口中所有的方法都是public,所以在声明时可以省略public
Java中的多重继承
有时我们需要表示“一个x是一个a和一个b以及一个c”,在C++中组合多个接口称为多重继承。
Java只允许从一个类继承,但是可以有多个接口,这样也可以实现多重继承。多个接口在implements后用逗号一一隔开。并且可以向上转型为每个接口。
// extends 必须在前面
public class X extends A implements B,C{....}
学习了抽象类和接口之后,我们会思考什么时候使用接口什么时候使用抽象类?事实上,如果知道某个事物应该成为一个父类,那么第一选择应该是使它成为接口。
通过继承来扩展接口
interface A extends B,C{...}
组合接口时名字冲突
当我们打算组合接口时,一定要避免接口之前有用相同名字的方法。
接口中的域
因为接口中的任何域都自动是static和final的,所以接口就成为了一种很便捷的用来创建常量的工具。
接口中的域不能是空白final,因为接口是没有构造器的,但是可以被非常量表达式初始化。
public interface RandVals{
Random RAND = new Random(47);
int RANDOM_INT =RAND.nextInt(10);
}