Menurut Herb Sutter kita harus lebih memilih antarmuka abstrak (semua fungsi virtual murni) ke kelas abstrak di C ++ untuk memisahkan implementasi sejauh mungkin. Sementara saya pribadi menemukan aturan ini sangat berguna, saya baru-baru ini bergabung dengan tim dengan banyak programmer Java dan dalam kode Java pedoman ini sepertinya tidak ada. Fungsi dan implementasinya sangat sering terletak di kelas abstrak. Jadi saya mendapatkan Herb Sutter semuanya salah bahkan untuk C ++ atau apakah ada perbedaan umum dalam penggunaan fungsi abstrak di C ++ dibandingkan dengan Java. Apakah kelas abstrak dengan kode implementasi lebih masuk akal di Jawa daripada di C ++ dan jika ya mengapa?
java
c++
interfaces
abstract-class
Martin
sumber
sumber
Jawaban:
OOP memiliki komposisi dan substitusi.
C ++ memiliki banyak pewarisan, spesialisasi templat, embedding dan semantik nilai / pindahkan / pointer.
Java memiliki satu pewarisan dan antarmuka, semantik semantik dan rujukan.
Cara umum sekolah OOP menggunakan bahasa-bahasa ini adalah menggunakan pewarisan untuk penggantian objek dan menanamkan untuk komposisi. Tetapi Anda juga membutuhkan leluhur yang sama dan cara untuk runtime-cast (dalam C ++ disebut
dynamic_cast
, di Jawa hanya meminta antarmuka dari yang lain).Java melakukan semua ini dengan
java.lang.Object
hierarki yang telah di-root sendiri . C ++ tidak memiliki root umum yang telah ditentukan, jadi Anda setidaknya harus mendefinisikannya, untuk datang ke "gambar" yang sama (tapi ini membatasi beberapa kemungkinan C ++ ...).Setelah itu, kemungkinan untuk memiliki kompilasi-waktu polimorfisme (think to CRTP) dan nilai semantik juga dapat menawarkan alternatif lain dengan cara konsep "objek OOP" dapat porting ke dalam program C ++.
Anda bahkan dapat membayangkan bid'ah menggunakan penanaman dan konversi implisit untuk mengelola substitusi dan warisan pribadi untuk mengelola komposisi, bahkan membalikkan paradigma sekolah tradisional. (Tentu saja, cara ini 20 tahun lebih muda dari yang lain, jadi jangan berharap dukungan masyarakat luas dalam melakukan itu)
Atau Anda dapat membayangkan pangkalan bersama virtual untuk semua kelas, membentuk antarmuka (tidak ada implementasi) hingga kelas akhir (sepenuhnya diimplementasikan) melalui antarmuka yang diimplementasikan sebagian, bahkan cluster antarmuka, menggunakan "dominasi" sebagai pengiriman dari antarmuka ke implementasi melalui "multi-stacked". skema pewarisan -parallelogram ".
Membandingkan OOP ke java ke C ++ dengan asumsi hanya ada satu dan hanya cara OOP yang membatasi kemampuan kedua bahasa.
Memaksa C ++ untuk sepenuhnya mematuhi idiom pengkodean Java mendenaturasi C ++ karena memaksa Java untuk berperilaku sebagai bahasa mirip C ++ adalah denaturasi Java.
Bukan masalah "sensibilitas" tetapi "mekanisme agregasi" yang berbeda memiliki kedua bahasa dan cara yang berbeda untuk menggabungkan mereka yang membuat beberapa idiom lebih menguntungkan dalam satu bahasa daripada yang lain dan sebaliknya.
sumber
Prinsip ini berlaku untuk kedua bahasa, tetapi Anda tidak melakukan perbandingan yang adil. Anda harus membandingkan kelas abstrak murni C ++ dengan antarmuka Java.
Bahkan di C ++, Anda dapat memiliki kelas abstrak yang memiliki beberapa fungsi diimplementasikan, tetapi berasal dari kelas abstrak murni (tanpa implementasi). Di Java, Anda akan memiliki kelas abstrak yang sama (dengan beberapa implementasi), yang dapat diturunkan dari antarmuka (tanpa implementasi).
sumber
Secara umum prinsip-prinsip OO yang sama berlaku untuk Java dan C ++. Namun, satu perbedaan besar adalah bahwa C ++ mendukung multiple-inheritance sementara di Java Anda hanya dapat mewarisi dari satu kelas. Ini adalah alasan utama mengapa Java memiliki antarmuka saya percaya, untuk menambah kurangnya pewarisan berganda dan mungkin untuk membatasi apa yang dapat Anda lakukan dengannya (karena ada banyak kritik atas penyalahgunaan pewarisan berganda). Jadi, mungkin dalam pikiran programmer Java, ada perbedaan yang lebih kuat antara kelas dan antarmuka abstrak. Kelas abstrak digunakan untuk berbagi dan mewarisi perilaku sementara antarmuka hanya digunakan untuk menambah fungsionalitas tambahan. Ingat, di Java Anda hanya dapat mewarisi dari satu kelas, tetapi Anda dapat memiliki banyak antarmuka. Namun dalam C ++, kelas abstrak murni (yaitu "antarmuka C ++") adalah digunakan untuk berbagi dan mewarisi perilaku tidak seperti tujuan dari antarmuka Java (meskipun Anda masih diharuskan untuk mengimplementasikan fungsi-fungsi), maka penggunaannya berbeda dari antarmuka Java.
sumber
Terkadang masuk akal untuk memiliki beberapa implementasi standar. Misalnya metode PrintError (string msg) generik yang berlaku untuk semua sub kelas.
Itu masih bisa diganti jika benar-benar diperlukan, tetapi Anda dapat menyimpan beberapa kerumitan klien dengan memungkinkan mereka hanya memanggil versi generik.
sumber