CodeGym /Java Blog /Toto sisi /Java中的繼承
John Squirrels
等級 41
San Francisco

Java中的繼承

在 Toto sisi 群組發布
Java 是一種物件導向的語言。這意味著 Java 中的一切都由類別及其物件組成,並遵循 OOP(物件導向程式設計)的範式。其中一個範例是繼承,這是 Java 中的一種機制,透過該機制允許一個類別繼承另一個類別的功能(欄位和方法)。簡單來說,在Java中,繼承就是在現有類別的基礎上建立新的類別。 Java 中的繼承 - 1

Java 繼承的關鍵角色

  • 繼承是這樣的概念:一個類別可以部分或完全重複其父類別(它所繼承的類別)的屬性和方法。
  • 子類別、子類別、擴充類別或衍生類別是從另一個類別繼承的類別。
  • 父類、超類或基底類是具有許多函數的類,而這些函數可以被另一個類(子類)傳遞(繼承)。
  • 方法重寫正在更改衍生類別方法的行為。這通常是更具體、更精緻的行為。如果您重寫繼承者中父類別中已有的方法,它會取代父類別方法。
  • 一個類別只能有一個祖先類,但每個類別可以有很多「孩子」。

怎麼運作的

繼承鏈從最抽象的類別指向更具體的類別。也就是說,超類別是類別鏈中最抽象的。通常它被表示為抽象(不需要實現的基底類別)。所有進一步的課程都更加具體。例如,有一個名為“Gadget”的類別。它可以具有現場(或狀態)“重量”現場電池容量、現場充電水平以及“工作”和充電的方法(或行為)。在這種情況下,方法可以是抽象的,即它們沒有具體的實現。雖然我們不能說它是什麼類型的小工具,但它絕對是任何可充電的小工具。讓我們建立 Gadget 類別的 Phone 子類別。它不再需要重新定義重量和電池,它只是從抽像小工具繼承它們。但工作的行為需要澄清。您也可以新增其他欄位「螢幕對角線」、連接器等。您可以新增方法「更新作業系統」。接下來,我們可以再創建兩個類,它們都將從 Phone、Android 和 iPhone 繼承。這兩個類別都繼承了 Gadget 和 Smartphone 的所有欄位和方法,並且這些方法可以被重寫。第一類需要「品牌名稱」字段,而 iPhone 不需要該字段,因為只有一家公司生產此類智慧型手機。
class Gadget {}
}
//subclass of Gadget class
class Phone extends Gadget {}
//subclass of Phone class
class IPhone extends Phone {}
//subclass of Phone class
class AndroidPhone extends Phone {}
子類別繼承父類別的所有公共成員和受保護成員。子類別位於哪個套件中並不重要。如果子類別與父類別位於同一套件中,則它也會繼承父類別的套件私有成員。您可以按原樣使用繼承的成員、替換它們、隱藏它們或新增成員:
  • 您可以像任何其他欄位一樣直接使用繼承欄位。
  • 您可以在子類別中宣告一個與父類別中同名的欄位。它隱藏了它(所以最好不要這樣做)。
  • 您可以在子類別中聲明新欄位(父類別沒有的欄位)。
  • 繼承的方法可以直接使用,無需在衍生類別中重寫。
  • 您也可以在子類別中編寫一個與父類別中的方法具有相同簽章的新實例方法。此過程將覆蓋它。
  • 您可以在子類別中聲明父類別中未聲明的新方法。
  • 您可以編寫一個子類別建構函數,該子類別建構函數隱式或使用 super 關鍵字呼叫超類別建構函數。

例子

讓我們建立一個包含權重和商標欄位以及work()方法的 MusicalInstrument 基底類別。我們也定義了一個建構函數。
public class MusicalInstrument {
   int weight;
   String tradeMark;

   public MusicalInstrument(int weight, String tradeMark) {
       this.weight = weight;
       this.tradeMark = tradeMark;
   }

   public void work() {
       System.out.println("the instrument is playing...");
   }
}
完全不清楚它是什麼類型的樂器以及如何演奏它。讓我們創造一種更具體的樂器:小提琴。它將具有與樂器中相同的字段(它們將在構造函數中使用 super 關鍵字呼叫。我們還可以重寫工作方法並創建一個用於按字串設定小提琴弦的方法。
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

   @Override
   public void work() {
       System.out.println("THe violin's playing");

   }

   public void violinTuning () {
     System.out.println("I'm tuning 1st string...");
     System.out.println("I'm tuning 2nd string...");
     System.out.println("I'm tuning 3rd string...");
     System.out.println("I'm tuning 4th string...");
}


}
讓我們建立一個Demo類別來測試Violin類別並看看繼承是如何運作的。
public class InheritDemo {

   public static void main(String[] args) {

       Violin violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       violin.violinTuning();
       violin.work();
   }
}
在這種情況下,程式的輸出將如下:
我正在調第一弦...我正在調第二弦...我正在調第三弦...我正在調第四弦...小提琴在演奏
也就是說,如果子類別中存在重寫的方法,那麼將不再呼叫祖先方法。如果它不存在怎麼辦?也就是說,Violin 類別如下圖所示:
public class Violin extends MusicalInstrument {
   String master;
   String owner;
   int age;
   boolean isTuned;

   public Violin(int weight, String tradeMark, String master, String owner, int age, boolean isTuned) {
       super(weight, tradeMark);
       this.master = master;
       this.owner = owner;
       this.age = age;
       this.isTuned = isTuned;
   }

  // @Override


 //  }

   public void violinTuning () {
       System.out.println("I'm tuning 1st string...");
       System.out.println("I'm tuning 2nd string...");
       System.out.println("I'm tuning 3rd string...");
       System.out.println("I'm tuning 4th string...");
   }

}
輸出是:
我正在調第一弦...我正在調第二弦...我正在調第三弦...我正在調第四弦...樂器正在演奏...
即會自動呼叫祖先方法。順便說一句,子類別可以透過祖先來定義,也就是進行向轉型:
Parent parent = new Child()
此初始化用於僅存取父類別中存在的成員和重寫的方法。在我們的例子中它將是:
public class InheritDemo {

   public static void main(String[] args) {

       MusicalInstrument violin = new Violin(1, null, "Amati", "Kremer", 285, false);
       //violin.violinTuning();
       violin.work();
   }
}
在這種情況下,我們無法配置小提琴方法。但同時,子孫類別的 work()方法將會被呼叫(如果存在)。

Java 平台類別層次結構

在Java中,一切都是由類別組成的,並且它們從屬於一個層次結構。問題出現了:是否有一個類別可以繼承所有其他類別?答案是肯定的,確實存在這樣一個類別。它被簡單地稱為Object。java.lang 套件中的Object類別定義並實作所有類別(包括您建立的類別)通用的行為在 Java 平台中,許多類別直接派生自Object,其他類別派生自其中一些類,依此類推,形成類別層次結構。

Java 中的繼承類型

讓我們重點介紹 Java 中的幾種繼承類型。1.單一繼承 這種型別就像我們上面的例子一樣,子類別繼承一個超類別的特性。下圖中,A類別作為派生類別B的基底類別。2. 多層繼承 這只是一個繼承鏈,即有一個基底類別A,從它繼承了B類,還有C類別繼承自類別B。在Java中,類別不能直接存取祖父母的成員。3. 層次繼承 在層次繼承中,一個類別充當多個子類別的超類別(基底類別)。上面,我們給出了 Phone 類別的範例,它可以有兩個「子層級」—AndroidPhone 和 IPhone。
class A {
    public void printA() {
System.out.println("A");
 }
}

class B extends A {
    public void printB() {
 System.out.println(" B"); }
}

class C extends A {
    public void printC() {
System.out.println("C");
}
}

class D extends A {
    public void printD() {
System.out.println("D");
 }
}

public class Demo {
    public static void main(String[] args)
    {
        B objB = new B();
        objB.printA();
        objB.printB();

        C objC = new C();
        objC.printA();
        objC.printC();

        D objD = new D();
        objD.printA();
        objD.printD();
    }
}
輸出是:
A B A C D
4. 多重繼承,即存在多個祖先...但是等等,Java 中不支持經典的多重繼承。在某種程度上,它可以不使用類別而是使用介面來實現。
interface A {
   public void printA();
}

interface B {
   public void printB();
}

interface C extends A, B {
   public void print();
}
class InheritDemo implements C {
   @Override
   public void print()
   {
       System.out.println("Print something");
   }

   @Override
   public void printA() {
   }

   @Override
   public void printB() {
   }
}
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION