接口与实现


1 接口

为了克服Java单继承的缺点,Java使用了接口,一个类可以实现多个接口

使用关键字​interface​来定义接口。接口的定义和类的定义很相似,分为接口的声明和接口体。



接口声明
——使用关键字interface来声明
——格式: interface 接口名字



接口体
—— 接口体中包含常量定义和方法定义两部分。接口体中只进行方法的声明,不提供方法的实现,且用分号结尾。



例如:

interface Printable {
final int MAX = 100;
void add();
float sum(float x, float y);
}


1 接口中变量自动是 public、static、final
2 接口中的方法默认是 public abstract
3 接口也产生class文件
4 接口中的方法不能被static和final修饰,因为要重写所有接口中的方法
5 接口中没有构造方法


2 实现接口

1、一个类通过使用关键字implements声明自己实现一个或多个接口。​*

如: class A implements Printable,Addable

2、如果一个非抽象类实现了某个接口,那么这个类必须重写该接口的所有方法,而且方法的访问权限​一定要显示地用public来修饰。​

3、接口可以通过继承产生新的接口。

4、Java提供的接口都在相应的包中,通过import语 句不仅可以引入包中的类,也可以引入包中的接口,
例如:import java.io.*;

5、如果一个类声明实现一个接口,但没有重写接口中的所有方法,那么这个类必须是抽象类,也就是说,抽象类既可以重写接口中的方法,也可以直接拥有接口中的方法。
程序可以用接口名直接访问接口中的常量,但是一个类实现了该接口,那么可以在类体中直接使用该接口中的常量。

6、定义接口时,如果关键字interface 前面加上public关键字,就称这样的接口是-一个public接口。public 接口可以被任何一个类实现。如果一一个接口不加public修饰,就称作友好接口,友好接口可以被与该接口在同一包中的类实现。
7、如果父类实现了某个接口,那么子类也就自然实现了该接口,子类不必再显式地使用关键字implements声明实现这个接口。
8、接口也可以被继承,即可以通过关键字extends声明一个接口是另一个接口的子接口。
由于接口中的方法和常量都是public的,子接口将继承父接口中的全部方法和常量。

例子1中 包含有China类、Japan 类和Computable接口,而且China和Japan类都实现了Computable接口

//Computable.java
public interface Computable {
int MAX = 46;
int f(int x);
}

//China.java
public class China implements Computable { //China类实现Computable接口
int number;
public int f(int x) { //不要忘记public关键字
int sum=0;
for(int i=1;i<=x;i++) {
sum=sum+i;
}
return sum;
}
}

//Japan.java
public class Japan implements Computable { //Japan类实现Computable接口
int number;
public int f(int x) {
return MAX+x;
}
}

//Test.java
public class Test {
public static void main(String args[]) {
China zhang;
Japan henlu;
zhang=new China();
henlu=new Japan();
zhang.number=32+Computable.MAX;
henlu.number=14+Computable.MAX;
System.out.println("zhang的学号"+zhang.number+",zhang求和结果"+zhang.f(100));
System.out.println("henlu的学号"+henlu.number+",henlu求和结果"+henlu.f(100));
}
}

【Java 接口与实现(详细版)】_抽象类

3 接口回调

接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法。实际上,当接口变量调用被类重写的接口方法时,就是通知相应的对象调用这个方法。

//分析:
Com com;//声明接口对象
ImpleCom obj = new ImpleCom();//实现接口子类对象
com = obj; //接口回调

【Java 接口与实现(详细版)】_编程语言_02

interface  ShowMessage {
void 显示商标(String s);
}
class TV implements ShowMessage {
public void 显示商标(String s) {
System.out.println(s);
}
}
class PC implements ShowMessage {
public void 显示商标(String s) {
System.out.println(s);
}
}
public class Example {
public static void main(String args[]) {
ShowMessage sm; //声明接口变量
sm=new TV(); //接口变量中存放对象的引用
sm.显示商标("长城牌电视机"); //接口回调。
sm=new PC(); //接口变量中存放对象的引用
sm.显示商标("联想奔月5008PC机"); //接口回调
}
}

4 理解接口

理解的关键点是:
(1)接口可以抽象出重要的行为标准,该行为标准用抽象方法来表示。
(2)可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被该类实现的接口方法,即体现该类根据接口里的行为标准给出的具体行为。

接口的思想在于它可以要求某些类有相同名称的方法,但方法的具体内容(方法体的内容)可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)。接口在要求一些类有相同名称的方法的同时,并不强迫这些类具有相同的父类。

例子3中,要求MotorVehicles类(机动车)的子类Taxi (出租车)和Bus(公共汽车)必须有名称为brake的方法(有刹车功能),但额外要求Taxi类有名字为controlAirTemperature和charge的方法(有空调和收费功
能),即要求Taxi实现两个接口,要求客车类有名字为charge的方法(有收费功能),即要求Bus只实现一个接口。

abstract class MotorVehicles {
abstract void brake();
}
interface MoneyFare {
void charge();
}
interface ControlTemperature {
void controlAirTemperature();
}
class Bus extends MotorVehicles implements MoneyFare {
void brake() {
System.out.println("公共汽车使用毂式刹车技术");
}
public void charge() {
System.out.println("公共汽车:一元/张,不计算公里数");
}
}
class Taxi extends MotorVehicles implements MoneyFare,ControlTemperature {
void brake() {
System.out.println("出租车使用盘式刹车技术");
}
public void charge() {
System.out.println("出租车:2元/公里,起价3公里");
}
public void controlAirTemperature() {
System.out.println("出租车安装了Hair空调");
}
}
class Cinema implements MoneyFare,ControlTemperature {
public void charge() {
System.out.println("电影院:门票,十元/张");
}
public void controlAirTemperature() {
System.out.println("电影院安装了中央空调");
}
}
public class Example{
public static void main(String args[]) {
Bus bus101 = new Bus();
Taxi buleTaxi = new Taxi();
Cinema redStarCinema = new Cinema();
MoneyFare fare;
ControlTemperature temperature;
fare = bus101;
bus101.brake();
fare.charge();
fare = buleTaxi;
temperature = buleTaxi;
buleTaxi.brake();
fare.charge();
temperature.controlAirTemperature();
fare = redStarCinema;
temperature = redStarCinema;
fare.charge();
temperature.controlAirTemperature();
}
}

5 接口与多态

可以通过在接口中声明若干个abstract方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可
以回调类实现的接口方法。

例子:接口与多态

interface CompurerAverage {
public double average(double a,double b);
}
class A implements CompurerAverage {
public double average(double a,double b) {
double aver=0;
aver=(a+b)/2;
return aver;
}
}
class B implements CompurerAverage {
public double average(double a,double b) {
double aver=0;
aver=Math.sqrt(a*b);
return aver;
}
}
public class Example {
public static void main(String args[]) {
CompurerAverage computer;
double a=11.23,b=22.78;
computer = new A();
double result = computer.average(a,b);
System.out.printf("%5.2f和%5.2f的算术平均值:%5.2f\n",a,b,result);
computer = new B();
result= computer.average(a,b);
System.out.printf("%5.2f和%5.2f的几何平均值:%5.2f",a,b,result);
}
}

【Java 接口与实现(详细版)】_编程语言_03

6 接口变量做参数

如果一个方法的参数是接口类型,我们就可以将任何实现该接口的类的实例的引用传递给该接口参数,那么接口参数就可以回调类实现的接口方法。

例子:接口参数

interface SpeakHello {
void speakHello();
}
class Chinese implements SpeakHello {
public void speakHello() {
System.out.println("中国人习惯问候语:你好,吃饭了吗? ");
}
}
class English implements SpeakHello {
public void speakHello() {
System.out.println("英国人习惯问候语:你好,天气不错 ");
}
}
class KindHello {
public void lookHello(SpeakHello hello) { //接口类型参数
hello.speakHello(); //接口回调
}
}
public class Example {
public static void main(String args[]) {
KindHello kindHello=new KindHello();
kindHello.lookHello(new Chinese());
kindHello.lookHello(new English());
}
}

【Java 接口与实现(详细版)】_抽象类_04

7 abstract类与接口的比较

1. abstract类 和接口都可以有abstract方法。
2.接口中只可以有常量,不能有变量;而abstract类中即可以有常量也可以有变量。
3. abstract类 中也可以有非abstract方法,接口不可以。(Java1.8之后不成立)

8 面向接口编程

面向接口去设计程序,可以通过在接口中声明若干个abstract方法,表明这些方法的重要性,方法体的内容细节由实现接口的类去完成。使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法。

【Java 接口与实现(详细版)】_接口_05