一、接口的定义与使用
格式:
(1)接口体中的抽象方法和常量
JDK8版本之前,接口体中只有抽象方法,访问权限一定都是public(允许省略public、abstract修饰符)。所有的static常量的访问权限一定都是public(允许省略public、final和static修饰符,接口中不会有变量)
(2)接口体中的default实例方法
从JDK8版本开始,允许使用default关键字,在接口体中定义称作default的实例方法(不可以定义default的static方法),default的实例方法和通常的普通的方法比就是用关键字default修饰的带方法体的实例方法。default实例方法的访问权限一定是public(允许省略public修饰符)。
(3)接口体中的static方法
从JDK8版本开始,允许在接口体中定义static方法。
一个类通过使用关键字 implements 声明自己实现一个或多个接口。如果实现多个接口,用逗号隔开接口名,如A类实现Printable和Addable接口:
class A implements Printable , Addable {
}
一个类实现了某个接口,那么这个类就自然拥有了接口中的常量,default方法(去掉了default关键字),该类也可以重写接口中的default方法(注意,重写时需要去掉default关键字)。如果一个非abstract类实现了某个接口,那么这个类必须重写该接口的所有abstract方法,即去掉abstract修饰给出方法体。
二、接口回调
可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法以及接口中的default方法
public class InterfaceTest {
public static void main(String[] args) {
ShowMessage sm = null; //声明接口变量
sm = new TV(); //接口变量中存放对象的引用
sm.show("长城牌电视机"); //接口回调
sm.f(); //接口回调
sm = new PC();
sm.show("惠普笔记本"); //接口回调
sm.f(); //接口回调
}
}
public interface ShowMessage {
public abstract void show(String s);
default void f(){
System.out.println("default方法");
}
}
public class TV implements ShowMessage{
@Override
public void show(String s) {
System.out.println(s);
}
//重写default方法
public void f(){
System.out.println("重写了default方法");
}
}
public class PC implements ShowMessage {
@Override
public void show(String s) {
System.out.println(s);
}
}
长城牌电视机
重写了default方法
惠普笔记本
default方法
三、理解接口
(1)接口可以抽象出重要的行为标准,该行为标准用抽象方法来表示。
(2)可以把实现接口的类的对象的引用赋值给接口变量,该接口变量可以调用被该类实现的接口方法,即体现该类根据接口里的行为标准给出的具体行为。
接口的思想在于它可以要求某些类有相同名称的方法,但方法的具体内容可以不同,即要求这些类实现接口,以保证这些类一定有接口中所声明的方法(即所谓的方法绑定)。接口在要求一些类有相同名称的方法的同时,并不强迫这些类具有相同的父类。
abstract class MotorVehicles{
abstract void brake();
}
interface MoneyFare{
void charge();
}
interface ControlTemperature{
void controlAirTemperature();
}
class Bus extends MotorVehicles implements MoneyFare{
@Override
public void charge() {
System.out.println("公共汽车:一元/一张,不计公里数。");
}
@Override
void brake() {
System.out.println("公共汽车刹车。");
}
}
class Taxi extends MotorVehicles implements MoneyFare,ControlTemperature{
@Override
public void charge() {
System.out.println("出租车刹车。");
}
@Override
void brake() {
System.out.println("出租车:两元/一张,起价3公里。");
}
@Override
public void controlAirTemperature() {
System.out.println("出租车安装了空调。");
}
}
class Cinema implements MoneyFare,ControlTemperature{
@Override
public void controlAirTemperature() {
System.out.println("电影院安装了空调。");
}
@Override
public void charge() {
System.out.println("电影院:门票,十元/张");
}
}
public class Motor {
public static void main(String[] args) {
Bus bus101 = new Bus();
Taxi blueTaxi = new Taxi();
Cinema cinema = new Cinema();
MoneyFare fare;
ControlTemperature temperature;
fare = bus101;
bus101.brake();
fare.charge();
fare = blueTaxi;
temperature = blueTaxi;
blueTaxi.brake();
fare.charge();
temperature.controlAirTemperature();
fare = cinema;
temperature = cinema;
fare.charge();
temperature.controlAirTemperature();
}
}
公共汽车刹车。
公共汽车:一元/一张,不计公里数。
出租车:两元/一张,起价3公里。
出租车刹车。
出租车安装了空调。
电影院:门票,十元/张
电影院安装了空调。
四、接口与多态
接口产生的多态就是指不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态
使用接口进行程序设计的核心思想是使用接口回调,即接口变量存放实现该接口的类的对象的引用,从而接口变量就可以回调类实现的接口方法
利用接口也可以体现程序设计的开-闭原则,即对扩展开放,对修改关闭。
public class Adver {
public static void main(String[] args) {
AdvertisementBoard board = new AdvertisementBoard();
board.setAdver(new PhilipsCorp());
board.show();
}
}
public interface Advertisement {
public void showAdvertisement();
public String getCorpName();
}
public class AdvertisementBoard {
Advertisement adver;
public void setAdver(Advertisement adver) {
this.adver = adver;
}
public void show(){
if(adver != null){
System.out.println("广告牌显示" + adver.getCorpName() + "公司的广告词:");
adver.showAdvertisement();
}else{
System.out.println("广告牌无广告。");
}
}
}
public class PhilipsCorp implements Advertisement {
@Override
public void showAdvertisement() {
System.out.println("只有最好的,只有更好。");
}
@Override
public String getCorpName() {
return "飞利浦";
}
}
广告牌显示飞利浦公司的广告词:
只有最好的,只有更好。
五、abstract与接口的比较
1.abstract类和接口都可以有abstract方法。
2.接口中只可以有常量,不能有变量;而abstract类中即可以有常量也可以有变量。
3. abstract类中也可以非abstract方法,但不可以有default实例方法。接口不可以有非abstract的方法(不是default方法,还带有方法体的方法),但可以有default实例方法。
在设计程序时应当根据具体的分析来确定是使用抽象类还是接口。abstract类除了提供重要的需要子类去实现的abstract方法外,也提供了子类可以继承的变量和非abstract方法。如果某个问题需要使用继承才能更好的解决,比如,子类除了需要实现父类的abstract方法,还需要从父类继承一些变量或继承一些重要的非abstract方法,就可以考虑用abstract类。如果某个问题不需要继承,只是需要若干个类给出某些重要的abstract方法的实现细节,就可以考虑使用接口。