接口
使用interface关键字来定义接口
如何定义接口?需要定义接口的成员
JDK7之前,只能定义全局常量和抽象方法
全局常量:public static final(但是书写时可以省略不写)
抽象方法:public abstract(但是书写时可以省略不写)
JDK8 除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。
接口中不能定义构造器,意味着接口无法被实例化。Java开发中,接口通过让类去实现(implements)的方式来使用。
package com.jinyang.interfacetest;
import org.junit.Test;
public class InterfaceTest {
@Test
public void test(){
System.out.println(Flyable.MAX_SPEED);
Plane pl = new Plane();
pl.stop();
}
}
interface Flyable{
//全局常量 public static final可省略不写
public static final int MAX_SPEED = 7777;
int MIN_SPEED = 0;
//抽象方法 public abstract可省略不写
void stop();
}
class Plane implements Flyable{
@Override
public void stop() {
System.out.println("\033[1;94mPlane Stop\033[0m");
}
}
Java类可以实现多个接口–>弥补了Java单继承性的局限性
class SubClass extends SuperClass implements InterfaceA{ }
interface Attackable{
void force();
}
interface Flyable{
//全局常量 public static final可省略不写
public static final int MAX_SPEED = 7777;
int MIN_SPEED = 0;
//抽象方法 public abstract可省略不写
void stop();
}
class Bullet extends Object implements Flyable,Attackable{
@Override
public void force() {
}
@Override
public void stop() {
}
}
接口与接口之间是可以继承的,并且接口是可以实现多继承的
interface CC extends Attackable,Flyable
{
...
}
接口的多态体现
package com.atguigu.java;
interface USB{ //
public void start() ;
public void stop() ;
}
class Computer{
public static void show(USB usb){
usb.start() ;
System.out.println("=========== USB 设备工作 ========") ;
usb.stop() ;
}
};
class Flash implements USB{
public void start(){ // 重写方法
System.out.println("U盘开始工作。") ;
}
public void stop(){ // 重写方法
System.out.println("U盘停止工作。") ;
}
};
class Print implements USB{
public void start(){ // 重写方法
System.out.println("打印机开始工作。") ;
}
public void stop(){ // 重写方法
System.out.println("打印机停止工作。") ;
}
};
public class InterfaceDemo{
public static void main(String args[]){
Computer.show(new Flash()) ;
Computer.show(new Print()) ;
c.show(new USB(){
public void start(){
System.out.println("移动硬盘开始运行");
}
public void stop(){
System.out.println("移动硬盘停止运行");
}
});
}
};
接口的应用:代理模式
//案例:经纪人和明星
package com.atguigu.java;
public class StaticProxyTest {
public static void main(String[] args) {
Star s = new Proxy(new RealStar());
s.confer();
s.signContract();
s.bookTicket();
s.sing();
s.collectMoney();
}
}
interface Star {
void confer();// 面谈
void signContract();// 签合同
void bookTicket();// 订票
void sing();// 唱歌
void collectMoney();// 收钱
}
class RealStar implements Star {
public void confer() {
}
public void signContract() {
}
public void bookTicket() {
}
public void sing() {
System.out.println("明星:歌唱~~~");
}
public void collectMoney() {
}
}
class Proxy implements Star {
private Star real;
public Proxy(Star real) {
this.real = real;
}
public void confer() {
System.out.println("经纪人面谈");
}
public void signContract() {
System.out.println("经纪人签合同");
}
public void bookTicket() {
System.out.println("经纪人订票");
}
public void sing() {
real.sing();
}
public void collectMoney() {
System.out.println("经纪人收钱");
}
}
接口的应用:工厂模式
工厂模式: 实现了创建者与调用者的分离, 即将创建对象的具体过程屏蔽隔离
起来,达到提高灵活性的目的。
其实设计模式和面向对象设计原则都是为了使得开发项目更加容易扩展和维
护,解决方式就是一个“分工”。
社会的发展也是这样,分工越来越细。
原始社会的人:人什么都要会,自己种,自己打猎,自己织衣服,自己治病
现在的人:可以只会一样,其他都不会,只会 Java 也能活,不会做饭,不会开
车,不会…
- 简单工厂模式: 用来生产同一等级结构中的任意产品。(对于增加新的产品,
需要修改已有代码) - 工厂方法模式: 用来生产同一等级结构中的固定产品。(支持增加任意产品)
- 抽象工厂模式: 用来生产不同产品族的全部产品。(对于增加新的产品,无
能为力;支持增加产品族)
//无工厂模式
package com.atguigu.pattern.factory.nofactory;
interface Car{
void run();
}
class Audi implements Car{
public void run() {
System.out.println("奥迪在跑");
}
}
class BYD implements Car{
public void run() {
System.out.println("比亚迪在跑");
}
}
public class Client01 {
public static void main(String[] args) {
Car a = new Audi();
Car b = new BYD();
a.run();
b.run();
}
}
//简单工厂模式
package com.atguigu.pattern.factory.simple;
interface Car {
void run();
}
class Audi implements Car {
public void run() {
System.out.println("奥迪在跑");
}
}
class BYD implements Car {
public void run() {
System.out.println("比亚迪在跑");
}
}
//工厂类
class CarFactory {
//方式一
public static Car getCar(String type) {
if ("奥迪".equals(type)) {
return new Audi();
} else if ("比亚迪".equals(type)) {
return new BYD();
} else {
return null;
}
}
}
public class Client02 {
public static void main(String[] args) {
Car a = CarFactory.getCar("奥迪");
a.run();
Car b = CarFactory.getCar("比亚迪");
b.run();
}
}
//工厂方法模式
package com.atguigu.pattern.factory.method;
interface Car{
void run();
}
class Audi implements Car{
public void run() {
System.out.println("奥迪在跑");
}
}
class BYD implements Car{
public void run() {
System.out.println("比亚迪在跑");
}
}
//工厂接口
interface Factory{
Car getCar();
}
//两个工厂类
class AudiFactory implements Factory{
public Audi getCar(){
return new Audi();
}
}
class BydFactory implements Factory{
public BYD getCar(){
return new BYD();
}
}
public class Client {
public static void main(String[] args) {
Car a = new AudiFactory().getCar();
Car b = new BydFactory().getCar();
a.run();
b.run();
}
}
补充内容
JDK8中关于接口的新特性,如下所示。(可以看到,interface越来越像类了)
接口中的方法权限是public的,并且public是可以忽略的。可以定义默认方法default,可以定义静态方法static
注意:
- 接口中定义的静态方法只能通过接口调用,对于类是不可见的。
- 通过实现类的对象可以调用接口中的默认方法。
- 实现类可以重写接口中的默认方法,调用时调用的是重写后的默认方法。如果不重写则调用接口中的默认方法。
- 如果子类(或实现类)继承的父类和实现的接口中都声明了同名同参数的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。
- 如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下就报错。—>报错原因:接口冲突
//InterfaceTestJDK8
public class InterfaceClass {
public static void main(String[] args) {
InterfaceTestJDK8.method();//可以通过接口直接调用静态方法
//通过实现类的对象可以调用接口中的默认方法。
SubClass s1 = new SubClass();
//s1.method(); //method() 是接口中定义的静态方法
s1.method2();
}
}
//InterfaceClass.java
public class InterfaceClass {
public static void main(String[] args) {
SubClass s1 = new SubClass();
//s1.method(); //method() 是接口中定义的静态方法
}
}
//这里可以看到无需进行接口中方法的重写了
//实现类可以重写接口中的默认方法,调用时调用的是重写后的默认方法。如果不重写则调用接口中的默认方法。
class SubClass implements InterfaceTestJDK8
{
public void method2(){
System.out.println("Override method2");
}
}
内部类
局部内部类的实例化
public class InnerClassTest {
//创建Dog实例 静态的成员内部类
MyPerson.Dog dog = new MyPerson.Dog();
//创建Brid实例 非静态的成员内部类
MyPerson p1 = new MyPerson();
MyPerson.Brid brid = p1.new Brid();
}
class MyPerson{
static class Dog{
}
class Brid{
}
}
该博客图片来源于尚硅谷宋老师教学课件