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.

但是因為接口不能有變量,所以不能有這種衝突。因此,允許接口的多重繼承。