Java抽象类与接口全解析
立即解锁
发布时间: 2025-08-18 00:27:49 阅读量: 21 订阅数: 36 


Java编程入门与实战指南
# Java 抽象类与接口全解析
## 1. 抽象类要点
抽象类在 Java 编程中有着独特的地位,以下是关于抽象类的一些要点:
- **方法实现**:抽象类中的方法不一定要全部是抽象方法,类可以为部分方法提供实现,而其他方法保持抽象。甚至,即使一个类没有任何抽象方法,也可以将其声明为抽象类,不过这样的类不能被实例化。
- **私有方法限制**:私有方法不能是抽象的,因为子类无法重写私有方法,而抽象方法必须被重写。
- **变量声明**:虽然不能创建抽象类的实例,但可以使用抽象类作为类型来声明变量,该变量可以引用抽象类的任何子类的实例。
- **抽象与 final 冲突**:一个类不能同时被指定为抽象和 final。因为抽象类需要被继承才能使用,而 final 类不能被继承,所以同时指定这两个修饰符没有意义。
抽象类在 Java API 中被广泛使用,许多抽象类的名称以 “Abstract” 开头,如 AbstractBorder、AbstractCollection 和 AbstractMap,但也有很多抽象类并非如此,例如 System.in 使用的 InputStream 类就是抽象的。
## 2. 接口概述
接口类似于抽象类,但有一些关键区别。接口只能包含抽象方法和 final 字段(常量),并且不能作为基类。类通过为接口声明的每个方法提供代码来实现接口。
接口相对于继承有两个优势:
- **易于使用**:接口比抽象类更容易处理,因为在接口中无需担心提供任何实现细节。
- **多实现能力**:一个类只能继承一个其他类,但可以实现任意数量的接口。
## 3. 创建基本接口
下面是一个定义单个方法的基本接口示例:
```java
public interface Playable
{
void play();
}
```
这个接口声明了任何实现 Playable 接口的类都必须为名为 play 的方法提供实现,该方法不接受参数且不返回值。
这个接口有一些有趣的细节:
- **公共访问**:接口本身被声明为 public,以便其他类可以使用。与公共类一样,公共接口必须在同名文件中声明,因此这个接口必须在名为 Playable.java 的文件中。
- **命名规范**:接口的名称(Playable)是一个形容词。大多数接口使用形容词而不是名词命名,因为它们描述了实现该接口的类的额外能力或特性。例如,实现 Playable 接口的类代表可以被播放的对象。许多动词可以通过在末尾添加 -able 转换为形容词,这种类型的形容词常用于接口命名。
- **组合命名**:另一种常见的接口命名方式是将形容词与名词组合,以表明接口为特定类型的对象添加了某种能力。例如,可以将提供纸牌游戏特有方法的接口命名为 CardGame,该接口可能包含 deal、shuffle 和 getHand 等方法。
- **方法默认修饰符**:接口中的所有方法都被假定为 public 和 abstract。虽然可以在接口方法上显式编写 public 和 abstract 关键字,但这种编码方式被认为是不好的,因为这可能表明你认为默认修饰符是 private 而不是 abstract。
## 4. 实现接口
要实现一个接口,类必须完成两件事:
- 在类声明中指定 implements 子句。
- 为接口声明的每个方法提供实现。
以下是一个实现 Playable 接口的类的示例:
```java
public class TicTacToe implements Playable
{
// additional fields and methods go here
public void play()
{
// code that plays the game goes here
}
// additional fields and methods go here
}
```
在这个示例中,TicTacToe 类的声明指定了 implements Playable,然后类的主体包含了 play 方法的实现。
一个类可以实现多个接口,例如:
```java
public class Hearts implements Playable, CardGame
{
// must implement methods of the Playable
// and CardGame interfaces
}
```
Hearts 类实现了两个接口:Playable 和 CardGame。
一个类还可以继承一个超类并实现一个或多个接口,例如:
```java
public class Poker extends Game
implements Playable, CardGame
{
// inherits all members of the Game class
// must implement methods of the Playable
// and CardGame interfaces
}
```
## 5. 使用接口作为类型
在 Java 中,接口是一种类型,就像类一样。因此,可以使用接口作为变量、参数或方法返回值的类型。
考虑以下代码片段:
```java
Playable game = getGame();
game.play();
```
这里假设 getGame 方法返回一个实现了 Playable 接口的对象。在第一条语句中,该对象被赋值给一个 Playable 类型的变量,然后第二条语句调用该对象的 play 方法。
另一个(稍微复杂一些)的示例是,假设有一个名为 Dealable 的接口,定义了一个名为 deal 的方法,该方法接受要发的牌数作为参数:
```java
public interface Dealable
{
void deal(int cards);
}
```
现在假设有一个名为 startGame 的方法,接受两个参数:一个 Dealable 对象和一个表示要玩的游戏的 String。该方法可能如下所示:
```java
private void startGame(Dealable deck, String game)
{
if (game.equals("Poker"))
deck.deal(5);
else if (game.equals("Hearts"))
deck.deal(13);
else if (game.equals("Gin"))
deck.deal(10);
}
```
假设还有一个名为 CardDeck 的类实现了 Dealable 接口,可以使用以下语句来开始一场 Hearts 游戏:
```java
Dealable d = new CardDeck();
startGame(d, "Hearts");
```
注意,变量 d 被声明为 Dealable 类型,也可以将其声明为 CardDeck 类型:
```java
CardDeck d = new CardDeck();
startGame(d, "Hearts");
```
因为 CardDeck 类实现了 Dealable 接口,所以它可以作为参数传递给 startGame 方法。
## 6. 接口的更多用途
### 6.1 添加字段到接口
除了抽象方法,接口还可以包含 final 字段,即常量。接口字段用于提供与接口相关的常量值。例如:
```java
public interface GolfClub
{
int DRIVER = 1;
int SPOON = 2;
int NIBLICK = 3;
int MASHIE = 4;
}
```
任何实现 GolfClub 接口的类都可以使用这四个字段(即常量)。
需要注意的是,接口字段自动被假
0
0
复制全文
相关推荐









