Kelas Abstrak
Kelas abstrak adalah kelas yang membuat beberapa atau semua anggota tidak diimplementasikan, sehingga implementasi dapat disediakan oleh kelas turunan.
Sintaks
// 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
Keterangan
Dalam pemrograman berorientasi pada objek, kelas abstrak digunakan sebagai kelas dasar hierarki, dan mewakili fungsionalitas umum dari beragam jenis objek. Seperti namanya, "abstrak" menyiratkan kelas abstrak yang sering kali tidak sesuai langsung ke entitas konkret di domain masalah. Namun, mereka mewakili kesamaan yang dimiliki banyak entitas konkret yang berbeda.
Kelas abstrak harus memiliki atribut AbstractClass
. Mereka dapat memiliki anggota yang diimplementasikan dan tidak diimplementasikan. Penggunaan istilah abstrak ketika diterapkan ke kelas sama seperti dalam bahasa .NET lainnya; namun, penggunaan istilah abstrak ketika diterapkan ke metode (dan properti) sedikit berbeda dalam F# dari penggunaannya dalam bahasa .NET lainnya. Di F#, ketika metode ditandai dengan kata kunci abstract
, ini menunjukkan bahwa anggota memiliki entri, yang dikenal sebagai slot pengiriman virtual, dalam tabel internal fungsi virtual untuk jenis tersebut. Dengan kata lain, metode ini virtual, meskipun kata kunci virtual
tidak digunakan dalam F#. Kata kunci abstract
digunakan pada metode virtual terlepas dari apakah metode tersebut diimplementasikan. Deklarasi slot pengiriman virtual terpisah dari definisi metode untuk slot pengiriman tersebut. Oleh karena itu, F# yang setara dengan deklarasi metode virtual dan definisi dalam bahasa .NET lain adalah kombinasi dari deklarasi metode abstrak dan definisi terpisah, dengan kata kunci default
atau kata kunci override
. Untuk informasi dan contoh selengkapnya, lihat Metode.
Kelas dianggap abstrak hanya jika ada metode abstrak yang dinyatakan tetapi tidak didefinisikan. Oleh karena itu, kelas yang memiliki metode abstrak belum tentu kelas abstrak. Jangan gunakan atribut AbstractClass kecuali kelas memiliki metode abstrak yang tidak terdefinisi.
Dalam sintaks sebelumnya, pengubah aksesibilitas dapat berupa public
, private
, atau internal
. Untuk informasi selengkapnya, lihat Kontrol Akses.
Seperti jenis lainnya, kelas abstrak dapat memiliki kelas dasar dan satu atau beberapa antarmuka dasar. Setiap kelas dasar atau antarmuka muncul pada baris terpisah bersama dengan kata kunci inherit
.
Definisi jenis kelas abstrak dapat berisi anggota yang sepenuhnya ditentukan, tetapi juga dapat berisi anggota abstrak. Sintaks untuk anggota abstrak ditampilkan secara terpisah dalam sintaks sebelumnya. Dalam sintaks ini, tanda tangan jenis anggota adalah daftar yang berisi jenis parameter secara berurutan dan jenis pengembalian, dipisahkan oleh token ->
dan/atau token *
yang sesuai untuk parameter kurir dan tupled. Sintaks untuk tanda tangan jenis anggota abstrak sama dengan yang digunakan dalam file tanda tangan dan yang ditampilkan oleh IntelliSense di editor Visual Studio Code.
Kode berikut menggambarkan Bentuk kelas abstrak, yang memiliki dua kelas turunan non-abstrak, Persegi, dan Lingkaran. Contoh ini menunjukkan cara menggunakan kelas, metode, dan properti abstrak. Dalam contoh, Bentuk kelas abstrak mewakili elemen umum dari entitas konkret lingkaran dan persegi. Fitur umum dari semua bentuk (dalam sistem koordinat dua dimensi) diabstraksikan ke dalam kelas Bentuk: posisi pada grid, sudut rotasi, dan properti area dan perimeter. Ini dapat ditimpa, kecuali untuk posisi, perilaku yang bentuk individunya tidak dapat berubah.
Metode rotasi dapat diganti, seperti pada kelas Lingkaran, yang rotasinya tidak berubah karena bentuknya simetris. Jadi di kelas Lingkaran, metode rotasi diganti dengan metode yang tidak melakukan apa-apa.
// 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
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk