Tidak ada yang salah dengan memiliki antarmuka yang mewarisi antarmuka lain tanpa menambahkan anggota baru, jika semua implementasi dari antarmuka yang terakhir diharapkan dapat melakukan hal - hal yang beberapa implementasi dari yang sebelumnya mungkin tidak berguna . Memang, ini adalah pola yang baik dimana IMHO seharusnya lebih banyak digunakan dalam hal-hal seperti .net Framework, terutama karena seorang pelaksana yang kelasnya secara alami akan memenuhi kendala yang tersirat oleh antarmuka yang lebih diturunkan dapat menunjukkan bahwa hanya dengan menerapkan antarmuka yang lebih diturunkan. , tanpa harus mengubah kode atau deklarasi anggota-implementasi.
Sebagai contoh, misalkan saya memiliki antarmuka:
antarmuka IMaybeMutableFoo {
Bar Thing {get; set;} // Dan properti lainnya juga
bool IsMutable;
IImmutableFoo AsImmutable ();
}
antarmuka IImmutableFoo: IMaybeMutableFoo {};
Suatu implementasi IImmutableFoo.AsImmutable()akan diharapkan untuk mengembalikan dirinya sendiri; implementasi kelas yang bisa berubah IMaybeMutableFoo.AsImmutable()akan diharapkan untuk mengembalikan objek baru yang sangat tidak dapat diubah yang berisi snapshot data. Sebuah rutinitas yang ingin menyimpan snapshot data yang disimpan dalam suatu IMaybeMutableFoodapat menawarkan kelebihan:
publicDoid StoreData (IImmutableFoo ThingToStore)
{
// Menyimpan referensi akan cukup, karena ThingToStore dikenal tidak dapat diubah
}
publicDoid StoreData (IMaybeMutableFoo ThingToStore)
{
StoreData (ThingToStore.AsImmutable ()); // Panggil kelebihan yang lebih spesifik
}
Dalam kasus di mana kompiler tidak tahu bahwa benda yang akan disimpan adalah IImmutableFoo, ia akan memanggil AsImmutable(). Fungsi harus kembali dengan cepat jika item sudah tidak dapat diubah, tetapi panggilan fungsi melalui antarmuka masih membutuhkan waktu. Jika kompiler tahu bahwa item tersebut sudah merupakan IImmutableFoo, ia dapat melewati pemanggilan fungsi yang tidak perlu.
IAnimaldanIDogyang nama tautologi mengerikan!