甲乙小朋友的房子

甲乙小朋友很笨,但甲乙小朋友不会放弃

0%

Java-abstract和interface

首先我们看一下抽象类abstract。它是普通类与接口之间的一种中庸之道。然后我们介绍一下接口。

抽象类和抽象方法

Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
====================================================================
继承关系:
abstract Instrument
↳ Wind
====================================================================
import static net.minview.util.Print.*;
/**乐器抽象类**/
abstract class Instrument{
private int i ;
// 抽象方法
public abstract void play(Note n);
public String what(){return "Instrument";}
}
/**某个乐器的具体类**/
class Wind extends Instrument{
public void play{Note n}{
print("Wind.play()" + n);
}
public String what(){return "Wind";}
}
  • 抽象类不能有对象
  • 如果一个类包含抽象方法,则该类必须被限定为抽象的
  • 抽象类的子类必须定义所有抽象方法

接口

接口并不是一个类,而是一个极度抽象的类。要让一个类成为一个接口的“子类”,必须用implements关键字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
====================================================================
关系:
interface Instrument
implementsWind
extendsWoodwind
====================================================================
/**乐器抽象接口**/
interface Instrument{
int i = 5 ; // static & final
// 接口方法
public abstract void play(Note n); // 不可以有任何实现
}
/**某个乐器的具体类**/
class Wind implements Instrument{
public void play{Note n}{
print("Wind.play()" + n);
}
public String what(){return "Wind";}
}
/**一个正常的类**/
class Woodwind extends Wind{

}

Queue接口

Java集合类库将接口和实现进行了分离。以队列(Queue)为例。一个队列接口如下所示:

1
2
3
4
5
6
7
8
9
interface Queue<E>{
void add(E element);
E remove();
int size();
}

| 1 | 2 | 3 | 4 |
↑ ↑
队头 队尾

这个接口并没有说明队列是如何实现的。队列实现有两种方式:循环数组、链表。

循环数组实现:

1
2
3
4
5
6
7
8
9
class CircularArrayQueue<E> implements Queue<E>{
CircularArrayQueue(int capacity){...}
public void add(E element){...}
public E remove(){...}
public int size(){...}
private E[] elements;
private int head;
private tail;
}

链表实现:

1
2
3
4
5
6
7
8
9
class LinkedListQueue<E> implements Queue<E>{
LinkedListQueue(){...}
public void add(E element){...}
public E reove(){...}
public int size(){...}

private Link head;
private Link tail;
}

完全解耦

为了解释接口的解耦功能,我们先引入一个例子:

程序员甲写了一个Node1,并且写了一个两个Node1的排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Node1{
int val;
int count;
public int CompareTo(Node1 o){
return this.val - o.val;
}
}
public static Node1[] sort(Node1 a,Node1 b){
if( a.CompareTo(b) > 0 ){
return new Node1[]{a,b};
}else{
return new Node1[]{b,a};
}
}
public static void main(String[] args){
Node1 a = new Node1();//此处省略
Node1 b = new Node1();
sort(a,b);
}

程序员乙写了一个Node2,也写了一个两个Node2的排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Node2{
String key;
int val;
public int CompareTo(Node2 o){
return this.val - o.val;
}
}
public static Node2[] sort(Node2 a,Node2 b){
if( a.CompareTo(b) > 0 ){
return new Node2[]{a,b};
}else{
return new Node2[]{b,a};
}
}
public static void main(String[] args){
Node2 a = new Node2();//此处省略
Node2 b = new Node2();
sort(a,b);
}

但是由于Node1和Node2不是继承自同一个基类,因此代码不能通用。我们通过接口的方式来改进:

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
interface Comparable{
int CompareTo(Object o){}
}
class Node1 implements Compareble{
int val;
int count;
@Override
public int CompareTo(Node1 o){
return this.val - o.val;
}
}
class Node2 implements Comparable{
String key;
int val;
@Override
public int CompareTo(Node2 o){
return this.val - o.val;
}
}
//接下来我们利用多态提供通用的sort方法(这个东西类似于Array.sort())
public static Compareble[] sort(Comparable a,Comparable b){
return a.CompareTo(b);
}
public static void main(String[] args){
//Node1
Node1 a = new Node1();
Node1 b = new Node1();
sort(a,b);

//Node2
Node2 c = new Node2();
Node2 d = new Node2();
sort(c,d);
}

这样一来,只要继承自Comparable接口的类,都可以使用sort()方法了!