Dawn's Blogs

分享技术 记录成长

0%

Java基础 (8) 接口和内部类

接口

为什么需要接口

一方面,有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java 不支持多重继承。有了接口,就可以得到多重继承的效果

另一方面,有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有 is-a 的关系,仅仅是具有相同的行为特征而已。如:鼠标、键盘、打印机等都支持 USB 连接。

接口就是规范,定义的是一组规则。继承实现的是是不是的逻辑,而接口定义的是能不能的逻辑。

注意点

接口是抽象方法常量定义的集合:

  • 接口中所有的成员变量默认都是 public static final 修饰的。
  • 接口中所有抽象方法默认都是 public abstract 修饰的。
  • 接口中没有构造器
  • 接口与接口之间可以多继承。
  • 与继承关系类似,接口与实现类之间存在多态性
1
2
3
class SubClass extends SuperClass implements InterfaceA, InterfaceB{

}

JDK 7.0 及以前,接口中只能定义常量和抽象方法。

JDK 8.0 开始,接口中除了定义常量和抽象方法之外,还可以定义静态方法默认方法

  • 接口中定义的静态方法只能通过接口来调用
  • 通过实现接口的对象,可以调用接口的默认方法。
  • 如果子类继承的父类和实现的接口中,定义了同名同参数的(默认)方法,在没有重写的情况下,默认调用父类中的方法(类优先原则)。
  • 在实现类中调用被重写的默认方法:
1
2
InterfaceA.super.method();
InterfaceB.super.method();

接口的多态性

接口的多态性体现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Computer {
public void work(USB usb) { // 多态的体现
usb.start();
// ...
usb.stop();
}
}

// USB 接口,定义了两个函数
interface USB {
void start();

void stop();
}

// 鼠标实现了 USB 接口
class Mouse implements USB {
public void start() {
// ...
}

public void stop() {
// ...
}
}

// 打印机实现了 USB 接口
class Printer implements USB {
public void start() {
// ...
}

public void stop() {
// ...
}
}

接口应用 - 代理设计模式

代理设计就是为其他对象提供一种代理以控制对这个对象的访问

分为:

  • 静态代理:静态定义代理类。
  • 动态代理:动态生成代理类。

静态代理

静态代理中包括代理类和被代理类。

  • 被代理类用于实现核心功能。
  • 代理类用于实现,控制被代理类的访问。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interface Network {
public void browse();
}

// 被代理类
class RealServer implements Network {
@Override
public void browse() {
System.out.println("真实服务器上网浏览信息");
}
}

// 代理类
class ProxyServer implements Network {
private Network network;

public ProxyServer(Network network) {
this.network = network;
}

public void check() {
System.out.println("检查网络连接等操作");
}

public void browse() {
check();
network.browse();
}
}

接口应用 - 工厂设计模式

工厂模式:实现了创建者与调用者的分离,将创建对象的具体过程屏蔽起来,达到高灵活性的目的。

工厂模式的分类:

  • 简单工厂模式。
  • 工厂方法模式。
  • 抽象工厂模式。

简单工厂模式

简单工厂模式定义一个用于创建对象的工厂类

调用者只要知道他要什么,从哪里拿、如何创建不需要知道。

缺点:对于增加新产品,不修改代码的话,是无法扩展的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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 static Car getAudi() {
// return new Audi();
// }
//
// public static Car getByd() {
// return new BYD();
// }
}

工厂方法模式

工厂方法模式有一组实现了相同接口的工厂类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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();
}
}

接口与抽象类的对比

image-20230127223619924

内部类

在 Java 中,允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。