1.接口介绍

今天是你获取知识的一天。另一个有趣的新话题是接口。

接口的概念是抽象和多态性原则的产物。接口非常类似于抽象类,其中所有方法都是抽象的。它的声明方式与类相同,但我们使用关键字interface

interface Feline
{
   void purr();
   void meow();
   void growl();
}

以下是有关接口的一些有用事实:

1. 声明一个接口

interface Drawable
{
   void draw();
}

interface HasValue
{
   int getValue();
}
  1. class我们写interface.
  2. 它只包含抽象方法(不要写关键字abstract
  3. 事实上,接口拥有所有的public方法
2.接口继承

接口只能继承接口。但是一个接口可以有很多父母。另一种说法是,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。也就是说,我们把类的方法分为两类:“供大家使用”和“只供自己使用”。

接口有助于进一步加强这种划分。我们将创建一个特殊的“供所有人使用的类”以及“仅供我们自己使用”的第二个类,它将继承第一个类。大致如下所示:

class Student
{
   private String name;
   public Student(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return this.name;
   }

   private void setName(String name)
   {
      this.name = name;
   }
interface Student
{
   public String getName();
}

class StudentImpl implements Student
{
   private String name;
   public StudentImpl(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return this.name;
   }

   private void setName(String name)
   {
      this.name = name;
   }
}
public static void main(String[] args)
{
   Student student = new Student("Alibaba");
   System.out.println(student.getName());
}
public static void main(String[] args)
{
   Student student = new StudentImpl("Ali")
   System.out.println(student.getName());
}

我们将我们的类分成两部分:一个接口和一个继承接口。这里的优势是什么?

许多不同的类可以实现(继承)同一个接口。每个人都可以有自己的行为。例如,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 类同时继承XCoordinateYCoordinate类,那么我们就会得到错误的代码。此类将具有其祖先类的方法,但它们无法正常工作,因为它们具有相同的value variable.

但是因为接口不能有变量,所以不能有这种冲突。因此,允许接口的多重继承。