Saya telah belajar C # selama sekitar enam bulan terakhir dan sekarang saya mempelajari Jawa. Pertanyaan saya adalah tentang pembuatan instance (dalam kedua bahasa, sungguh) dan ini lebih dari: Saya bertanya-tanya mengapa mereka melakukannya dengan cara itu. Ambil contoh ini
Person Bob = new Person();
Apakah ada alasan bahwa objek tersebut ditentukan dua kali? Apakah akan ada something_else Bob = new Person()
?
Tampaknya jika saya mengikuti dari konvensi itu akan lebih seperti:
int XIsAnInt;
Person BobIsAPerson;
Atau mungkin salah satunya:
Person() Bob;
new Person Bob;
new Person() Bob;
Bob = new Person();
Saya kira saya ingin tahu apakah ada jawaban yang lebih baik daripada "itu hanya cara dilakukan".
java
c#
object-oriented
Jason Wohlgemuth
sumber
sumber
LivingThing
? Anda bisa menulisLivingThing lt = new Person()
. Cari warisan dan antarmuka.Person Bob
mendeklarasikan variabel tipe "referensi kePerson
" yang dipanggilBob
.new Person()
menciptakanPerson
objek. Referensi, variabel, dan objek adalah tiga hal berbeda!var bob = new Person();
?Person Bob();
mungkin di C ++ dan artinya hampir sama denganPerson Bob = Person();
Jawaban:
Ya, karena warisan. Jika:
Kemudian:
Bob juga orang, dan tentu saja, dia tidak ingin diperlakukan berbeda dari orang lain.
Selanjutnya, kita bisa memberkahi Bob dengan kekuatan super:
Jadi, demi sial, ia tidak akan tahan diperlakukan berbeda dari moderator lainnya. Dan dia suka menyelinap di sekitar forum untuk menjaga semua orang tetap di jalur sementara penyamaran:
Kemudian ketika dia menemukan beberapa poster 1 yang buruk, dia melepaskan jubah tembus pandang dan menerkam.
Dan kemudian dia bisa bertindak semua tidak bersalah dan hal-hal sesudahnya:
sumber
enum
.Mari kita ambil baris kode pertama Anda dan memeriksanya.
Yang pertama
Person
adalah spesifikasi tipe. Dalam C #, kita bisa membuang ini hanya dengan mengatakandan kompiler akan menyimpulkan tipe variabel Bob dari panggilan konstruktor
Person()
.Tetapi Anda mungkin ingin menulis sesuatu seperti ini:
Di mana Anda tidak memenuhi seluruh kontrak API Orang, tetapi hanya kontrak yang ditentukan oleh antarmuka
IPerson
.sumber
IPerson
contoh dalam kode saya untuk memastikan saya tidak sengaja menggunakan metode pribadi apa pun ketika saya menulis kode yang harus disalin / dapat dilestarikan keIPerson
implementasi lain .internal
?private
yang bermakna: metode pabrik yang merupakan bagian dari kelas yang dipakai. Dalam situasi saya, akses ke nilai-nilai pribadi harus menjadi pengecualian, bukan norma. Saya bekerja pada kode yang akan hidup lebih lama dari saya. Jika saya melakukannya dengan cara ini, bukan saja saya tidak mungkin menggunakan metode pribadi sendiri, tetapi ketika pengembang berikutnya menyalin / menempel ini beberapa lusin tempat dan pengembang setelah itu menyalinnya, itu mengurangi peluang bahwa seseorang melihat peluang untuk gunakan metode pribadi sebagai perilaku "normal".Sintaks ini cukup banyak warisan dari C ++, yang, omong-omong, memiliki keduanya:
dan
Yang pertama untuk membuat objek dalam lingkup saat ini, yang kedua untuk membuat pointer ke objek yang dinamis.
Anda pasti bisa
something_else Bob = new Person()
Anda melakukan dua hal yang berbeda di sini, menyatakan jenis variabel lokal
nums
dan Anda mengatakan Anda ingin membuat objek baru dari jenis 'Daftar' dan meletakkannya di sana.C # jenis setuju dengan Anda, karena sebagian besar waktu jenis variabel identik dengan apa yang Anda masukkan maka:
Dalam beberapa bahasa Anda melakukan yang terbaik untuk menghindari menyatakan jenis variabel seperti dalam F # :
sumber
new std::pair<int, char>()
, maka anggotafirst
dansecond
pasangan memiliki durasi penyimpanan otomatis, tetapi mereka mungkin dialokasikan pada heap (sebagai anggotapair
objek durasi penyimpanan dinamis ).Ada perbedaan besar antara
int x
danPerson bob
. Sebuahint
adalahint
merupakanint
dan harus selalu menjadiint
dan tidak pernah bisa menjadi apa pun selain sebuahint
. Bahkan jika Anda tidak menginisialisasiint
ketika Anda mendeklarasikannya (int x;
), itu masih merupakanint
set ke nilai default.Ketika Anda menyatakan
Person bob
, bagaimanapun, ada banyak fleksibilitas untuk apa namabob
sebenarnya merujuk pada waktu tertentu. Itu bisa merujuk kePerson
, atau bisa merujuk ke beberapa kelas lain, misalnyaProgrammer
, berasal dariPerson
; bahkan bisa jadinull
, mengacu pada tidak ada objek sama sekali.Sebagai contoh:
Para perancang bahasa tentu bisa membuat sintaksis alternatif yang akan menyelesaikan hal yang sama dengan
Person carol = new Person()
simbol yang lebih sedikit, tetapi mereka masih harus mengijinkanPerson carol = new Person()
(atau membuat aturan aneh yang membuat salah satu dari empat contoh di atas ilegal). Mereka lebih peduli dengan menjaga bahasa "sederhana" daripada menulis kode yang sangat ringkas. Itu mungkin memengaruhi keputusan mereka untuk tidak memberikan sintaksis alternatif yang lebih pendek, tetapi bagaimanapun juga, itu tidak perlu dan mereka tidak menyediakannya.sumber
Kedua deklarasi bisa berbeda tetapi seringkali sama. Pola yang umum dan direkomendasikan di Jawa terlihat seperti:
Variabel-variabel ini
list
danmap
dideklarasikan menggunakan antarmukaList
danMap
sementara kode instantiate implementasi spesifik. Dengan cara ini, sisa kode hanya tergantung pada antarmuka dan mudah untuk memilih kelas implementasi yang berbeda untuk instantiate, sepertiTreeMap
, karena sisa kode tidak dapat bergantung pada bagianHashMap
API yang ada di luarMap
antarmuka.Contoh lain di mana kedua jenis berbeda adalah dalam metode pabrik yang mengambil subclass spesifik untuk instantiate, kemudian mengembalikannya sebagai jenis dasar sehingga penelepon tidak perlu mengetahui detail implementasi, misalnya pilihan "kebijakan".
Ketik inferensi dapat memperbaiki redundansi kode sumber. Misalnya di Jawa
akan membangun jenis Daftar yang benar berkat ketikkan inferensi dan deklarasi
Dalam beberapa bahasa, ketik inferensi lebih jauh, misalnya dalam C ++
sumber
bob
, tidakBob
. Ini menghindari banyak ambiguitas misalnya package.Class vs Class.variable.clazz
.clazz
digunakan karenaclass
kata kunci sehingga tidak dapat digunakan sebagai pengidentifikasi.Class
adalah pengidentifikasi yang benar-benar valid.cLaSs
,cLASS
dancLASs
.Dalam kata-kata awam:
var = new Process()
Anda tidak mendeklarasikan variabel terlebih dahulu.sumber
Ini juga tentang tingkat kontrol atas apa yang terjadi. Jika deklarasi objek / variabel secara otomatis memanggil konstruktor, misalnya, jika
adalah otomatis sama dengan
maka Anda tidak akan pernah dapat menggunakan (misalnya) metode pabrik statis untuk membuat instance objek daripada konstruktor default, yaitu, ada kalanya Anda tidak ingin memanggil konstruktor untuk instance objek baru.
Contoh ini dijelaskan di Joshua Bloch 's Jawa Efektif (Item 1 cukup ironis!)
sumber