抽象クラスAbstract Classes

抽象クラスは、一部またはすべてのメンバーを実装しないままにして、派生クラスによって実装を提供できるようにするクラスです。Abstract classes are classes that leave some or all members unimplemented, so that implementations can be provided by derived classes.

構文Syntax

// Abstract class syntax.
[<AbstractClass>]
type [ accessibility-modifier ] abstract-class-name =
[ inherit base-class-or-interface-name ]
[ abstract-member-declarations-and-member-definitions ]

// Abstract member syntax.
abstract member member-name : type-signature

RemarksRemarks

オブジェクト指向プログラミングでは、抽象クラスが階層の基底クラスとして使用され、さまざまな種類のオブジェクトの共通機能を表します。In object-oriented programming, an abstract class is used as a base class of a hierarchy, and represents common functionality of a diverse set of object types. "Abstract" という名前が示すとおり、多くの場合、抽象クラスは問題ドメインの具象エンティティに直接対応していません。As the name "abstract" implies, abstract classes often do not correspond directly onto concrete entities in the problem domain. ただし、共通のさまざまな具象エンティティの数を表すことができます。However, they do represent what many different concrete entities have in common.

抽象クラスにAbstractClassは属性が必要です。Abstract classes must have the AbstractClass attribute. 実装および実装されていないメンバーを持つことができます。They can have implemented and unimplemented members. 用語の使用抽象クラスは、他の .NET 言語と同様に適用するとただし、用語の使用抽象メソッド (およびプロパティ) に適用する場合からの F# で少し異なりますが、他の .NET 言語で使用します。The use of the term abstract when applied to a class is the same as in other .NET languages; however, the use of the term abstract when applied to methods (and properties) is a little different in F# from its use in other .NET languages. でF#は、メソッドがabstractキーワードでマークされている場合、その型の仮想関数の内部テーブルに、メンバーに仮想ディスパッチスロットと呼ばれるエントリがあることを示します。In F#, when a method is marked with the abstract keyword, this indicates that a member has an entry, known as a virtual dispatch slot, in the internal table of virtual functions for that type. メソッドが仮想、つまり、ですが、virtualキーワードは、F# 言語では使用されません。In other words, the method is virtual, although the virtual keyword is not used in the F# language. キーワードabstractは、メソッドが実装されているかどうかに関係なく、仮想メソッドで使用されます。The keyword abstract is used on virtual methods regardless of whether the method is implemented. 仮想ディスパッチスロットの宣言は、そのディスパッチスロットのメソッドの定義とは別のものです。The declaration of a virtual dispatch slot is separate from the definition of a method for that dispatch slot. そのため、抽象メソッドの宣言といずれかを別の定義の両方の組み合わせは、仮想メソッドの宣言と定義を別の .NET 言語での F# と同じ、defaultキーワードまたはoverrideキーワード。Therefore, the F# equivalent of a virtual method declaration and definition in another .NET language is a combination of both an abstract method declaration and a separate definition, with either the default keyword or the override keyword. 詳細と例については、「メソッド」を参照してください。For more information and examples, see Methods.

クラスは、宣言されているが定義されていない抽象メソッドがある場合にのみ、抽象と見なされます。A class is considered abstract only if there are abstract methods that are declared but not defined. したがって、抽象メソッドを持つクラスは、必ずしも抽象クラスではありません。Therefore, classes that have abstract methods are not necessarily abstract classes. クラスに未定義の抽象メソッドがある場合を除き、 AbstractClass属性は使用しないでください。Unless a class has undefined abstract methods, do not use the AbstractClass attribute.

前の構文では、アクセシビリティ-修飾子publicprivateinternal、またはを指定できます。In the previous syntax, accessibility-modifier can be public, private or internal. 詳細については、「アクセス制御」(アクセス制御) を参照してください。For more information, see Access Control.

他の型と同様に、抽象クラスは基底クラスと1つ以上の基本インターフェイスを持つことができます。As with other types, abstract classes can have a base class and one or more base interfaces. 各基底クラスまたはインターフェイスは、 inheritキーワードと共に個別の行に表示されます。Each base class or interface appears on a separate line together with the inherit keyword.

抽象クラスの型定義には、完全に定義されたメンバーを含めることができますが、抽象メンバーを含めることもできます。The type definition of an abstract class can contain fully defined members, but it can also contain abstract members. 抽象メンバーの構文は、前の構文で個別に表示されます。The syntax for abstract members is shown separately in the previous syntax. この構文では、メンバーの型シグネチャは、列挙型と戻り値の型を含むリストであり、カリー化および->タプルのパラメーターに*は、トークンまたはトークンで区切られています。In this syntax, the type signature of a member is a list that contains the parameter types in order and the return types, separated by -> tokens and/or * tokens as appropriate for curried and tupled parameters. 抽象メンバー型シグネチャの構文は、署名ファイルで使用される構文と、Visual Studio Code エディターで IntelliSense によって示されるシグネチャと同じです。The syntax for abstract member type signatures is the same as that used in signature files and that shown by IntelliSense in the Visual Studio Code Editor.

次のコードは、抽象クラスの図形を示しています。抽象クラスには、2つの非抽象派生クラス (Square と Circle) があります。The following code illustrates an abstract class Shape, which has two non-abstract derived classes, Square and Circle. この例は、抽象クラス、メソッド、およびプロパティの使用方法を示しています。The example shows how to use abstract classes, methods, and properties. この例では、抽象クラスのシェイプは、具象エンティティの circle と square の共通要素を表しています。In the example, the abstract class Shape represents the common elements of the concrete entities circle and square. (2 次元座標系内の) すべての図形の共通機能は、形状クラスに抽象化されます。これは、グリッド上の位置、回転角度、および領域と境界のプロパティです。The common features of all shapes (in a two-dimensional coordinate system) are abstracted out into the Shape class: the position on the grid, an angle of rotation, and the area and perimeter properties. これらは、位置、つまり個々の図形が変更できない動作を除き、オーバーライドできます。These can be overridden, except for position, the behavior of which individual shapes cannot change.

回転メソッドは、対称軸クラスのようにオーバーライドできます。これは、対称によって回転が不変です。The rotation method can be overridden, as in the Circle class, which is rotation invariant because of its symmetry. そのため、Circle クラスでは、ローテーションメソッドは何も実行しないメソッドに置き換えられます。So in the Circle class, the rotation method is replaced by a method that does nothing.

// An abstract class that has some methods and properties defined
// and some left abstract.
[<AbstractClass>]
type Shape2D(x0 : float, y0 : float) =
    let mutable x, y = x0, y0
    let mutable rotAngle = 0.0

    // These properties are not declared abstract. They
    // cannot be overriden.
    member this.CenterX with get() = x and set xval = x <- xval
    member this.CenterY with get() = y and set yval = y <- yval

    // These properties are abstract, and no default implementation
    // is provided. Non-abstract derived classes must implement these.
    abstract Area : float with get
    abstract Perimeter : float  with get
    abstract Name : string with get

    // This method is not declared abstract. It cannot be
    // overridden.
    member this.Move dx dy =
       x <- x + dx
       y <- y + dy

    // An abstract method that is given a default implementation
    // is equivalent to a virtual method in other .NET languages.
    // Rotate changes the internal angle of rotation of the square.
    // Angle is assumed to be in degrees.
    abstract member Rotate: float -> unit
    default this.Rotate(angle) = rotAngle <- rotAngle + angle

type Square(x, y, sideLengthIn) =
    inherit Shape2D(x, y)
    member this.SideLength = sideLengthIn
    override this.Area = this.SideLength * this.SideLength
    override this.Perimeter = this.SideLength * 4.
    override this.Name = "Square"

type Circle(x, y, radius) =
    inherit Shape2D(x, y)
    let PI = 3.141592654
    member this.Radius = radius
    override this.Area = PI * this.Radius * this.Radius
    override this.Perimeter = 2. * PI * this.Radius
    // Rotating a circle does nothing, so use the wildcard
    // character to discard the unused argument and
    // evaluate to unit.
    override this.Rotate(_) = ()
    override this.Name = "Circle"

let square1 = new Square(0.0, 0.0, 10.0)
let circle1 = new Circle(0.0, 0.0, 5.0)
circle1.CenterX <- 1.0
circle1.CenterY <- -2.0
square1.Move -1.0 2.0
square1.Rotate 45.0
circle1.Rotate 45.0
printfn "Perimeter of square with side length %f is %f, %f"
        (square1.SideLength) (square1.Area) (square1.Perimeter)
printfn "Circumference of circle with radius %f is %f, %f"
        (circle1.Radius) (circle1.Area) (circle1.Perimeter)

let shapeList : list<Shape2D> = [ (square1 :> Shape2D);
                                  (circle1 :> Shape2D) ]
List.iter (fun (elem : Shape2D) ->
              printfn "Area of %s: %f" (elem.Name) (elem.Area))
          shapeList

出力:Output:

Perimeter of square with side length 10.000000 is 40.000000
Circumference of circle with radius 5.000000 is 31.415927
Area of Square: 100.000000
Area of Circle: 78.539816

関連項目See also