第九章 接口
接口和内部类为我们提供一种将接口与实现分离的更加结构化的方法
1、如果实现接口的class未实现接口中的所有函数,则这个class必须被声明为abstract class,而接口中未被实现的函数在这个class中为abstract class。
interface Interface{
public void f();
public void g();
}
abstract class First2 implements Interface{
public void f(){System.out.println("f()");}
// public void g(){System.out.println("g()");}//(a)
//如果屏蔽(a)报错,提示The type First2 must implement the inherited abstract method Interface.g(),所以需要将该类声明为abstract或者实现类里有g()方法
}
class Second2 extends First2{
public void g(){System.out.println("g()2");}
}
public class InterfaceTest {
public static void main(String[] args) {
Interface f = new Second2();
f.f();
f.g();
}
}
2、接口中的所有函数自动具有public访问权限,所以实现某个接口时,必须将承袭自该接口的所有函数都定义为public
interface Interface{
public void f();
void g();
}
abstract class First2 implements Interface{
public void f(){System.out.println("f()");}
// void g(){}
// public void g(){System.out.println("g()");}
//The type First2 must implement the inherited abstract method Interface.g()
}
class Second2 extends First2{
public void g(){System.out.println("g()2");}
//如果去掉public,将报错 Cannot reduce the visibility of the inherited method from
}
public class InterfaceTest {
public static void main(String[] args) {
Interface f = new Second2();
f.f();
f.g();
}
}
3、接口中的数据成员自动成为static和final
interface Interface{
int i=1;
public void f();
void g();
}
abstract class First2 implements Interface{
public void f(){System.out.println("f()");}
// void g(){}
// public void g(){System.out.println("g()");}
//The type First2 must implement the inherited abstract method Interface.g()
}
class Second2 extends First2{
public void g(){System.out.println("g()2");}
//如果去掉public,将报错 Cannot reduce the visibility of the inherited method from
}
public class InterfaceTest {
public static void main(String[] args) {
Interface f = new Second2();
//Interface.i++;//报错,由于i自动为final,不能修改
f.f();
f.g();
}
}
4、Java中的多重继承
1)组合多个类的接口的行为被称作多重继承
2)在导出类中,不强制要求必须有一个是抽象的或“具体的”基类
如果要从一个非接口的类继承,那么只能从一个类去继承,其余的基元素都必须是接口。
如下所示:
interface CanFight{
void fight();
}
interface CanSwim{
void swim();
}
class ActionCharacter{
public void fight(){System.out.println("ActionCharacter");}
}
class Hero extends ActionCharacter implements CanFight, CanSwim{
public void swim(){System.out.println("Hero");};//实现canswim接口的方法
//继承具体类ActionCharacter,同时继承该类的方法
}//
public class Adventure {
static void f(CanFight x) { x.fight(); }
static void s(CanSwim x) { x.swim(); }
static void a(ActionCharacter x) { x.fight(); }
static void h(Hero x){ x.fight(); x.swim();}
public static void main(String[] args) {
Hero hero = new Hero();
f(hero);//static 方法可以直接调用
s(hero);
a(hero);
h(hero);
}
}
5、通过继承来扩展接口
1)通过继承,可以在接口中添加新的方法声明,获得新接口。
2)通过继承在新接口中组合数个接口,获得新接口。
3)Java是不允许通过关键字extends来实现多重继承的,但除了通过多重继承来扩充接口除外。
6、组合接口时名字冲突
在打算组合的不同接口中使用相同的方法名通常会造成代码可读性的混乱,请尽量避免这种事情发生。如下:
interface I1 { void f(); }
interface I2 { int f(int i); }
interface I3 { int f(); }
class C { public int f() { return 1; } }
class C2 implements I1, I2{
public void f() {}
public int f(int i) { return 1; }
}
class C3 extends C implements I2{
public int f(int i) { return 1; }
}
class C4 extends C implements I3{
public int f() { return 1; }
}
//class C5 extends C implements I1{} //(a)
//class C6 extends C implements I1{ public void f(){} } //(b)
//interface I4 extends I1, I3{} //(c)
//class C7 implements I4{
// public void f() {}
// public int f() { return 1; }
//}
(a)(b)(c)处因为覆盖,实现和重载搅在了一起。而且重载方法仅通过返回类型是区分不开的。他们同时定义了f()方法。
7、嵌套接口
嵌套的interfaces可以在定义该内部接口的外部类(接口)之外被使用(但内隐类不行)。
1)当接口嵌套于class中
a. 不论接口为public、friendly或private,都可被实现为public、friendly、private三种嵌套类。
b. 被声明为private的接口不能在class外被使用。
class A{//接口嵌套于类中
private interface B{
void f();
}
//定义内部类BImp实现接口B
public class BImp implements B{
public void f() {}
}
public B getB() { return new BImp(); }
//定义内部类BImp2实现接口B
private class BImp2 implements B{
public void f() {}
}
private B dRef;
public void recivedD(B d){
dRef = d;
dRef.f();;
}
}
public class InterfaceName {
public static void main(String[] args) {
A a = new A(); //(a)
// A.B ab = a.getB();//(b)//接口B是private
// A.BImp = a.getB();//(c)//BImp内部类的作用域为A内
a.recivedD(a.getB());
}
}
虽然A class含有接口,但它仍可被实例化,如(a)。
由于接口B为private,所以在(b)处调用接口B时会出错。但当把接口B声明为public时,(b)将通过编译。但(c)处依然会出错,因为内部类的作用域为定义该内部类的外部类内。
2)当接口嵌套于接口中
a. 嵌套于接口中的接口自动为public,且只能为public。
b. 当实现某个接口时,无需实现其中嵌套的接口。
c. Private接口无法在其所定义的class之外被实现。