今天继续填坑,讲一下接口。说起接口,其实我们可以把它当做一种特殊的抽象类,接口中有着抽象方法。但不同于类的是,它可以存在一个类有多个接口。接下来,我用一个例子形象的描述一下接口。
例如,有两个抽象类:Animal和Fruit,其中Fruit的子类均可以食用,而Animal中存在一些子类(Tiger)不能被食用。如果我们要构建一下howToEat()方法,按照上一次我们讲的多态知识,我们会在抽象类Animal和Fruit中构造howToEat方法,然后被子类所继承。但是这就带来一个问题,由于子类必须强制重写抽象父类中的howToEat方法,使得Tiger这个不能食用的类也要重写方法。这就给我们袋来了一些逻辑上的不便。此时。接口应运而生。
接口在这个例子中,可以当作一个类中的一种共同的方法,只要让能食用的类接上这个接口,就可以构造了这个方法了。
public interface Edible {
public abstract String howToEat ( ) ;
}
接着再构建几个类。
abstract class Animal {
}
class Chicken extends Animal implements Edible {
@Override
public String howToEat ( ) {
return "Chicken: Fry it" ;
}
}
class Tiger extends Animal {
}
abstract class Fruit implements Edible {
}
class Apple extends Fruit {
@Override
public String howToEat ( ) {
return "Apple: make apple cider" ;
}
}
class Orange extends Fruit {
public String howToEat ( ) {
return "Orange: make orange juice" ;
}
}
可以发现,父类接上了接口后,子类也会自动接上了父类接口。同时接口还可以定义成一个数组,通过多态实现向上转型,我们可以看一个例子。
Edible[ ] edibles = {
new Chicken ( ) , new Apple ( ) , new Orange ( ) } ;
for ( Edible e : edibles) {
System. out. println ( e. howToEat ( ) ) ;
}
在上面代码中,我用接口实例化了三个类。这里有个好处就是,当我想实例化Tiger的时候,系统因为检测到Tiger没有存在这个接口而报错。这里其实就有类似于泛型的意思了,如果没有用接口,而是使用Object类来建立一个数组,想要实现howToEat就要进行判断了。
Object[ ] objects = {
new Tiger ( ) , new Apple ( ) , new Chicken ( ) } ;
for ( Object o : objects) {
if ( o instanceof Edible )
System. out. println ( ( ( Edible) o) . howToEat ( ) ) ;
}
如上述代码所示,要进行判断。说完了接口,今天又来增加额外的知识点:泛型。泛型的定义是:参数化类型。简单说就是系统通过自动识别传入的参数,如果不符合类型就会报错。我们举个简单的例子。
List list = new ArrayList ( ) ;
list. add ( "Qiqi" ) ;
list. add ( "MiaoMiao" ) ;
list. add ( 100 ) ;
for ( int i= 0 ; i< 3 ; i++ )
{
String a = ( String) list. get ( i) ;
System. out. println ( a) ;
}
这里先建立了List系列的集合,向里面储存字符串和整数,但是当我们运行后发现系统报错。主要原因是我们要取出字符串类型的数据,但是有个整形数字混在其中,导致出错。如果我们要规定输入的数据一定是字符串,为了防止出错,我们可以使用泛型。
List< String> list = new ArrayList ( ) ;
list. add ( "Qiqi" ) ;
list. add ( "MiaoMiao" ) ;
for ( int i= 0 ; i< 2 ; i++ )
{
String a = ( String) list. get ( i) ;
System. out. println ( a) ;
}