繼承Inheritance

繼承是用來建立物件導向程式設計中的「is-a」關聯性或 subtyping 模型。Inheritance is used to model the "is-a" relationship, or subtyping, in object-oriented programming.

指定繼承關聯性Specifying Inheritance Relationships

您可以使用類別宣告中的inherit關鍵字來指定繼承關聯性。You specify inheritance relationships by using the inherit keyword in a class declaration. 基本的語法形式如下列範例所示。The basic syntactical form is shown in the following example.

type MyDerived(...) =
    inherit MyBase(...)

一個類別最多隻能有一個直接基類。A class can have at most one direct base class. 如果您未使用inherit關鍵字指定基類, 類別會隱含繼承自。 System.ObjectIf you do not specify a base class by using the inherit keyword, the class implicitly inherits from System.Object.

繼承的成員Inherited Members

如果類別繼承自另一個類別, 則衍生類別的使用者可以使用基類的方法和成員, 就如同它們是衍生類別的直接成員一樣。If a class inherits from another class, the methods and members of the base class are available to users of the derived class as if they were direct members of the derived class.

任何 let 系結和函式參數都是類別的私用, 因此無法從衍生類別存取。Any let bindings and constructor parameters are private to a class and, therefore, cannot be accessed from derived classes.

關鍵字base可在衍生類別中使用, 並參考基類實例。The keyword base is available in derived classes and refers to the base class instance. 其使用方式與自我識別碼類似。It is used like the self-identifier.

虛擬方法和覆寫Virtual Methods and Overrides

相較于其他 .NET 語言, 虛擬方法 ( F#和屬性) 在中的工作方式稍有不同。Virtual methods (and properties) work somewhat differently in F# as compared to other .NET languages. 若要宣告新的虛擬成員, 請使用abstract關鍵字。To declare a new virtual member, you use the abstract keyword. 無論您是否為該方法提供預設的實作為, 都可以執行此動作。You do this regardless of whether you provide a default implementation for that method. 因此, 基底類別中虛擬方法的完整定義會遵循此模式:Thus a complete definition of a virtual method in a base class follows this pattern:

abstract member [method-name] : [type]

default [self-identifier].[method-name] [argument-list] = [method-body]

而在衍生類別中, 此虛擬方法的覆寫會遵循此模式:And in a derived class, an override of this virtual method follows this pattern:

override [self-identifier].[method-name] [argument-list] = [method-body]

如果您省略基類中的預設實作為, 基底類別會變成抽象類別。If you omit the default implementation in the base class, the base class becomes an abstract class.

下列程式碼範例說明如何在基類中宣告新的function1虛擬方法, 以及如何在衍生類別中覆寫它。The following code example illustrates the declaration of a new virtual method function1 in a base class and how to override it in a derived class.

type MyClassBase1() =
   let mutable z = 0
   abstract member function1 : int -> int
   default u.function1(a : int) = z <- z + a; z

type MyClassDerived1() =
   inherit MyClassBase1()
   override u.function1(a: int) = a + 1

建構函式和繼承Constructors and Inheritance

基類的函式必須在衍生類別中呼叫。The constructor for the base class must be called in the derived class. 基類的引數會出現在inherit子句的引數清單中。The arguments for the base class constructor appear in the argument list in the inherit clause. 所使用的值必須從提供給衍生類別的引數來判斷。The values that are used must be determined from the arguments supplied to the derived class constructor.

下列程式碼顯示基類和衍生類別, 其中衍生的類別會在繼承子句中呼叫基類的函式:The following code shows a base class and a derived class, where the derived class calls the base class constructor in the inherit clause:

type MyClassBase2(x: int) =
   let mutable z = x * x
   do for i in 1..z do printf "%d " i


type MyClassDerived2(y: int) =
   inherit MyClassBase2(y * 2)
   do for i in 1..y do printf "%d " i

在多個函式的情況下, 可以使用下列程式碼。In the case of multiple constructors, the following code can be used. 衍生類別的第一行程式碼是inherit子句, 而欄位則是以val關鍵字宣告的明確欄位來顯示。The first line of the derived class constructors is the inherit clause, and the fields appear as explicit fields that are declared with the val keyword. 如需詳細資訊, 請參閱明確欄位:val關鍵字。For more information, see Explicit Fields: The val Keyword.

type BaseClass =
    val string1 : string
    new (str) = { string1 = str }
    new () = { string1 = "" }

type DerivedClass =
    inherit BaseClass

    val string2 : string
    new (str1, str2) = { inherit BaseClass(str1); string2 = str2 }
    new (str2) = { inherit BaseClass(); string2 = str2 }

let obj1 = DerivedClass("A", "B")
let obj2 = DerivedClass("A")

繼承的替代專案Alternatives to Inheritance

在需要稍微修改類型的情況下, 請考慮使用物件運算式做為繼承的替代方法。In cases where a minor modification of a type is required, consider using an object expression as an alternative to inheritance. 下列範例說明如何使用物件運算式, 做為建立新衍生型別的替代方法:The following example illustrates the use of an object expression as an alternative to creating a new derived type:

open System

let object1 = { new Object() with
      override this.ToString() = "This overrides object.ToString()"
      }

printfn "%s" (object1.ToString())

如需物件運算式的詳細資訊, 請參閱物件運算式For more information about object expressions, see Object Expressions.

當您建立物件階層時, 請考慮使用區分聯集, 而不是繼承。When you are creating object hierarchies, consider using a discriminated union instead of inheritance. 相異聯集也可以針對共用一般類型的不同物件, 建立各種不同的行為模型。Discriminated unions can also model varied behavior of different objects that share a common overall type. 單一差異聯集通常不需要多個不同的衍生類別, 而是彼此的次要變化。A single discriminated union can often eliminate the need for a number of derived classes that are minor variations of each other. 如需區分等位的詳細資訊, 請參閱區分等位。For information about discriminated unions, see Discriminated Unions.

另請參閱See also