Mengapa semua kelas di .NET secara global mewarisi dari kelas Object?

16

Ini sangat menarik bagi saya yang keunggulannya memberikan pendekatan "global root class" untuk kerangka kerja. Dengan kata-kata sederhana alasan apa yang dihasilkan .NET framework dirancang untuk memiliki satu kelas objek root dengan fungsi umum yang cocok untuk semua kelas.

Saat ini kami sedang merancang kerangka kerja baru untuk penggunaan internal (kerangka kerja di bawah platform SAP) dan kami semua dibagi menjadi dua kubu - pertama yang berpikir bahwa kerangka kerja harus memiliki akar global, dan yang kedua - yang berpikir sebaliknya.

Saya berada di kamp "akar global". Dan alasan saya apa pendekatan seperti itu akan menghasilkan fleksibilitas yang baik dan pengurangan biaya pengembangan menyebabkan kita tidak akan mengembangkan fungsionalitas umum lagi.

Jadi, saya sangat tertarik untuk mengetahui alasan apa yang mendorong arsitek .NET untuk mendesain kerangka kerja sedemikian rupa.

Anton Semenov
sumber
6
Ingat bahwa .NET Framework adalah bagian dari lingkungan pengembangan perangkat lunak umum. Kerangka kerja yang lebih spesifik, seperti milik Anda, mungkin tidak memerlukan objek "root". Ada root objectdalam kerangka .NET sebagian karena menyediakan beberapa kemampuan dasar di semua objek, seperti ToString()danGetHashCode()
Robert Harvey
10
"Saya sangat menarik untuk mengetahui alasan apa yang benar-benar mendorong arsitek NET untuk merancang kerangka kerja sedemikian rupa." Ada tiga alasan yang sangat bagus untuk itu: 1. Jawa melakukannya seperti itu, 2. Jawa melakukannya dengan cara itu, dan 3. Jawa melakukannya dengan cara itu.
dasblinkenlight
2
@vcsjones: dan Java misalnya sudah tercemar dengan wait()/ notify()/ notifyAll()dan clone().
Joachim Sauer
3
@daskblinkenlight Kotoran itu. Java tidak melakukannya dengan cara itu.
Dante
2
@dasblinkenlight: FYI, Java adalah yang saat ini menyalin C #, dengan lambdas, fungsi LINQ, dll ...
user541686

Jawaban:

18

Penyebab yang paling mendesak Objectadalah wadah (sebelum obat generik) yang dapat berisi apa saja alih-alih harus menggunakan gaya C "Tuliskan lagi untuk semua yang Anda butuhkan". Tentu saja, bisa dibilang, gagasan bahwa segala sesuatu harus mewarisi dari kelas tertentu dan kemudian menyalahgunakan fakta ini untuk benar-benar kehilangan setiap setitik tipe keselamatan begitu mengerikan sehingga seharusnya menjadi lampu peringatan raksasa untuk pengiriman bahasa tanpa obat generik, dan juga sarana itu Objectsepenuhnya berlebihan untuk kode baru.

DeadMG
sumber
6
Ini adalah jawaban yang benar. Kurangnya dukungan generik adalah satu-satunya alasan. Argumen "metode umum" lainnya bukanlah argumen nyata karena metode umum tidak perlu umum - Contoh: 1) ToString: disalahgunakan dalam kebanyakan kasus; 2) GetHashCode: tergantung pada apa yang dilakukan program, sebagian besar kelas tidak memerlukan metode ini; 3) GetType: tidak harus menjadi metode instan
Codism
2
Dengan cara apa. NET "benar-benar kehilangan setiap titik tipe keselamatan" dengan "menyalahgunakan" gagasan bahwa semuanya harus diwarisi dari kelas tertentu? Apakah ada kode shit yang dapat ditulis sekitar Objectyang tidak bisa ditulis void *di C ++?
Carson63000
3
Siapa bilang saya pikir void*lebih baik? Bukan itu. Jika ada itu bahkan lebih buruk .
DeadMG
void*lebih buruk di C dengan semua cast pointer implisit, tetapi C ++ lebih ketat dalam hal ini. Setidaknya Anda harus berperan secara eksplisit.
Tamás Szelei
2
@fish: A terminologi berdalih: di C, tidak ada yang namanya "pemeran implisit". Para pemain adalah operator eksplisit yang menentukan konversi. Maksud Anda " konversi penunjuk implisit ".
Keith Thompson
11

Saya ingat Eric Lippert pernah mengatakan bahwa mewarisi dari System.Objectkelas memberikan 'nilai terbaik bagi pelanggan'. [edit: ya, katanya di sini ]:

... Mereka tidak membutuhkan tipe basis umum. Pilihan ini tidak dibuat karena kebutuhan. Itu dibuat dari keinginan untuk memberikan nilai terbaik bagi pelanggan.

Saat mendesain sistem tipe, atau apa pun dalam hal ini, kadang-kadang Anda mencapai titik keputusan - Anda harus memutuskan X atau tidak-X ... Manfaat memiliki jenis pangkalan umum lebih besar daripada biaya, dan manfaat bersih karenanya akrual lebih besar dari manfaat bersih karena tidak memiliki tipe pangkalan umum. Jadi kami memilih untuk memiliki tipe pangkalan yang sama.

Itu jawaban yang cukup samar. Jika Anda menginginkan jawaban yang lebih spesifik, coba ajukan pertanyaan yang lebih spesifik.

Memiliki semuanya berasal dari System.Objectkelas memberikan keandalan dan kegunaan yang saya hormati. Saya tahu bahwa semua objek akan memiliki tipe ( GetType), bahwa mereka akan sejalan dengan metode finalisasi CLR ( Finalize), dan bahwa saya dapat menggunakannya GetHashCodepada mereka ketika berhadapan dengan koleksi.

gws2
sumber
2
Ini cacat. Anda tidak perlu GetType, Anda cukup memperpanjang typeofuntuk mengganti fungsinya. Adapun Finalize, kemudian sebenarnya, banyak jenis yang sama sekali tidak dapat diselesaikan sama sekali dan tidak memiliki metode Finalisasi yang berarti. Selain itu, banyak jenis yang tidak dapat hashable atau convertible ke string-terutama tipe internal yang tidak pernah dimaksudkan untuk hal seperti itu dan tidak pernah diberikan untuk penggunaan umum. Semua tipe ini memiliki antarmuka yang tercemar secara tidak perlu.
DeadMG
5
Tidak, itu tidak cacat - Saya tidak pernah mengklaim bahwa Anda akan menggunakan GetType, Finalizeatau GetHashCodeuntuk setiap System.Object. Saya hanya menyatakan bahwa mereka ada di sana jika Anda menginginkannya. Adapun "antarmuka mereka tercemar tanpa perlu", saya akan merujuk pada kutipan asli saya dari elippert: "nilai terbaik untuk pelanggan". Jelas tim .NET bersedia menangani pengorbanan.
gws2
Jika tidak perlu, maka itu adalah polusi antarmuka. "Jika Anda ingin" tidak pernah menjadi alasan yang baik untuk memasukkan metode. Seharusnya hanya ada di sana karena Anda membutuhkannya dan konsumen Anda akan menyebutnya . Lain lagi, itu tidak baik. Juga, kutipan Lippert Anda merupakan daya tarik untuk kekeliruan otoritas, karena ia juga mengatakan tidak lain dari "Itu baik".
DeadMG
Saya tidak mencoba untuk memperdebatkan poin Anda @DeadMG - pertanyaannya adalah secara khusus "Mengapa semua kelas di .NET secara global mewarisi dari kelas Object" dan dengan demikian saya ditautkan ke pos sebelumnya oleh seseorang yang sangat dekat dengan tim .NET di Microsoft yang telah memberikan jawaban yang sah - meskipun tidak jelas - mengapa tim pengembangan .NET memilih pendekatan ini.
gws2
Terlalu samar untuk menjadi jawaban atas pertanyaan ini.
DeadMG
4

Saya berpikir bahwa desainer Java dan C # menambahkan objek root karena pada dasarnya gratis untuk mereka, seperti makan siang gratis .

Biaya menambahkan objek root sangat sama dengan biaya menambahkan fungsi virtual pertama Anda. Karena kedua CLR dan JVM adalah lingkungan yang dikumpulkan sampah dengan finalizer objek, Anda harus memiliki setidaknya satu virtual untuk Anda java.lang.Object.finalizeatau untuk System.Object.Finalizemetode Anda . Oleh karena itu, biaya untuk menambahkan objek root Anda sudah dibayar dimuka, Anda bisa mendapatkan semua manfaat tanpa membayarnya. Ini adalah yang terbaik dari kedua dunia: pengguna yang membutuhkan kelas root yang sama akan mendapatkan apa yang mereka inginkan, dan pengguna yang tidak peduli akan dapat memprogram seolah-olah itu tidak ada.

dasblinkenlight
sumber
4

Menurut saya Anda memiliki tiga pertanyaan di sini: satu adalah mengapa root umum diperkenalkan ke .NET, yang kedua adalah apa kelebihan dan kekurangan dari itu, dan yang ketiga adalah apakah ide yang baik untuk elemen kerangka kerja untuk memiliki global akar.

Mengapa .NET memiliki akar yang sama?

Dalam arti yang paling teknis, memiliki akar yang sama sangat penting untuk refleksi dan untuk wadah pra-generik.

Selain itu, setahu saya, memiliki akar yang sama dengan metode dasar seperti equals()dan hashCode()diterima dengan sangat positif di Jawa, dan C # dipengaruhi oleh (antara lain) Jawa, sehingga mereka ingin memiliki fitur itu juga.

Apa kelebihan dan kekurangan dari memiliki akar yang sama dalam suatu bahasa?

Keuntungan memiliki akar yang sama:

  • Anda dapat mengizinkan semua objek memiliki fungsi tertentu yang Anda anggap penting, seperti equals()dan hashCode(). Itu berarti, misalnya, bahwa setiap objek di Java atau C # dapat digunakan dalam peta hash - bandingkan situasi itu dengan C ++.
  • Anda dapat merujuk ke objek dengan tipe yang tidak dikenal - misalnya jika Anda hanya mentransfer informasi, seperti yang dilakukan wadah pra-generik.
  • Anda dapat merujuk ke objek dengan tipe yang tidak diketahui - misalnya saat menggunakan refleksi.
  • Ini dapat digunakan dalam kasus-kasus langka ketika Anda ingin dapat menerima objek yang bisa dari jenis yang berbeda dan tidak terkait - misalnya sebagai parameter dari printfmetode -seperti.
  • Ini memberi Anda fleksibilitas untuk mengubah perilaku semua objek dengan mengubah hanya satu kelas. Misalnya, jika Anda ingin menambahkan metode ke semua objek di program C # Anda, Anda bisa menambahkan metode ekstensi object. Mungkin tidak terlalu umum, tetapi tanpa akar kata yang sama, itu tidak mungkin.

Kerugian memiliki akar yang sama:

  • Ini bisa disalahgunakan untuk merujuk ke suatu objek yang nilainya bahkan jika Anda bisa menggunakan jenis yang lebih akurat untuk itu.

Haruskah Anda menggunakan akar yang sama dalam proyek kerangka kerja Anda?

Sangat subyektif, tentu saja, tetapi ketika saya melihat daftar pro-con di atas saya pasti akan menjawab ya . Secara khusus, peluru terakhir dalam daftar pro - fleksibilitas kemudian mengubah perilaku semua objek dengan mengubah root - menjadi sangat berguna dalam platform, di mana perubahan ke root lebih mungkin diterima oleh klien daripada perubahan keseluruhan bahasa.

Selain itu - meskipun ini bahkan lebih subyektif - saya menemukan konsep root umum sangat elegan dan menarik. Ini juga membuat beberapa penggunaan alat lebih mudah, misalnya sekarang mudah untuk meminta alat untuk menunjukkan semua keturunan dari root yang sama dan menerima ikhtisar yang cepat dan bagus dari jenis kerangka kerja.

Tentu saja, tipe-tipe itu setidaknya harus sedikit terkait untuk itu, dan khususnya, saya tidak akan pernah mengorbankan aturan "is-a" hanya untuk memiliki akar yang sama.

ek
sumber
Saya pikir c # tidak hanya dipengaruhi oleh Java, itu di beberapa titik -adalah Java. Microsoft tidak dapat menggunakan Java lagi sehingga akan kehilangan miliaran investasi. Mereka mulai dengan memberi bahasa bahwa mereka sudah memiliki nama baru.
Mike Braun
3

Secara matematis, ini sedikit lebih elegan untuk memiliki sistem tipe yang berisi atas , dan memungkinkan Anda untuk mendefinisikan bahasa sedikit lebih lengkap.

Jika Anda membuat kerangka kerja, maka hal-hal tentu akan dikonsumsi oleh basis kode yang ada. Anda tidak dapat memiliki supertipe universal karena semua tipe lain dalam apa pun yang dikonsumsi kerangka ada.

Di bahwa titik, keputusan untuk memiliki kelas dasar umum tergantung pada apa yang Anda lakukan. Sangat jarang bahwa banyak hal memiliki perilaku yang sama, dan berguna untuk merujuk hal-hal ini melalui perilaku yang umum saja.

Tetapi itu terjadi. Jika ya, maka langsung saja abstraksi perilaku umum itu.

Telastyn
sumber
2

Mendorong untuk objek root karena mereka ingin semua kelas dalam kerangka mendukung hal-hal tertentu (mendapatkan kode hash, mengkonversi ke string, pemeriksaan kesetaraan, dll.). Baik C # dan Java merasa berguna untuk meletakkan semua fitur umum ini dari sebuah Object di beberapa kelas root.

Perlu diingat bahwa mereka tidak melanggar prinsip OOP atau apa pun. Apa pun di kelas Object masuk akal dalam subclass apa pun (baca: kelas apa saja ) dalam sistem. Jika Anda memilih untuk mengadopsi desain ini, pastikan Anda mengikuti pola ini. Artinya, jangan memasukkan hal-hal di root yang tidak termasuk dalam setiap, satu kelas di sistem Anda. Jika Anda mengikuti aturan ini dengan hati-hati, saya tidak melihat alasan mengapa Anda tidak boleh memiliki kelas root yang berisi kode umum yang berguna untuk seluruh sistem.

Oleksi
sumber
2
Itu tidak benar sama sekali. Ada banyak kelas internal saja yang tidak pernah hash, tidak pernah direfleksikan, tidak pernah dikonversi ke string. Warisan yang tidak perlu dan metode berlebihan pasti tidak melanggar banyak prinsip.
DeadMG
2

Beberapa alasan, fungsi umum yang bisa dibagi oleh semua kelas anak Dan itu juga memberi penulis kerangka kemampuan untuk menulis banyak fungsionalitas lain ke dalam kerangka yang semuanya bisa digunakan. Contohnya adalah caching dan sesi ASP.NET. Hampir semuanya dapat disimpan di dalamnya, karena mereka menulis metode add untuk menerima objek.

Kelas root bisa sangat memikat, tetapi sangat, sangat mudah disalahgunakan. Apakah mungkin untuk memiliki antarmuka root? Dan hanya punya satu atau dua metode kecil? Atau apakah itu akan menambah lebih banyak kode daripada yang dibutuhkan untuk kerangka kerja Anda?

Saya bertanya, saya ingin tahu tentang fungsi apa yang perlu Anda paparkan ke semua kelas yang mungkin dalam kerangka yang Anda tulis. Akankah itu benar-benar digunakan oleh semua benda? Atau oleh sebagian besar dari mereka? Dan begitu Anda membuat kelas root, bagaimana Anda mencegah orang menambahkan fungsionalitas acak ke dalamnya? Atau variabel acak yang mereka inginkan menjadi "global"?

Beberapa tahun yang lalu ada aplikasi yang sangat besar di mana saya membuat kelas root. Setelah beberapa bulan pengembangan itu diisi oleh kode yang tidak memiliki bisnis di sana. Kami mengonversi aplikasi ASP lama dan kelas root adalah pengganti file global.inc lama yang kami gunakan di masa lalu. Harus belajar pelajaran itu dengan cara yang sulit.

bwalk2895
sumber
2

Semua benda tumpukan bawaan mewarisi dari Object ; itu masuk akal karena semua objek tumpukan mandiri harus memiliki aspek umum tertentu, seperti cara mengidentifikasi tipenya. Kalau tidak, jika pengumpul sampah memiliki referensi ke objek tumpukan jenis yang tidak diketahui, itu tidak akan memiliki cara untuk mengetahui bit dalam gumpalan memori yang terkait dengan objek yang harus dianggap sebagai referensi ke objek tumpukan lainnya.

Lebih jauh, dalam sistem tipe, akan lebih mudah untuk menggunakan mekanisme yang sama untuk mendefinisikan anggota struktur dan anggota kelas. Perilaku lokasi penyimpanan tipe nilai (variabel, parameter, bidang, slot array, dll.) Sangat berbeda dari lokasi penyimpanan tipe kelas, tetapi perbedaan perilaku tersebut dicapai dalam kompiler kode sumber dan mesin eksekusi (termasuk kompiler JIT) daripada diekspresikan dalam sistem tipe.

Salah satu konsekuensi dari ini adalah bahwa mendefinisikan tipe nilai secara efektif mendefinisikan dua tipe - tipe lokasi penyimpanan dan tipe objek tumpukan. Yang pertama dapat secara implisit dikonversi ke yang terakhir, dan yang terakhir dapat dikonversi ke yang pertama melalui typecast. Kedua jenis konversi ini berfungsi dengan menyalin semua bidang publik dan pribadi dari satu contoh dari jenis yang dipertanyakan. Selain itu, dimungkinkan menggunakan batasan umum untuk memanggil anggota antarmuka pada lokasi penyimpanan tipe nilai secara langsung, tanpa membuat salinannya terlebih dahulu.

Semua ini penting karena referensi ke objek tumpukan tipe nilai berperilaku seperti referensi kelas dan tidak suka tipe nilai. Pertimbangkan, misalnya, kode berikut:

string testEnumerator <T> (T it) di mana T: IEnumerator <string>
{
  var it2 = itu;
  it.MoveNext ();
  it2.MoveNext ();
  mengembalikannya. Saat ini;
}
tes public void ()
{
  var theList = Daftar baru <string> ();
  theList.Add ("Fred");
  theList.Add ("George");
  theList.Add ("Percy");
  theList.Add ("Molly");
  theList.Add ("Ron");

  var enum1 = theList.GetEnumerator ();
  IEnumerator <string> enum2 = enum1;

  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum1));
  Debug.Print (testEnumerator (enum2));
  Debug.Print (testEnumerator (enum2));
}

Jika testEnumerator()metode ini meneruskan lokasi penyimpanan tipe nilai, itakan menerima contoh yang bidang publik dan privatnya disalin dari nilai yang diteruskan. Variabel lokal it2akan menyimpan instance lain yang bidangnya semua disalin it. Memanggil MoveNextpada it2tidak akan mempengaruhi it.

Jika kode di atas melewati lokasi penyimpanan tipe kelas, maka nilai yang diteruskan it,, dan it2, semua akan merujuk ke objek yang sama, dan dengan demikian memanggil MoveNext()salah satu dari mereka secara efektif akan memanggilnya pada mereka semua.

Perhatikan bahwa casting List<String>.Enumeratoruntuk IEnumerator<String>mengubahnya secara efektif dari tipe nilai ke tipe kelas. Tipe objek heap adalah List<String>.Enumeratortetapi perilakunya akan sangat berbeda dari tipe nilai dari nama yang sama.

supercat
sumber
+1 karena tidak menyebutkan ToString ()
JeffO
1
Ini semua tentang detail implementasi. Tidak perlu memaparkan ini kepada pengguna.
DeadMG
@DeadMG: Apa maksudmu? Perilaku yang dapat diamati dari suatu List<T>.Enumeratoryang disimpan sebagai secara List<T>.Enumeratorsignifikan berbeda dari perilaku yang disimpan dalam suatu IEnumerator<T>, di mana menyimpan nilai dari jenis sebelumnya ke lokasi penyimpanan dari kedua jenis akan membuat salinan dari keadaan pencacah, saat menyimpan nilai dari tipe yang terakhir ke lokasi penyimpanan yang juga dari tipe yang terakhir tidak akan membuat salinan.
supercat
Ya, tapi Objectmemiliki tidak ada hubungannya dengan fakta bahwa.
DeadMG
@DeadMG: Maksud saya adalah bahwa turunan tipe dari turunan System.Int32juga merupakan turunan dari System.Object, tetapi lokasi penyimpanan tipe System.Int32tidak memiliki System.Objectturunan maupun referensi ke satu.
supercat
2

Desain ini benar-benar ditelusuri kembali ke Smalltalk, yang saya lihat sebagian besar sebagai upaya mengejar orientasi objek dengan mengorbankan hampir semua dan semua masalah lainnya. Karena itu, cenderung (menurut saya) untuk menggunakan orientasi objek, bahkan ketika teknik lain mungkin (atau bahkan pasti) lebih unggul.

Memiliki hierarki tunggal dengan Object(atau sesuatu yang serupa) di root membuatnya cukup mudah (untuk satu contoh) untuk membuat kelas koleksi Anda sebagai koleksi Object, jadi sepele untuk koleksi berisi segala jenis objek.

Sebagai imbalan untuk keuntungan yang agak kecil ini, Anda mendapatkan banyak kerugian. Pertama, dari sudut pandang desain, Anda berakhir dengan beberapa ide yang benar-benar gila. Setidaknya menurut pandangan Jawa tentang alam semesta, apa kesamaan Ateisme dan Hutan? Bahwa mereka berdua memiliki kode hash! Apakah Peta adalah koleksi? Menurut Jawa, tidak, bukan itu!

Pada 70-an ketika Smalltalk dirancang, omong kosong semacam ini diterima, terutama karena tidak ada yang merancang alternatif yang masuk akal. Smalltalk diselesaikan pada 1980, dan pada 1983 Ada (yang termasuk obat generik) dirancang. Meskipun Ada tidak pernah mencapai jenis popularitas yang diprediksi oleh beberapa orang, obat generiknya cukup untuk mendukung koleksi objek dari jenis yang sewenang-wenang - tanpa kegilaan yang melekat pada hierarki monolitik.

Ketika Java (dan pada tingkat lebih rendah, .NET) dirancang, hierarki kelas monolitik mungkin dipandang sebagai pilihan "aman" - satu dengan masalah, tetapi sebagian besar masalah diketahui . Pemrograman generik, sebaliknya, adalah sesuatu yang hampir semua orang (bahkan saat itu) sadari setidaknya secara teoritis merupakan pendekatan yang jauh lebih baik untuk masalah ini, tetapi yang oleh banyak pengembang berorientasi komersial dianggap agak kurang dieksplorasi dan / atau berisiko (yaitu, dalam dunia komersial , Ada sebagian besar ditolak karena gagal).

Biar saya perjelas: hierarki monolitik adalah kesalahan. Alasan untuk kesalahan itu setidaknya bisa dimengerti, tetapi itu adalah kesalahan. Ini desain yang buruk, dan masalah desainnya meliputi hampir semua kode yang menggunakannya.

Untuk desain baru hari ini, bagaimanapun, tidak ada pertanyaan yang masuk akal: menggunakan hierarki monolitik adalah kesalahan yang jelas dan ide yang buruk.

Jerry Coffin
sumber
Layak disebutkan bahwa templat dikenal luar biasa dan berguna sebelum .NET dikirim.
DeadMG
Dalam dunia komersial, Ada adalah sebuah kegagalan, bukan karena verbositasnya, tetapi karena kurangnya antarmuka standar untuk layanan sistem operasi. Tidak ada API standar ke sistem file, grafik, jaringan, dll. Membuat pengembangan aplikasi 'host' menjadi sangat mahal.
kevin cline
@ kevincline: Saya mungkin seharusnya mengatakan itu sedikit berbeda - akibatnya Ada secara keseluruhan dianggap sebagai kegagalan karena kegagalannya di pasar. Menolak untuk menggunakan Ada adalah (IMO) cukup masuk akal - tetapi menolak untuk belajar darinya jauh lebih sedikit (paling-paling).
Jerry Coffin
@ Jerry: Saya pikir template C ++ mengadopsi ide-ide generik Ada, kemudian memperbaikinya dengan instantiasi implisit.
kevin cline
1

Apa yang ingin Anda lakukan sebenarnya menarik, sulit untuk membuktikan apakah itu salah atau benar sampai Anda selesai.

Berikut beberapa hal yang perlu dipikirkan:

  • Kapan Anda akan dengan sengaja melewatkan objek tingkat atas ini ke objek yang lebih spesifik?
  • Kode apa yang ingin Anda masukkan ke setiap kelas Anda?

Hanya itulah dua hal yang dapat diuntungkan dari root bersama. Dalam bahasa itu digunakan untuk mendefinisikan beberapa metode yang sangat umum dan memungkinkan Anda untuk melewati objek yang belum didefinisikan, tetapi itu tidak boleh berlaku untuk Anda.

Juga, dari pengalaman pribadi:

Saya menggunakan toolkit yang pernah ditulis oleh pengembang yang latar belakangnya adalah Smalltalk. Dia membuatnya sehingga semua "Data" kelasnya diperpanjang satu kelas dan semua metode mengambil kelas itu - sejauh ini sangat bagus. Masalahnya adalah kelas data yang berbeda tidak selalu dapat dipertukarkan, jadi sekarang editor dan kompiler saya tidak dapat memberi saya bantuan apa pun tentang apa yang harus diteruskan ke dalam situasi tertentu dan saya harus merujuk ke dokumennya yang tidak selalu membantu. .

Itu adalah perpustakaan yang paling sulit digunakan yang pernah saya tangani.

Bill K
sumber
0

Karena itulah cara OOP. Sangat penting untuk memiliki tipe (objek) yang dapat merujuk pada apa saja. Argumen tipe objek dapat menerima apa pun. Ada juga warisan, Anda dapat memastikan bahwa ToString (), GetHashCode () dll tersedia pada apa saja dan segalanya.

Bahkan Oracle telah menyadari pentingnya memiliki tipe dasar seperti itu dan berencana untuk menghapus primitif di Jawa dekat 2017

Dante
sumber
6
Ini bukan jalan OOP atau penting. Anda tidak memberikan argumen aktual selain "Itu bagus".
DeadMG
1
@DeadMG Anda dapat membaca argumen yang melewati kalimat pertama. Primitif berperilaku berbeda dari objek sehingga memaksa programmer untuk menulis banyak varian kode tujuan yang sama untuk objek dan primitif.
Dante
2
@DeadMG baik dia mengatakan itu berarti Anda dapat berasumsi ToString()dan GetType()akan ada di setiap objek. Mungkin perlu menunjukkan bahwa Anda dapat menggunakan variabel tipe objectuntuk menyimpan objek .NET.
JohnL
Juga, sangat mungkin untuk menulis tipe yang ditentukan pengguna yang dapat menyimpan referensi jenis apa pun. Anda tidak memerlukan fitur bahasa khusus untuk mencapainya.
DeadMG
Anda seharusnya hanya memiliki Obyek pada level yang berisi kode tertentu, Anda tidak boleh hanya memiliki satu untuk menyatukan grafik Anda. "Objek" sebenarnya mengimplementasikan beberapa metode penting dan bertindak sebagai cara untuk mengirimkan objek ke dalam perkakas di mana jenisnya bahkan belum dibuat.
Bill K