------- android培训、java培训、期待与您交流! ----------
1. 接口的书写格式
我们可以把接口理解为一种特殊的抽象类,因为接口特点之一就是它所有的方法都是抽象的。接口的书写格式如下:
代码1:
interface Inter
{
//常量
public static final doublePI = 3.14;
//抽象方法
public abstract void f();
} 接口的标识符是interface,这与类的标识符class是有区别的。通常,在接口内部定义的都是常量和抽象方法,并且两者修饰符都是固定的,常量的修饰符:public static final;方法的修饰符:public abstract。大家需要注意的是:只要定义的是接口,那么其内部的常量和方法的上述修饰符不必手动添加,系统会自动添加缺少的修饰符。但是为了提高代码的阅读性,应尽量将修饰符添加齐全。
2. 接口的用法
接口和抽象类一样,因为抽象方法的存在,无法创建实例对象,也要通过子类“继承”的形式复写方法。对于接口来说,它的子类和接口之间的关系不再称为“继承”,而是称为“实现”,关键字为“implements”。以上述Inter接口为例,
代码2:
interface Inter
{
//常量
public static final doublePI = 3.14;
//抽象方法
public abstract void f();
}
class Demo implements Inter
{
public void f()
{
System.out.println(“Demo run”);
}
}
class InterfaceDemo
{
public static voidmain(String[] args)
{
Demo d =new Demo();
System.out.println(d.PI);
System.out.println(Demo.PI);
System.out.println(Inter.PI);
}
}运行结果为:
3.14
3.14
3.14
这表明,虽然不能调用接口的方法,但是可以通过接口名调用接口内的常量。当然,由于final修饰符的原因,无论是通过接口名、类名还是对象调用该常量,都是不能重新赋值的。此外,上述代码中子类Demo实现了Inter接口,并复写了f()方法。
3. 继承与实现的区别
从形式上看,好像子类实现接口和子类继承抽象父类没有什么区别。实际上,抽象父类中既有抽象方法还有非抽象方法,子类继承了非抽象方法,就可以直接使用了,也就是说子类还是从父类“继承”了一些现成的东西,不必完全由自己定义;而对于接口来说,子类只有把接口的所有方法全部复写一遍,也就说是将这些抽象方法“实现”为真正的有实际用途的方法以后,才能使用。
4. 接口的多实现
所谓多实现,就是一个类可以实现多个接口。多实现的格式如下:
代码3:
interface Inter1
{
public abstract void f_1();
}
interface Inter2
{
public abstract void f_2();
}
class Demo2 implements Inter1, Inter2
{
public void f_1()
{
System.out.println(“f_1run”);
}
public void f_2()
{
System.out.println(“f_2run”);
}
} 子类通过逗号分隔实现的多个接口,并复写所有接口的所有非同名抽象方法。这里为什么要强调非同名方法,因为假如两个接口定义了两个同名的抽象方法(两个方法的返回值类型必须相同,否则会出现编译错误),子类实现了这两个接口以后,实际上只需要复写一次该方法就行了,这就是接口可以实现多实现的原因,因为接口的方法没有方法体,在都只有方法名的情况下不存在子类无法区分两个方法的问题。而继承体系中,如果两个父类定义了两个同名方法,那么子类在继承并调用的时候,就会出现问题。
此外,子类在继承了某个类的情况下还可以进行多实现,比如,
代码4:
class Sub extends Super implements Inter1, Interface2{}小知识点1:
类与类之间是继承;
接口与类之间是实现;
接口与接口之间只能是继承,这是因为,所谓实现,必须由子类将接口的抽象方法复写,并定义具体的实际内容,而接口内部都是抽象方法,也就不可能具体实现了。
5. 接口的多继承
前面的内容中我们讲到,Java中不允许直接地多继承,而是通过其他的方法间接实现,那就是通过接口来多继承。
代码5:
interface Inter1
{
public abstract void f_1();
}
interface Inter2
{
public abstract void f_2();
}
interface Inter3 extends Inter1, Inter2
{
public abstract void f_3();
} 接口可以实现多继承的原因和它允许多实现的原因是一样的,就是因为接口的方法没有方法体,即使方法名相同也不会造成混乱。但是,不能出现方法名相同,而返回值类型不同的情况,比如:
代码5:
interface Inter1
{
public abstract int f();
}
interface Inter2
{
public abstract booleanf();
}
interface Inter3 extends Inter1, Inter2{} 对于上述代码,如果有子类实现了Inter3接口,那么复写了两个f()方法以后,就会出现返回值类型混乱的情况,当调用子类对象的f()方法时无法确定返回值类型到底是什么。那么这就是Java中唯一可以实现多继承的地方,除此以外,均不能进行多继承。
6. 接口的意义
为了大家更好的理解接口的存在意义,我们举一个现实生活中的例子来说明。早期的CPU都是焊死在主板上的,然而CPU的更新换代速度以及人们对CPU处理性能的要求越来越高,将CPU焊死在主板上的方式显然不能满足人们的要求——每次需要升级电脑都要重新购买新的设备。
这个时候,为了提高计算机的扩展性,人们在主板上专门设计了一个通用的CPU插槽,有了这个插槽,就可以方便的更换符合这类插槽“规则”的CPU而不需要重新购买电脑了。有了这种“插槽”的设计,就降低了CPU和主板的耦合性,换句话说,原来CPU和主板之间的关系非常紧密,而现在二者关系的紧密程度大大降低,也就是解耦了。此外,不仅可以设计CPU的插槽,还可以设计显卡插槽、声卡插槽、网卡插槽等等,只要板卡符合对应C插槽的规则就可以使用,大大提高了计算机功能的扩展性,这就是“插槽”的好处。而这里“插槽”就可以理解为程序中的“接口”,同样提高了代码的扩展性。
那么降低了耦合性以后,无论对厂商还是对消费者都是有好处的。对厂商来说,CPU厂商和主板厂商就可以专门研发各自的产品,而不需要分散精力;对于消费者来说,方便的更换自己需要的板卡,随意进行功能扩展。
我们用一段代码来说明接口的意义,比如我们定义车辆(Vehicle)类,车辆类中有一个开车方法(定义了具体的方法体)和加油的抽象方法(因为不同的车加不同的油)。再定义一个轿车(Sedan)类继承车辆类,复写加油方法,并打印“加93号汽油”。我们又希望这个轿车通过改装变成赛车,也就说为它增加一个比赛功能,此时我们为了增加代码的扩展性,定义一个比赛接口,其内部定义一个比赛方法,轿车类实现比赛接口并复写比赛方法即可。
代码6:
/*
定义抽象类——车辆。
由于不同车加不同的油,加油方法定义为抽象方法
*/
abstract class Vehicle
{
//抽象方法,加油
abstract void refuel();
//开车方法
public void drive()
{
System.out.println("开车");
}
}
/*
比赛接口,实现该接口,可获得比赛功能
*/
interface Racing
{
public abstract voidrace();
}
/*
轿车类继承车辆类,复写加油方法;
实现比赛接口,复写比赛方法
*/
class Sedan extends Vehicle implements Racing
{
public void refuel()
{
System.out.println("加93号汽油");
}
public void race()
{
System.out.println("进行赛车比赛");
}
}
class InterfaceTest
{
public static voidmain(String[] args)
{
Sedan s = newSedan();
s.refuel();
s.drive();
s.race();
}
}运行结果为:
加93号汽油
开车
进行赛车比赛
通过这样的设计,可以让有需要的轿车类,通过实现比赛接口,而拥有比赛功能;反之,如果将比赛功能定义在车辆类中,只要继承了车辆类就会拥有比赛功能,而这是不符合现实情况的。
通过上述例子,我们可以进一步理解实现和继承的区别:继承的关系可以理解为“is a”,轿车是车辆的一种,通过继承子类应该拥有该继承体系的基本方法;实现的关系可以理解为“like a”,轿车通过实现比赛接口拥有了比赛功能,扩展了它原有的功能。如果我们再定义别的接口,轿车类就又可以进一步扩展了。因此,接口内应定义扩展功能。
本文详细介绍了接口的概念、书写方式、用法以及多实现、多继承的特点,并通过实例展示了接口如何提高代码的扩展性和降低耦合性,进而解释了接口在编程中的核心价值。
1172

被折叠的 条评论
为什么被折叠?



