第9章 接口 (Interface)
9.1 抽象类和抽象方法
在 java 中,基类很多时候都只是为了给导出类提供一些公共的通用接口(方法),所以基类只表示一种基本形式。 这时候就有了抽象类的概念。
含有抽象方法的类叫做抽象类。是用 abstract 关键字定义的。抽象方法是说,只有定义,而没有具体实现的方法。
abstract chouxiangfangfa(); // 后面一般不写花括号。
所以这样来看,由于抽象类中含有无实现的方法,所以 抽象类并不能用来创建对象。
所以,正如上面第一段所说,抽象类生来就是为了继承而存在的。
这里看一下抽象类和普通类的区别:
- 抽象类不能创建对象;
- 抽象方法必须为可以被继承类访问的(因为继承类需要来写抽象方法的具体实现),所以应该为 public/protected,默认的 pub
- 抽象类的继承类必须给出父类中抽象方法的具体实现,否则,子类也必须 用 abstract 关键字定义成抽象类。
9.2 接口
这里的接口,特指 java 中的 Interface 关键字定义的接口(通常情况下,接口泛指别人调用的方法或者函数)。
接口实际上是对抽象类的进一步深化。抽象类中的抽象方法是没有任何实现的方法,而接口中所有的方法都是只有定义,而没有方法体的方法,是一个 极度抽象类。
接口除了方法外,也可以包含域,但是隐式地被定义为 static & final。
让一个类遵循某个(也可以多个)特定接口,用 implements 关键字,表示 “interface 只是其外貌,现在要说明其具体是如何工作的”。
抽象类和接口的区别:
- 抽象类可以提供成员方法的实现细节,接口只能是 public abstract 方法;
- 抽象类中成员变量可以是各种,接口中 只能是 static final
- 一个类可以继承一个抽象类,而 一个类可以实现多个接口(extends 只能一个,implements 可以多个)
9.3 完全耦合
9.4 java 中的多重继承
这里说的意思就是,我们可以通过接口来实现多继承的形式。这里用 implements A,B,C 这样形式的关键字即可。看下面的代码:这里的接口就可以向上转型(和类的感觉是一样的),所以下面 main() 函数中,是有向上转型处理的。
package Interface;
interface CanFight{
void fight();
}
interface CanSwim{
void swim();
}
interface CanFly{
void fly();
}
class ActionCharacter{
public void fight(){}
}
class Hero extends ActionCharacter implements CanFight,
CanSwim, CanFly{
public void swim(){}
public void fly(){}
}
public class Adventure {
public static void t(CanFight x){x.fight();}
public static void u(CanSwim x){x.swim();}
public static void v(CanFly x){x.fly();}
public static void w(ActionCharacter x){x.fight();}
public static void main(String args[]){
Hero h = new Hero();
t(h); // 当做 CanFight 来处理
u(h); // 当做 CanSwim 来处理
v(h);
w(h);
}
}
9.5 通过继承来扩展接口
意思是说这里的接口不仅可以 implements 实现,还可以 extends 来继承。和类的继承是一样的。
package Interface;
interface Monster{
void menace();
}
interface DangerousMon extends Monster{ // 由于继承,DangMon 接口有 2 个方法。
void destroy();
}
interface Lethal{
void kill();
}
class DragonZilla implements DangerousMon{ // 这里就实现了 其 2 个方法。
public void menace(){} //
public void destroy(){}
}
interface Vampire extends DangerousMon, Lethal{
void drinkBlood();
}
class VeryBadVampire implements Vampire{
public void menace(){}
public void destroy(){}
public void kill(){}
public void drinkBlood(){}
}
public class HorrowShow{
static void u(Monster b){b.menace();}
static void v(DangerousMon s){s.menace();
s.destroy();}
static void w(Lethal l){l.kill();}
public static void main(String args[]){
DangerousMon mike = new DragonZilla();
u(mike);
v(mike);
Vampire shine = new VeryBadVampire(); // 向上转型
u(shine);
v(shine);
w(shine);
}
}
9.6 适配接口
9.7 接口中的域
前面我们说过,接口中的 域 自动声明为 static final。
9.8 嵌套接口
接口可以嵌套在其他的类或接口中。
9.9 接口和工厂 factory
生成遵循某个接口对象的典型方式就是 工厂方法 设计模式。
这里所谓的 “工厂方法” ,就是说用一个方法(这里是 getService()方法)来生成接口对象。如下面代码所示,Service接口有两个继承的接口 Imple1 和 Imple2,而 ServiceFactory 也有两个继承接口 分别可以生成 Imple1 接口对象和 Imple2 对象。
package Interface;
// 说的是接口和工厂
interface Service{
void method1();
void method2();
}
interface ServiceFactory{
Service getService();
}
class Imple1 implements Service{
Imple1(){} // Package access
public void method1(){System.out.println("实现1.方法1");}
public void method2(){System.out.println("实现1.方法2");}
}
class Imple1Fact implements ServiceFactory{
public Service getService(){
return new Imple1();
}
}
class Imple2 implements Service{
Imple2(){} // Package access
public void method1(){System.out.println("实现2.方法1");}
public void method2(){System.out.println("实现2.方法2");}
}
class Imple2Fact implements ServiceFactory{
public Service getService(){
return new Imple2();
}
}
public class Factories {
public static void serviceConsumer(ServiceFactory fact){
Service s = fact.getService();
s.method1();
s.method2();
}
public static void main(String args[]){
serviceConsumer(new Imple1Fact()); // upcast
serviceConsumer(new Imple2Fact());
}
}
/*output
实现1.方法1
实现1.方法2
*/
网友评论