Saya telah bekerja dengan penyedia sedikit adil belakangan ini, dan saya menemukan situasi yang menarik di mana saya ingin memiliki kelas abstrak yang memiliki metode statis abstrak. Saya membaca beberapa posting tentang topik ini, dan itu masuk akal, tetapi apakah ada penjelasan yang jelas dan bagus?
c#
.net
language-design
lomaxx
sumber
sumber
Jawaban:
Metode statis tidak dipakai seperti itu, mereka hanya tersedia tanpa referensi objek.
Panggilan ke metode statis dilakukan melalui nama kelas, bukan melalui referensi objek, dan kode Bahasa Menengah (IL) untuk memanggilnya akan memanggil metode abstrak melalui nama kelas yang mendefinisikannya, belum tentu nama kelas yang Anda gunakan.
Izinkan saya menunjukkan sebuah contoh.
Dengan kode berikut:
Jika Anda memanggil B.Test, seperti ini:
Maka kode aktual di dalam metode Utama adalah sebagai berikut:
Seperti yang Anda lihat, panggilan dibuat ke A.Test, karena itu adalah kelas A yang mendefinisikannya, dan bukan ke B.Test, meskipun Anda dapat menulis kode dengan cara itu.
Jika Anda memiliki tipe kelas , seperti di Delphi, di mana Anda dapat membuat variabel yang merujuk ke tipe dan bukan objek, Anda akan lebih banyak menggunakan metode virtual dan abstrak statis (dan juga konstruktor), tetapi mereka tidak tersedia dan dengan demikian panggilan statis non-virtual di .NET.
Saya menyadari bahwa desainer IL dapat memungkinkan kode dikompilasi untuk memanggil B.Test, dan menyelesaikan panggilan saat runtime, tetapi masih tidak virtual, karena Anda masih harus menulis semacam nama kelas di sana.
Metode virtual, dan dengan demikian yang abstrak, hanya berguna ketika Anda menggunakan variabel yang, pada saat runtime, dapat berisi berbagai jenis objek, dan karenanya Anda ingin memanggil metode yang tepat untuk objek saat ini yang Anda miliki dalam variabel. Dengan metode statis, Anda harus tetap menggunakan nama kelas, sehingga metode yang tepat untuk menelepon diketahui pada waktu kompilasi karena tidak dapat dan tidak akan berubah.
Dengan demikian, metode statis virtual / abstrak tidak tersedia di .NET.
sumber
Test()
dalamA
daripada abstrak dan berpotensi didefinisikanB
. \Car
tipe denganCreateFromDescription
metode pabrik statis virtual , maka kode yang menerimaCar
tipe generik yang dibatasiT
dapat memanggilT.CreateFromDescription
untuk menghasilkan mobil tipeT
. Konstruk semacam itu dapat didukung dengan cukup baik di dalam CLR jika masing-masing tipe yang mendefinisikan metode semacam itu memiliki instance singleton statis dari generic class bersarang yang memiliki metode "statis" virtual.Metode statis tidak bisa diwarisi atau diganti, dan itulah sebabnya mereka tidak bisa abstrak. Karena metode statis didefinisikan pada tipe, bukan instance, dari suatu kelas, mereka harus dipanggil secara eksplisit pada tipe itu. Jadi ketika Anda ingin memanggil metode pada kelas anak, Anda perlu menggunakan namanya untuk memanggilnya. Ini membuat warisan tidak relevan.
Asumsikan Anda dapat, untuk sesaat, mewarisi metode statis. Bayangkan skenario ini:
Jika Anda memanggil Base.GetNumber (), metode apa yang akan dipanggil? Nilai mana yang dikembalikan? Cukup mudah untuk melihat bahwa tanpa membuat instance objek, pewarisan agak sulit. Metode abstrak tanpa pewarisan hanyalah metode yang tidak memiliki tubuh, jadi tidak bisa disebut.
sumber
int DoSomething<T>() where T:Base {return T.GetNumber();}
. Tampaknya bermanfaat jikaDoSomething<Base>()
dapat mengembalikan lima, sementaraDoSomething<Child2>()
akan mengembalikan dua. Kemampuan seperti itu tidak hanya berguna untuk contoh mainan, tetapi juga untuk sesuatu seperticlass Car {public static virtual Car Build(PurchaseOrder PO);}
, di mana setiap kelas yang berasal dariCar
harus mendefinisikan metode yang dapat membangun contoh yang diberikan pesanan pembelian.Responden lain (McDowell) mengatakan bahwa polimorfisme hanya berfungsi untuk instance objek. Itu harus memenuhi syarat; ada bahasa yang memperlakukan kelas sebagai turunan dari tipe "Kelas" atau "Metaclass". Bahasa-bahasa ini memang mendukung polimorfisme untuk metode instance dan kelas (statis).
C #, seperti Java dan C ++ sebelumnya, bukan bahasa seperti itu; yang
static
kata kunci digunakan secara eksplisit untuk menunjukkan bahwa metode ini statis-terikat daripada dinamis / virtual.sumber
Berikut adalah situasi di mana pasti ada kebutuhan untuk warisan untuk bidang dan metode statis:
sumber
legs
harus menjadi properti abstrak statis.Untuk menambah penjelasan sebelumnya, panggilan metode statis terikat ke metode tertentu pada waktu kompilasi , yang lebih mengesampingkan perilaku polimorfik.
sumber
Kami benar-benar mengesampingkan metode statis (dalam delphi), ini agak jelek, tetapi berfungsi dengan baik untuk kebutuhan kita.
Kami menggunakannya sehingga kelas dapat memiliki daftar objek yang tersedia tanpa turunan kelas, misalnya, kami memiliki metode yang terlihat seperti ini:
Itu jelek tapi perlu, cara ini kita bisa instantiate hanya apa yang dibutuhkan, daripada memiliki semua kelas instantianted hanya untuk mencari objek yang tersedia.
Ini adalah contoh sederhana, tetapi aplikasi itu sendiri adalah aplikasi client-server yang memiliki semua kelas yang tersedia hanya dalam satu server, dan beberapa klien berbeda yang mungkin tidak memerlukan semua yang dimiliki server dan tidak akan pernah membutuhkan objek objek.
Jadi ini jauh lebih mudah untuk dipertahankan daripada memiliki satu aplikasi server yang berbeda untuk setiap klien.
Semoga contohnya jelas.
sumber
Metode abstrak secara virtual implisit. Metode abstrak membutuhkan instance, tetapi metode statis tidak memiliki instance. Jadi, Anda dapat memiliki metode statis dalam kelas abstrak, itu tidak bisa abstrak statis (atau abstrak statis).
sumber