一、接口(interface)
1.1 接口的声明
接口interface关键字。与class,enum是同级。
public interface 接口名{
}
1.2 接口中的内容
JDK1.8之前
接口中只能写二种内容:
1 public static final int I; //公有静态常量。
2 public abstract void dis(); //公有抽象方法。
JDK1.8之后
接口中又多了两种内容:
1 公有静态方法
2 公有实现方法(实例方法)(有方法体可以直接使用的方法)
static void print(){
System.out.println("公有静态方法!");
}
default void info(){
System.out.println("公有实例方法!");
}
1.3 接口的使用
接口中有抽象方法,所以接口本身不能被实例化。
接口的使用需要与类配合。与接口配合一起使用的类,我们叫实现类。
需要使用实现类。实现接口中的所有抽象方法。
实现的关键字:implements
public class 实现类 extends 父类 implements 接口列表{
方法重写(){ }
}
1实现类可以在继承一个父类的同时,实现接口。
2 使用implements 关键字实现接口。
3 Java只支持单继承,但是可以支持多实现。
public class Impl01 implements Inter01,Inter02{
}4 实现类应该实现接口中所有抽象方法。
public class Impl01 implements Inter01{
@Override
public void dis() {
System.out.println("实现类Impl01给出的方法实现!");
}
}
1.4 接口与实现类之间也支持多态
类的多态:
父类 引用 = new 子类( );
接口的多态:
接口 引用 = new 实现类( );
接口的引用打点可以调用实现类的重写方法。
public class Test {
public static void main(String[] args) {
Inter01 inter01 = new Impl01();
inter01.dis();
inter01.info();
}
}
二、 软件工程 — 接口
2.1 接口是怎么来的
接口也是抽象和封装的结果
类是对大量对象的抽象和封装
父类是对大量子类的抽象和封装
方法是对实现某一功能的代码的抽象和封装。单一职责。一个方法只做一个事。
接口是对方法的抽象和封装
2.2 接口是什么
接口是表示了一种行为。一种能力。
例如:拍照接口。计算工资接口
一个类实现了一个接口。一般表示 这个类具备了某种能力。
鸟有飞行的行为。一切飞行的动作就是一个飞行接口。
interface 飞行接口{
飞行();
}
所有实现这个飞行接口的类。都具备了飞行的能力。
红鸟 extends 鸟类 implements 飞行接口{
飞行(){“正常飞!”}
}
飞机 implements 飞行接口{
飞行(){“发动机!”}
}
超人 implements 飞行接口{
飞行(){“外穿!”}
}
红鸟,飞机,超人,找不到一个合适的父类。
但是这三个类有相同的行为。相同的能力。
现在如果再来编写弹弓类。我们只需要一个能飞的事物。
2.3 案例:用接口修改“愤怒的小鸟”
接口是一种能力。接口也是针对方法的抽象
在愤怒的小鸟案例中,我们知道每一种鸟都有飞行的行为
(1) 编写飞行接口
/**
* 这是一个飞行接口
*/
public interface Fly {
/**
* 飞行的方法
*/
void fly();
}
(2) 修改鸟类去实现飞行接口
public abstract class Bird implements Fly {
private String name;
private String color;
public Bird() {
}
public Bird(String name, String color) {
this.name = name;
this.color = color;
}
}
(3) 修改弹弓类。针对接口编程
public class Slingshot {
/**
* 针对父类做编程
* @param bird 鸟类
*/
public void shot(Bird bird){
bird.fly();
}
/**
* 针对接口编程的方法
* @param fly 飞行接口。表示了具有飞行能力的所有对象
*/
public void shot(Fly fly){
fly.fly();
}
}
2.4 案例:超市有不同的打折方法
要注意在创建实现方法时创建一个接口实现包,这样逻辑结构更清晰。
(1) 编写打折接口
超市有很多种打折方式(Discount):
public interface Discount{
double discount(double sumprice);
}
/**
* 打折行为接口
*/
public interface Discount {
/**
* 打折方法
* @param sumprice 总价
* @return 打折之后的价格
*/
double discount(double sumprice);
}
(2) 编写不同的打折实现方式
1 不打折(NonDiscount)
总价的多少,应付价格就是多少。
/**
* 不打折方式的实现类
*/
public class NonDiscount implements Discount {
@Override
public double discount(double sumprice) {
return sumprice;
}
}
2 折扣率(BuckDiscount)
总价折扣率(buckling)计算应付的价格。
public class BuckDiacount implements Discount{
private double buckling;
public double discount(double sumprice){ }
}
public class BuckDiscount implements Discount {
private double buckling;
public BuckDiscount() {
}
public BuckDiscount(double buckling) {
this.buckling = buckling;
}
@Override
public double discount(double sumprice) {
return sumprice*this.buckling;
}
}
3 返现(CashbackDiscount)
总价按每满(satisfy)多少返(back)多少的方式计算应付价格。
public class CashbackDiscount implements Discount{
private double satisfy;
private double back;
public double discount(double sumprice){ }
}
public class CashbackDiscount implements Discount {
private double satisfy;
private double back;
public CashbackDiscount() {
}
public CashbackDiscount(double satisfy, double back) {
this.satisfy = satisfy;
this.back = back;
}
public double discount(double sumprice){
return sumprice - (((int)(sumprice/satisfy))*back);
}
}
(3) 编写测试类
测试接口与实现类的功能。
(4) 打折接口与三个实现类的功能
UML中的类图。
最上面的是接口。
下面三个是这个接口的实现类。
实现类与接口之间使用一个 空心箭头虚线 表示。
(5) 编写收银员(Cashier)。
收银员的结算(settle)行为中可以使用不同的打折方式。
我们以“有一个”的关系来组织 收银员 与 打折方式。
收银员有一个打折方式
public class Cashier {
//有一个打折行为
private Discount dis;
public Cashier() {
}
public Cashier(Discount dis) {
this.dis = dis;
}
public void settle(double sumprice){
System.out.println(dis.discount(sumprice));
}
}
UML中如何表示有一个(组合)关系。
收银员这类。可以在多种 打折方式接口 的实现类 之间任意选择。
(6) 编写收银员的测试类
public class CashierTest {
public static void main(String[] args) {
double sum = 1000;
NonDiscount discount = new NonDiscount();
BuckDiscount buckDiscount = new BuckDiscount();
buckDiscount.setBuckling(0.9);
CashbackDiscount cashbackDiscount = new CashbackDiscount(100,35);
Cashier cashier = new Cashier();
cashier.setDis(discount);
cashier.settle(sum);
cashier.setDis(buckDiscount);
cashier.settle(sum);
cashier.setDis(cashbackDiscount);
cashier.settle(sum);
}
}