Saya pikir ini mungkin fitur bahasa yang berguna dan bertanya-tanya apakah ada bahasa yang mendukungnya.
Idenya adalah jika Anda memiliki:
class C
virtual F
statement1
statement2
dan
class D inherits C
override F
statement1
statement2
C.F()
Akan ada kata kunci yang diterapkan pada CF () sehingga menghapus baris terakhir dari kode di atas akan menyebabkan kesalahan kompiler karena mengatakan "Metode ini dapat diganti tetapi implementasi di sini perlu dijalankan tidak peduli apa".
programming-languages
Aaron Anodide
sumber
sumber
Jawaban:
Ya mereka melakukanya. Ini disebut model Skandinavia OO, digunakan misalnya dalam Simula (model OO lain yang tersebar luas dan diterima seperti yang sekarang, adalah model Amerika). Dalam model Skandinavia, Anda tidak mengesampingkan, tetapi memasok sub-perilaku.
dalam metode foo Superclass:
dalam metode Subclass 'foo:
Jika Anda memanggil metode 'instance' Superclass foo, hanya
some-code-before
dansome-code-after
terjadi (INNER
tidak melakukan apa-apa), tetapi jika Anda menyebut Subclass 'instance' foo, itu benarsome-code-before
,some-code-in-subclass
dan kemudiansome-code-after
.sumber
Tidak ada bahasa yang saya tahu tentang penegakan yang memanggil metode yang diganti. Memang, beberapa bahasa memungkinkan metode penggantian yang tidak dapat ditimpa (seperti menggunakan
new
kata kunci dalam C #). Namun, ada dua cara untuk mendekati ini.Yang pertama adalah membuat metode yang tidak dapat diedit (mis. Yang tidak memiliki
virtual
kata kunci dalam C # atau yang memilikifinal
kata kunci di Jawa) yang memanggil metode yang tidak dapat dipanggil yang tidak dapat dipanggil dari luar kelas (misalnyaprotected
dalam C #, Java atau C ++).dan
Kelas overriding
C
bebas untuk menimpaF
dan memodifikasi perilakunya tetapi penelepon dari luar kelas hanya mengaksesnyaA
.Sunting: Seperti yang telah ditunjukkan orang lain, ini disebut pola metode Templat .
Cara kedua adalah menggunakan bahasa yang memberlakukan prasyarat dan prasyarat yang ditentukan dalam kelas dasar, seperti Eiffel atau C # dengan Kontrak Kode. Itu tidak akan memaksa kelas dasar untuk dipanggil tetapi metode yang ditimpa dapat dipaksa untuk melakukan pernyataan yang sama. Menggunakan aspek juga dapat membantu jika bahasa memungkinkan aspek diwariskan.
sumber
private
dalam C ++ :) Herb Sutter menjelaskannya di sini secara rinci.Tidak benar-benar bagian dari bahasa, tetapi penganalisa kode statis FindBugs untuk Java memiliki anotasi
OverrideMustInvoke
yang dapat ditambahkan oleh pengembang ke metode, dan yang akan menyebabkan FindBugs menunjukkan kesalahan jika menemukan metode override yang tidak memanggil super implementasi . Bahkan memungkinkan menentukan apakah panggilan harus menjadi yang pertama atau terakhir dalam metode utama.sumber
Diperlukan untuk memanggil metode superclass adalah anti-pola . Jika tidak diberlakukan pada waktu kompilasi, itu rawan kesalahan, itulah sebabnya Anda mencari konstruksi bahasa yang memeriksanya.
Ada cara yang didukung dalam semua bahasa OO: Pola metode templat . Di sini, Anda membuat metode superclass tidak dapat ditimpa, dan di dalamnya Anda memanggil metode yang dapat ditimpa. Subclass kemudian dapat mengganti metode ini untuk menambahkan fungsionalitas:
Bergantung pada lokasi panggilan ke metode yang diganti bahkan memungkinkan untuk menentukan urutan eksekusi, yang dengan panggilan super biasa adalah atas kehendak pelaksana subkelas.
sumber
Pola terdekat yang bisa saya pikirkan adalah acara berlangganan sendiri. Agak rumit, dan sama sekali tidak intuitif untuk pembuat kode, tetapi mencapai tujuannya.
sumber
Mesin Lisp "rasa" memungkinkan metode dengan mengetik "sebelum" "setelah" dan "sekitar" metode utama yang diwarisi.
sumber
Meskipun bukan ide yang buruk dalam teori, itu memang memiliki efek samping negatif dari membatasi pilihan saya ketika menerapkan
D
. Misalnya, bagaimana jika (karena alasan yang tidak terduga), lebih mudah untuk memanggil implementasi superclassF
dari beberapa metode lain:Di bawah skenario Anda, saya membayangkan kompiler akan menandai implementasi
F
diD
, meskipun ia memanggil (secara tidak langsung)C.F()
.Pada dasarnya, apa yang telah Anda jelaskan adalah mekanisme yang memungkinkan untuk membantu kompiler mengenali ketika kontrak pada kelas yang diwarisi dari
C
dilanggar. Maksud saya adalah, walaupun itu adalah hal yang hebat, itu tidak harus dengan mengorbankan membatasi bagaimana saya dapat mengimplementasikan subclass saya.sumber