1.接口介绍
今天是你获取知识的一天。另一个有趣的新话题是接口。
接口的概念是抽象和多态性原则的产物。接口非常类似于抽象类,其中所有方法都是抽象的。它的声明方式与类相同,但我们使用关键字interface
。
interface Feline
{
void purr();
void meow();
void growl();
}
以下是有关接口的一些有用事实:
1. 声明一个接口
interface Drawable
{
void draw();
}
interface HasValue
{
int getValue();
}
class
我们写interface
.- 它只包含抽象方法(不要写关键字
abstract
) - 事实上,接口拥有所有的
public
方法
接口只能继承接口。但是一个接口可以有很多父母。另一种说法是,Java 具有接口的多重继承。例子:
interface Piece extends Drawable, HasValue
{
int getX();
int getY();
}
3. 从接口继承类
一个类可以继承多个接口(只能从一个类继承)。这是使用implements
关键字完成的。例子:
abstract class ChessItem implements Drawable, HasValue
{
private int x, y, value;
public int getValue()
{
return value;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
}
ChessItem 类被声明为抽象类:它实现了除draw
. 换句话说,该类ChessItem
包含一个抽象方法—— draw()
.
extends
和关键字的技术含义implements
是一样的:都是继承。进行区分是为了提高代码的可读性。我们还说类是继承的(通过extends
),接口是实现的(通过implements
)
4.变量
最重要的是:普通变量不能在接口中声明(尽管静态变量可以)。
但是为什么我们需要接口呢?它们什么时候使用?与类相比,接口有两个强大的优势:
2. 将“方法描述”与其实现分开。
前面我们说过,如果你想让你的类的方法可以被其他类调用,那么你的方法就需要标记关键字public
。如果您希望其中一些方法仅在您的类中调用,则需要用关键字标记它们private
。也就是说,我们把类的方法分为两类:“供大家使用”和“只供自己使用”。
接口有助于进一步加强这种划分。我们将创建一个特殊的“供所有人使用的类”以及“仅供我们自己使用”的第二个类,它将继承第一个类。大致如下所示:
前 | 后 |
---|---|
|
|
|
|
我们将我们的类分成两部分:一个接口和一个继承该接口的类。这里的优势是什么?
许多不同的类可以实现(继承)同一个接口。每个人都可以有自己的行为。例如,ArrayList
LinkedList
是接口的两种不同实现List
。
因此,我们不仅隐藏了各种实现,还隐藏了实现类本身(因为我们只需要代码中的接口)。这让我们变得非常灵活:就在程序运行时,我们可以用一个对象替换另一个对象,改变对象的行为而不影响使用它的所有类。
当与多态性结合时,这是一种非常强大的技术。目前,您应该这样做的原因还很不明确。您首先需要遇到包含数十个或数百个类的程序,以便理解接口可以使您的生活比没有它们要容易得多。
3.多重继承
在Java中,所有类只能有一个父类。在其他编程语言中,类通常可以有多个父类。这很方便,但也带来了很多问题。
Java 的创造者达成了妥协:他们禁止类的多重继承,但允许接口的多重继承。一个接口可以有多个父接口。 一个类可以有多个父接口,但只有一个父类。
为什么他们禁止类的多重继承而允许接口的多重继承?由于所谓的钻石继承问题:

B类继承A类时,对C、D类一无所知。所以它使用它认为合适的 A 类的变量。C 类做同样的事情:它使用 A 类的变量,但方式不同。而这一切,导致了D班的一场冲突。
让我们看看下面这个简单的例子。假设我们有 3 个类:
class Data
{
protected int value;
}
class XCoordinate extends Data
{
public void setX (int x) { value = x;}
public int getX () { return value;}
}
class YCoordinate extends Data
{
public void setY (int y) { value = y;}
public int getY () { return value; }
}
Data 类存储value
变量。它的 XCoordinate 后代类使用该变量来存储x
值,YCoordinate
后代类使用它来存储y
值。
它有效。分别地。但是如果我们希望 XYCoordinates 类同时继承XCoordinate
和YCoordinate
类,那么我们就会得到错误的代码。此类将具有其祖先类的方法,但它们无法正常工作,因为它们具有相同的value variable
.
但是因为接口不能有变量,所以不能有这种冲突。因此,允许接口的多重继承。
GO TO FULL VERSION