Filsafat jawa edisi terbaru. Bruce Eckel - Filosofi Java3. Pemrograman Sisi Server

  • 12.04.2020

Untuk mengubah dokumen default, edit file "blank.fb2" secara manual.

Kata Pengantar 13

Java SE5 dan SE6 14

Terima kasih 14

Bab 1 Pengenalan Objek 17

Pengembangan abstraksi 18

Objek memiliki antarmuka 20

Fasilitas ini menyediakan layanan 22

Implementasi Tersembunyi 23

Implementasi penggunaan kembali 24

Warisan 25

Objek yang Dapat Dipertukarkan dan Polimorfisme 29

Hirarki Akar Tunggal 33

Wadah 33

Jenis parameter 35

Penciptaan, penggunaan benda dan masa hidupnya 36

Penanganan Pengecualian: Menangani Kesalahan 38

Eksekusi paralel 38

Java dan Internet 39

Bab 2. Semuanya adalah objek 48

Semua objek harus dibuat secara eksplisit 49

Objek tidak perlu dihapus 53

Membuat tipe data baru 54

Metode, Argumen, dan Nilai Pengembalian 56

Membuat Program Java 58

Kata kunci statis 60

Program Java 61 pertama kami

Komentar dan dokumentasi tersemat 64

Gaya desain program 70

Bab 3 Operator 71

Perintah cetak sederhana 71

Pernyataan Java 72

Literal 82

Java tidak memiliki sizeof() 92

Lanjutkan 100

Bab 4 Struktur Kontrol 101

Sintaks untuk setiap 105

istirahat dan lanjutkan 108

Perintah buruk ke 109

Lanjutkan 115

Bab 5 Inisialisasi dan Penghentian 116

Konstruktor menjamin inisialisasi 116

Metode Kelebihan Beban 118

Pembersihan: finalisasi dan pengumpulan sampah 130

Menginisialisasi anggota kelas 137

Inisialisasi konstruktor 140

Inisialisasi larik 146

Lanjutkan 151

Bab 6 Kontrol Akses 152

Paket sebagai modul perpustakaan 153

Penentu Akses Java 159

Antarmuka dan Implementasi 163

Akses ke kelas 164

Lanjutkan 167

Bab 7 Menggunakan Kembali Kelas 169

Sintaks komposisi 170

Sintaks pewarisan 172

Delegasi 176

Menggabungkan Komposisi dan Warisan 178

Komposisi versus warisan 184

Konversi Tipe Ke Atas 186

Kata kunci terakhir 188

Lanjutkan 197

Bab 8. Polimorfisme 198

Sekali lagi tentang transformasi ke atas. . . > 199

Fitur 201

Konstruktor dan Polimorfisme 208

Kovarians tipe kembali 216

Pengembangan dengan warisan 217

Lanjutkan 220

Bab 9 Antarmuka 221

Kelas dan metode abstrak 221

Antarmuka 224

Memisahkan Antarmuka dari Implementasi 227

Memperluas Antarmuka Melalui Warisan 233

Antarmuka sebagai sarana adaptasi 236

Antarmuka bersarang 239

Antarmuka dan pabrik 242

Lanjutkan 244

Bab 10 Kelas Dalam 245

Membuat Kelas Dalam 245

Komunikasi dengan kelas eksternal 246

Konstruksi .this dan .new 248

Kelas dalam dan upcasting 249

Kelas internal yang tidak disebutkan namanya 253

Kelas dalam: mengapa? 261

Warisan dari Kelas Dalam 272

Apakah mungkin untuk mengganti kelas dalam? 272

Kelas Dalam Lokal 274

Lanjutkan 276

Bab 11 Koleksi Objek 277

Wadah yang Diparameterisasi dan Diketik 277

Konsep Inti 280

Menambahkan grup elemen 281

Iterator 288

Tetapkan 294

Antrian 298

Antrian Prioritas 299

Koleksi dan Iterator 301

Idiom "adaptor metode" 306

Lanjutkan 309

Bab 12 Menangani Kesalahan dan Pengecualian 310

Pengecualian utama 310

Menangkap 312 Pengecualian

Membuat pengecualian Anda sendiri 314

Spesifikasi Pengecualian 319

Menangkap Pengecualian Sewenang-wenang 320

Pengecualian Standar Java 328

Pemutusan dengan akhirnya 330

Menggunakan akhirnya dengan pengembalian 334

Batasan saat menggunakan pengecualian 336

Konstruktor 339

Identifikasi pengecualian 343

Solusi alternatif 344

Lanjutkan 351

Bab 13 Jenis Informasi 352

Kebutuhan untuk Inferensi Tipe Dinamis (RTTI) 352

Pendaftaran pabrik 372

Refleksi: informasi kelas dinamis 376

Mediator dinamis 380

Objek dengan keadaan tak tentu 384

Antarmuka dan Informasi Jenis 390

Lanjutkan 394

Bab 14 Parameterisasi 397

Parameterisasi sederhana 398

Antarmuka berparameter 404

Metode Parameter 407

Membangun model kompleks 419

Pembatasan 437

Metakarakter 440

Lanjutkan 452

Bab 15 Array 454

Fitur array 454

Array sebagai objek 456

Array kembali 458

Array multidimensi 460

Array dan parameterisasi 463

Membuat data uji 465

Membuat Array Menggunakan Generator 470

Perangkat Pembantu Array 474

Lanjutkan 482

Bab 16 Sistem I/O Java 483

File 484 kelas

Masukan dan keluaran 489

Menambahkan Atribut dan Antarmuka 491

Kelas Pembaca dan Penulis 494

RandomAccessFile: dengan sendirinya 497

Penggunaan umum aliran I/O 498

Pembaca dan Penulis File 505

Standar I/O 507

I/O baru (nio) 510

Kompresi data 531

Membuat serial objek 536

Preferensi 553

Lanjutkan 555

Bab 17 Eksekusi Paralel 557

Kelas benang 559

Artis 561

Berbagi sumber daya 578

Komunikasi antar utas 598

Saling memblokir 602

Komponen perpustakaan baru 607

Hitung Mundur Kait 607

CyclicBarrier 609

PrioritasBlockingAntrian 614

Semaphore 619

Pemodelan 624

Lanjutkan 629

Indeks abjad 631

Pengenalan Objek

Kami membedah alam, mengubahnya menjadi konsep, dan memberikan makna kepadanya, seperti yang kami lakukan dalam banyak hal, karena kami semua adalah pihak dalam kesepakatan yang sah dalam masyarakat yang terikat oleh ucapan, dan yang ditetapkan dalam struktur bahasa . .. Kami tidak dapat berkomunikasi sama sekali, kecuali dengan menyetujui organisasi dan klasifikasi data yang ditetapkan oleh perjanjian ini.

Benyamin Lee Worf (1897-1941)

Kami berutang munculnya revolusi komputer ke mesin. Oleh karena itu, bahasa pemrograman kami mencoba untuk lebih dekat dengan mesin ini.

Tetapi pada saat yang sama, komputer bukanlah mekanisme yang begitu banyak karena mereka adalah sarana untuk memperkuat pemikiran ("sepeda untuk pikiran," seperti yang suka dikatakan Steve Jobs), dan sarana ekspresi diri lainnya. Akibatnya, alat pemrograman kurang condong ke mesin dan lebih ke pikiran kita, serta bentuk ekspresi aspirasi manusia lainnya, seperti sastra, lukisan, patung, animasi, dan bioskop. Pemrograman berorientasi objek (OOP) adalah bagian dari mengubah komputer menjadi kendaraan untuk ekspresi diri.

Bab ini akan memperkenalkan Anda pada dasar-dasar OOP, termasuk melihat metode utama pengembangan perangkat lunak. Itu, dan buku pada umumnya, mengasumsikan bahwa Anda memiliki pengalaman pemrograman dalam bahasa prosedural, belum tentu C. Jika Anda merasa bahwa sebelum membaca buku ini Anda kurang pengetahuan tentang pemrograman dan sintaks C, gunakan seminar multimedia Thinking in C. diunduh dari situs web

Pada bulan Maret tahun lalu, dia melamar ke cabang besar perusahaan internasional di Samara (ya. Saya memiliki banyak kesombongan dan ambisi sejak kecil). Waktu itu saya tahu html, css, java, javascript (dasar), pascal, visualbasic6, mysql query, php, Ide umum:c++. Saya sama sekali tidak tahu bahasa Jawa. Mereka menawari saya pekerjaan sebagai perancang tata letak, tetapi saya menolaknya. Hanya sebagai pemrogram! Kemudian mereka memberi saya daftar:

Bruce Eckel Thinking in Java (Terjemahan Rusia edisi ke-2 atau asli edisi ke-4 - baca keduanya)
-Steve McConnell - kode sempurna.
- Geng empat - Desain pola. (ini hampir ABC dari OOP)
-jelaskan mungkin tentang perbedaan antara j2se dan j2ee.

pada bulan Desember kebutuhan muncul. mendapat pekerjaan di web-studio Samara kecil. segera jelas bahwa ini adalah scammers, tetapi pekerjaan apa pun yang dapat saya tunjukkan kepada pemberi kerja di masa depan diperlukan. mereka tidak membayar untuk membayar (walaupun semua telinga dimakan dengan janji), tetapi kode dibawa ke standar desain, dan yang paling penting, mereka mengajarkan ke mana harus mencari dan apa yang harus dicari jika terjadi kesalahan, apa sedikit hal-hal yang mudah untuk dilewatkan.

Selain literatur di atas, saya mengambil kursus intuisi (sekarang saya mengerti bahwa itu konyol dalam ruang lingkupnya, tetapi pada prinsipnya ada dasar-dasarnya di sana)

Pada akhir Februari, saya mengirimkan kembali resume saya dan menerima undangan untuk wawancara. Total ada 6 wawancara dan berlangsung selama 1,5 bulan. Dua di antaranya ditahan melalui tautan video dengan Moskow. Seluruh gambar itu mengingatkan pada film "Come Tomorrow". Tapi pada akhirnya, saya mendapat tawaran pekerjaan. Kontrak itu dibuat untuk pekerjaan paruh waktu, karena. Saya tidak memiliki gelar saat itu. Bulan lalu saya menerima diploma dan kontrak diperpanjang untuk satu waktu penuh.

Posisi Soft-Engineer saat ini. Gajinya lebih dari memuaskan. Kemarin, sehubungan dengan transisi ke pekerjaan penuh waktu, mereka menaikkannya sebesar 30%.

Bahkan di kantor penipu itu mereka meminta contoh pekerjaan. Saya mempresentasikan pekerjaan yang dilakukan oleh saya secara freelance. Bahkan karya dalam bahasa lain selalu jauh lebih baik daripada tidak sama sekali.

Ps: Diploma biru FISIKA. Saya sepenuhnya otodidak, jadi semuanya ada di tangan Anda. Saya hanya memiliki Bahasa Inggris dari sekolah Gratis (7 jam seminggu). meskipun orang Amerika yang datang kepada kami selama perjalanannya keliling dunia tidak mengenalnya dengan baik. Saya hampir tidak mengerti setengahnya karena aksennya. tapi ini tidak begitu penting di departemen saya. semua dokumentasi dalam bahasa Inggris - Anda akan belajar bahkan jika Anda tidak tahu)))))

Terima kasih khusus untuk forum ini. Saya benar-benar belajar di sini- setiap hari mengajarkan semua topik yang ditemui)

PERPUSTAKAAN PROGRAMMER

Bruce Eckel

edisi ke-4

(^PPTER

Moskow - St. Petersburg - Nizhny Novgorod - Voronezh Rostov-on-Don - Yekaterinburg - Samara - Novosibirsk Kyiv - Kharkov - Minsk

BBK 32,973 2-018,1

Ekel B.

E38 Filsafat Jawa. perpustakaan pemrogram. edisi ke-4 - St. Petersburg: Peter, 2009. - 640 e.: sakit. - (Seri "Perpustakaan Programmer").

ISBN 978-5-388-00003-3

Java tidak dapat dipahami dengan melihatnya hanya sebagai kumpulan dari beberapa harakureshki - perlu untuk memahami tugas bahasa ini sebagai masalah khusus pemrograman secara umum. r3ia adalah buku tentang masalah pemrograman: mengapa mereka menjadi masalah dan pendekatan apa yang digunakan Java untuk menyelesaikannya. Oleh karena itu, fitur bahasa yang dibahas dalam setiap bab terkait erat dengan bagaimana mereka digunakan untuk memecahkan masalah tertentu.

Buku ini, yang telah bertahan dari banyak cetakan ulang dalam versi aslinya, karena penyajiannya yang mendalam dan filosofis tentang seluk-beluk bahasa, dianggap sebagai salah satu manual terbaik untuk programmer Java.

BBK 32.973.2-018.1 UDC 004.3

Hak penerbitan diperoleh melalui kesepakatan dengan Prentice Hall PTR.

Seluruh hak cipta. Tidak ada bagian dari buku ini yang boleh direproduksi dalam bentuk apapun tanpa izin tertulis dari pemegang hak cipta.

Informasi yang terkandung dalam buku ini telah diperoleh dari sumber yang diyakini oleh penerbit dapat diandalkan. Namun, mengingat kemungkinan kesalahan manusia atau teknis, penerbit tidak dapat menjamin keakuratan dan kelengkapan mutlak dari informasi yang diberikan dan tidak bertanggung jawab atas kemungkinan kesalahan berhubungan dengan penggunaan buku.

ISBN 978-0131872486 © Prentice Hall PTR, 2006

ISBN 978-5-388-00003-3 © Terjemahan ke dalam bahasa Rusia oleh Peter Press LLC, 2009

© Publikasi dalam bahasa Rusia, desain oleh Piter Press LLC, 2009

Kata Pengantar.................................13

Java SE5 dan SE6 ...................................14

Ucapan Terima Kasih .................................14

Bab 1 Pengenalan Objek ..................................17

Perkembangan abstraksi .................................18

Sebuah objek memiliki antarmuka ..................................20

Fasilitas ini menyediakan layanan ..................................22

Implementasi Tersembunyi.............................23

Implementasi Penggunaan Kembali ...................................24

Warisan ...................................25

Objek yang Dapat Dipertukarkan dan Polimorfisme..................................29

Hirarki Akar Tunggal ..................................33

Wadah ..................................33

Jenis Parameter.................................35

Penciptaan, penggunaan benda dan waktu hidupnya .................................36

Menangani Pengecualian: Menangani Kesalahan..................................38

Eksekusi Paralel ..................................38

Jawa dan Internet ..................39

Ringkasan..................................47

Bab 2 Semuanya adalah Obyek ..................................48

Semua objek harus dibuat secara eksplisit ..................................49

Objek tidak perlu dihapus...................................53

Membuat Tipe Data Baru...................................54

Metode, Argumen, dan Nilai Pengembalian ..................................56

Membuat Program Java.................................58

Kata kunci statis ..................................60

Program Java pertama kami.................................61

Komentar dan Dokumentasi Tertanam...................................64

Gaya pemrograman ........................................70

Ringkasan..................................70

Bab 3. Operator .................................71

Perintah Cetak Sederhana............................. 71

Pernyataan Java............................72

Literal...................................82

Java tidak memiliki sizeof() ................................................92

Lanjutkan...................100

Bab 4 Struktur Kontrol ..................101

Sintaks untuk masing-masing ..................................105

kembali, ...................................107

istirahat dan lanjutkan ...................................108

Perintah goto yang buruk ........................109

Ringkasan................................................115

Bab 5. Inisialisasi dan Penghentian ..................116

Inisialisasi Jaminan Konstruktor.................................116

Metode Overloading.................................118

Pembersihan: Finalisasi dan Pengumpulan Sampah.................................130

Menginisialisasi Anggota Kelas.................................137

Inisialisasi konstruktor ...................................140

Inisialisasi Array..................................146

Ringkasan.............................151

Bab 6 Kontrol Akses ........................152

Paket sebagai modul perpustakaan ..................................153

Penentu akses Java..................................159

Antarmuka dan Implementasi .................................163

Mengakses Kelas ..................................164

Ringkasan...................................167

Bab 7 Menggunakan Kembali Kelas .................................169

Sintaks Komposisi..................................170

Sintaks Warisan ..................................172

Delegasi...................................176

Menggabungkan Komposisi dan Warisan............................178

Komposisi Versus Warisan ..................................184

dilindungi.................................185

Konversi Tipe Ke Atas.................................................186

Kata Kunci Akhir ...................188

Ringkasan..................................197

Bab 8 Polimorfisme

Sekali lagi tentang transformasi ke atas. . . >................199

Fitur...................................201

Konstruktor dan Polimorfisme ..................................208

Kovarians tipe pengembalian................................................216

Mendesain dengan Warisan................................217

Lanjutkan ..................................220

Bab 9. Antarmuka.........................221

Kelas dan Metode Abstrak................................................221

Antarmuka ..................................224

Memisahkan Antarmuka dari Implementasi..................................227

Memperluas Antarmuka Melalui Warisan .................................233

Antarmuka sebagai sarana adaptasi ..................................236

Antarmuka Bersarang.................................239

Antarmuka dan Pabrik.................................242

Lanjutkan ..................................244

Bab 10 Kelas Dalam.................................245

Membuat Kelas Dalam..................................245

Komunikasi dengan kelas eksternal.................................246

Konstruksi .this dan .new............................248

Kelas Dalam dan Konversi Ke Atas.........................249

Kelas Dalam Tanpa Nama ..................253

Kelas dalam: mengapa? .................................. 261

Warisan dari Kelas Dalam ..................................272

Apakah mungkin untuk mengganti kelas dalam?......................272

Kelas Dalam Lokal.................................274

Ringkasan...................................276

Bab 11 Koleksi Objek ..................................277

Wadah yang Diparameterisasi dan Diketik .................................277

Konsep Dasar..................................280

Menambahkan Grup Elemen ..................................281

Daftar.................................285

Iterator..................................288

Daftar Tertaut..................................291

Tumpukan..................................292

Banyak................................................. 294

Peta.................................296

Antrian..................................298

Antrian Prioritas..................................299

Koleksi dan Iterator..................................301

Idiom "adaptor metode" .........................306

Lanjutkan ..................................309

Bab 12 Menangani Kesalahan dan Pengecualian...................310

Pengecualian Utama ............................. 310

Menangkap Pengecualian.................................312

Membuat Pengecualian Anda Sendiri.................................314

Spesifikasi Pengecualian.................................319

Menangkap Pengecualian Sewenang-wenang..................................320

Pengecualian Java Standar.................................328

Mengakhiri dengan akhirnya ......................330

Menggunakan akhirnya dengan pengembalian ........................334

Pembatasan Penggunaan Pengecualian...................................336

Konstruktor..................................339

Identifikasi Pengecualian.................................343

Solusi Alternatif............................344

Ringkasan..................................351

Bab 13 Jenis Informasi .................................352

Kebutuhan untuk Inferensi Tipe Dinamis (RTTI) .........352

Pendaftaran pabrik .................................372

Refleksi: informasi dinamis tentang sebuah kelas................................376

Perantara Dinamis..................................380

Objek dengan keadaan tak tentu...................................384

Antarmuka dan Informasi Jenis ..................................390

Lanjutkan.................................394

Bab 14

Parametrisasi sederhana.................................398

Antarmuka berparameter ..................................404

Metode Parameterisasi...................407

Membangun Model Kompleks.................................419

Pembatasan..................................437

Metakarakter..................................440

Lanjutkan..................452

Bab 15. Array ..................................454

Fitur Array ..................................454

Array sebagai Obyek.................................456

Mengembalikan Array.................................458

Array multidimensi .................................460

Array dan Parameterisasi ..................................463

Membuat Data Uji.............................465

Membuat Array Menggunakan Generator..................470

Perangkat Pembantu Array ..................................474

Lanjutkan..................482

Bab 16 Sistem I/O Java.................................483

Kelas file..................................484

Masukan dan Keluaran...................................489

Menambahkan Atribut dan Antarmuka ..................................491

Kelas Pembaca dan Penulis ..................................494

RandomAccessFile: dengan sendirinya..................497

Penggunaan Umum Aliran I/O.................................498

Pembaca dan Penulis File ..................................505

Saya mungkin tidak salah dalam berasumsi bahwa sebagian besar pelajar Java mulai melakukannya dengan bantuan buku terkenal Bruce Eckel: "Berpikir di Jawa", yang dikenal dalam edisi Rusia sebagai "Filsafat Jawa". Sayangnya di dalam format elektronik(dalam bahasa Rusia) edisi ke-2 buku ini adalah yang paling banyak didistribusikan, berdasarkan versi Java 1.1, yang telah lama kehilangan relevansinya. Inovasi yang muncul di versi Java berikutnya (dan terutama di Java SE5) sangat signifikan, yang menyebabkan revisi serius buku dalam edisi keempat (terjemahan yang diterbitkan dalam bahasa Rusia). Namun, dalam format elektronik yang mudah dibaca (dan yang paling penting - untuk pencarian cepat), versi Rusia dari publikasi ini tidak ada. Oleh karena itu, saya memutuskan untuk mengisi celah ini dan menghasilkan versi lengkap dari buku populer ini dalam format "wikibook". Saya percaya bahwa informasi ini akan menarik dan berguna tidak hanya untuk pelajar bahasa, tetapi juga untuk semua orang yang bekerja di Java karena banyaknya contoh bagus yang menggambarkan hampir semua aspek pemrograman dalam bahasa ini. Terutama dalam hal fitur Java yang jarang digunakan.

buku wiki "Filsafat Jawa" diposting di:

"Musim Semi Beraksi"

Buku dari seri "..... dalam Aksi"(biasanya dalam format PDF dan biasanya dalam bahasa Inggris) memang sepatutnya populer di kalangan tertentu :) Di antara mereka ada juga Talmud yang luas, seperti "JSTL beraksi"(mudah dibaca dan dengan pengetahuan bahasa Inggris yang moderat, tetapi cocok untuk peran referensi yang baik tentang topik), dan kerajinan yang lebih sederhana, seperti Struts dalam Aksi("Tidak semuanya emas..."). Buku "Musim Semi Beraksi" dalam daftar ini masih dari kategori "kelas berat", dan dalam setiap arti kata. Membacanya tanpa fasih berbahasa Inggris mungkin tidak mudah. Dan intinya bukan kerumitan materi yang disajikan (tidak rumit), tetapi kenyataan bahwa ternyata - terlalu "artistik Inggris", atau sesuatu .... Penuh penyimpangan liris, ekspresi bersayap, permainan kata-kata dan bla bla bla lainnya, penulis bahasa, dengan cepat mengubah membaca panduan ini (dalam bahasa aslinya) menjadi proses yang membosankan. Tetapi di sisi lain, ini memungkinkan Anda untuk mengetahui bahwa kata "seri"(biasanya - "menggambar") dapat digunakan dalam arti "ekstrak dari" (lit. - "tarik, seret"). Akibatnya (dengan mempertimbangkan gaya presentasi umum yang diadopsi dalam buku) untuk memahami arti yang tepat frase seperti: "... musim semi menggambar data ini ...", itu terjadi pada saat yang sama - dan itu tidak mudah, dan itu sangat diperlukan. Oleh karena itu, pembaca bab-bab yang belum saya terjemahkan harus memutuskan sendiri apa yang diinginkan penulis dalam kasus seperti itu: mengekspresikan diri mereka secara puitis tentang pembuatan (rekaman) file, atau bercanda menceritakan tentang membacanya.

Buku ini telah saya ubah dari PDF menjadi wikibook sebagai referensi cepat untuk penggunaan pribadi saya. Oleh karena itu, terjemahannya tidak total, tetapi hanya di tempat-tempat yang cukup antusias. Bab-bab selanjutnya hanya diberikan dalam bentuk yang nyaman untuk pencarian cepat. Itu diterbitkan, SEGALANYA dalam bentuk - "sebagaimana adanya", dan Anda tidak boleh menyalahkan kualitas teks Rusia ... Saya bukan penerjemah profesional, dan saya tidak memiliki editor sastra. Mungkin saya akan mengecewakan seseorang dengan fakta bahwa saya tidak menerjemahkan beberapa tempat dan bab buku (dan saya bahkan tidak berencana untuk menerjemahkannya), tetapi perlu untuk meninggalkan cadangan untuk generasi mendatang.

buku wiki "Musim semi beraksi " diposting di:

PENGANTAR OBJEK

Kami berutang munculnya revolusi komputer ke mesin. Oleh karena itu, bahasa pemrograman kami mencoba untuk lebih dekat dengan mesin ini.

Tetapi pada saat yang sama, komputer bukanlah mekanisme, tetapi sarana untuk memperkuat pemikiran ("sepeda untuk pikiran", seperti yang suka dikatakan Steve Jobs), dan sarana ekspresi diri lainnya. Akibatnya, alat pemrograman kurang condong ke mesin dan lebih ke pikiran kita, serta bentuk ekspresi aspirasi manusia lainnya, seperti sastra, lukisan, patung, animasi, dan bioskop. Pemrograman berorientasi objek (OOP) adalah bagian dari mengubah komputer menjadi media ekspresi diri.

Bab ini akan memperkenalkan Anda pada dasar-dasar OOP, termasuk melihat teknik pemrograman dasar. Itu, dan buku secara umum, mengasumsikan bahwa Anda memiliki pengalaman pemrograman dalam bahasa prosedural, belum tentu C.

Bab ini berisi persiapan dan bahan tambahan. Banyak pembaca lebih suka membayangkan gambaran besarnya terlebih dahulu, dan baru kemudian memahami seluk-beluk OOP. Oleh karena itu, banyak ide dalam bab ini berfungsi untuk memberi Anda pemahaman yang kuat tentang OOP. Namun, banyak orang tidak memahami gagasan umum sampai mereka melihat secara spesifik bagaimana segala sesuatunya bekerja; orang-orang seperti itu sering terjebak dalam istilah umum, tanpa contoh di depan mereka. Jika Anda salah satu dari yang terakhir dan ingin memulai dengan dasar-dasar bahasa, Anda dapat melompat ke bab berikutnya - melewatkan bab ini tidak akan menjadi hambatan untuk menulis program atau belajar bahasa. Namun, Anda harus kembali ke bab ini nanti untuk memperluas wawasan Anda dan memahami mengapa objek begitu penting dan di mana mereka cocok dengan desain program.

Perkembangan abstraksi

Semua bahasa pemrograman dibangun di atas abstraksi. Mungkin kesulitan tugas yang harus diselesaikan secara langsung tergantung pada jenis dan kualitas abstraksi. Dengan "ketik" yang saya maksud: "Apa sebenarnya yang kita abstraksi?" Bahasa assembly adalah abstraksi kecil dari komputer yang menjalankannya. Banyak yang disebut bahasa "perintah" yang dibuat setelahnya (seperti Fortran, BASIC dan C) adalah abstraksi dari tingkat berikutnya. Bahasa-bahasa ini memiliki keunggulan signifikan dibandingkan bahasa rakitan, tetapi abstraksi dasarnya masih membuat Anda berpikir tentang struktur komputer daripada masalah yang sedang dipecahkan. Pemrogram harus membangun hubungan antara model mesin (dalam "ruang solusi", yang mewakili tempat di mana solusi diimplementasikan - misalnya, komputer) dan model masalah yang akan dipecahkan (dalam "ruang masalah" , yang merupakan tempat terjadinya masalah - misalnya, area yang diterapkan). Membangun koneksi membutuhkan upaya terlepas dari bahasa pemrograman yang sebenarnya; hasilnya adalah program yang sulit untuk ditulis dan sulit untuk dipelihara. Tidak hanya itu, ia juga menciptakan seluruh industri "metodologi pemrograman".

Alternatif untuk memodelkan mesin adalah memodelkan masalah yang sedang dipecahkan. Bahasa awal seperti PELAT dan APL, memilih pendekatan khusus untuk memodelkan dunia sekitar ("Semua masalah diselesaikan dengan daftar" atau "Algoritma menyelesaikan semuanya", masing-masing). PROLOG memperlakukan semua masalah sebagai rantai solusi. Bahasa dibuat untuk pemrograman berdasarkan sistem batasan, dan bahasa khusus di mana pemrograman dilakukan dengan memanipulasi struktur grafis (cakupan yang terakhir ternyata terlalu sempit). Masing-masing pendekatan ini bagus di area tertentu dari masalah yang harus dipecahkan, tetapi begitu Anda meninggalkan area ini, menjadi sulit untuk menggunakannya.

Pendekatan objek melangkah lebih jauh dengan menyediakan programmer dengan sarana untuk mewakili tugas di ruangnya. Pendekatan ini cukup umum dan tidak membatasi jenis masalah yang sedang dipecahkan. Elemen-elemen ruang masalah dan representasinya dalam ruang solusi disebut "objek". (Anda mungkin memerlukan objek lain yang tidak memiliki analog di ruang masalah.) Idenya adalah bahwa program dapat beradaptasi dengan spesifik masalah dengan membuat jenis objek baru sehingga saat membaca kode yang memecahkan masalah, Anda secara bersamaan melihat kata-kata, menggambarkan dirinya. Ini adalah abstraksi yang lebih fleksibel dan kuat, melampaui semua yang ada sebelumnya dalam kemampuannya. Beberapa perancang bahasa percaya bahwa pemrograman berorientasi objek dengan sendirinya tidak cukup untuk menyelesaikan semua masalah pemrograman, dan menganjurkan kombinasi paradigma pemrograman yang berbeda dalam satu bahasa. Bahasa seperti itu disebut multi-paradigma(multiparadigma). Lihat buku Timothy Budd Pemrograman Multiparadigma di Leda (Addison-Wesley, 1995).. Dengan demikian, OOP memungkinkan Anda untuk mendeskripsikan tugas dalam konteks tugas itu sendiri, dan bukan dalam konteks komputer tempat solusi akan dieksekusi. Namun, koneksi dengan komputer masih dipertahankan. Setiap objek seperti komputer kecil; ia memiliki status dan operasi yang memungkinkannya. Analogi seperti itu sangat cocok dengan dunia luar, yaitu “realitas yang diberikan kepada kita dalam bentuk objek” yang memiliki karakteristik dan perilaku.

Alan Kay merangkum dan menyimpulkan lima fitur utama bahasa obrolan ringan- bahasa berorientasi objek pertama yang sukses, salah satu pendahulunya Jawa. Karakteristik ini mewakili pendekatan akademis "murni", untuk pemrograman berorientasi objek:

  • Semuanya adalah objek. Pikirkan sebuah objek sebagai variabel halus; itu menyimpan data, tetapi Anda dapat "meminta" suatu objek, memintanya untuk melakukan operasi pada dirinya sendiri. Secara teoritis, secara mutlak setiap komponen dari masalah yang sedang dipecahkan (anjing, bangunan, layanan, dll.) dapat direpresentasikan sebagai objek.
  • Program adalah sekelompok objek yang saling memberi tahu apa yang harus dilakukan melalui pesan. Untuk membuat permintaan ke suatu objek, Anda "mengirimnya pesan". Lebih visual, pesan dapat direpresentasikan sebagai panggilan ke metode milik objek tertentu.
  • Setiap objek memiliki "memori" sendiri yang terdiri dari objek lain. Dengan kata lain, Anda membuat objek baru dengan memasukkan objek yang ada ke dalamnya. Dengan demikian, dimungkinkan untuk membangun program kompleks yang sewenang-wenang, menyembunyikan kompleksitas keseluruhan di balik kesederhanaan objek individu.
  • Setiap objek memiliki tipe. Dalam istilah lain, setiap objek adalah turunan dari kelas, di mana "kelas" setara dengan kata "tipe". Perbedaan paling penting antar kelas justru terletak pada jawaban atas pertanyaan: “Pesan apa yang dapat dikirim ke suatu objek?”
  • Semua objek dari tipe tertentu dapat menerima pesan yang sama. Seperti yang akan segera kita lihat, ini adalah keadaan yang sangat penting. Karena objek bertipe "lingkaran" juga merupakan objek bertipe "bentuk", memang benar bahwa "lingkaran" pasti mampu menerima pesan untuk "bentuk". Dan ini berarti Anda dapat menulis kode untuk bentuk dan memastikan bahwa kode itu akan berfungsi untuk semua yang termasuk dalam konsep bentuk. Pertukaran adalah salah satu konsep yang paling kuat di OOP.

Booch menawarkan deskripsi objek yang lebih ringkas:

Suatu objek memiliki keadaan, perilaku, dan kepribadian.

Intinya adalah bahwa suatu objek dapat memiliki data internal (yang merupakan keadaan objek), metode (yang mendefinisikan perilaku), dan setiap objek dapat dibedakan secara unik dari objek lain - lebih khusus lagi, setiap objek memiliki alamat unik di pikiran Hal ini benar dengan beberapa batasan, karena objek sebenarnya mungkin ada di mesin lain dan di ruang alamat yang berbeda, dan mungkin juga disimpan di disk. Dalam kasus ini, identitas suatu objek harus ditentukan oleh sesuatu selain alamat memori..

Objek memiliki antarmuka

Kemungkinan Aristoteles adalah orang pertama yang mempelajari konsep tipe dengan cermat; dia berbicara tentang "kelas ikan dan kelas burung". Konsep bahwa semua objek, meskipun unik, pada saat yang sama merupakan bagian dari kelas objek dengan karakteristik dan perilaku yang serupa, digunakan dalam bahasa berorientasi objek pertama, Simula-67, dengan pengenalan kata kunci fundamental kelas , yang memperkenalkan tipe baru ke dalam program.

Bahasa simulasi, seperti namanya, diciptakan untuk mengembangkan dan mensimulasikan situasi yang mirip dengan masalah klasik "teller bank". Anda memiliki kelompok kasir, pelanggan, rekening, pembayaran, dan mata uang - banyak "objek". Objek yang identik dalam semua kecuali keadaan internal saat program sedang berjalan dikelompokkan ke dalam "kelas objek". Dari sini datang kata kunci kelas . Membuat tipe data abstrak adalah konsep dasar dalam semua pemrograman berorientasi objek. Tipe data abstrak bertindak dengan cara yang hampir sama dengan tipe bawaan: Anda dapat membuat variabel tipe (disebut objek atau instance dalam istilah OOP) dan memanipulasinya (disebut pesan atau kueri; Anda membuat permintaan dan objek memutuskan apa yang harus dilakukan dengannya. itu. ). Anggota (elemen) dari setiap kelas memiliki kesamaan: setiap akun memiliki saldo, setiap kasir menerima setoran, dll. Pada saat yang sama, semua anggota berbeda dalam keadaan internal mereka: setiap akun memiliki saldo individu, setiap kasir memiliki nama manusia. Oleh karena itu, semua kasir, pelanggan, rekening, transfer, dll. Dapat diwakili oleh entitas unik di dalamnya program komputer. Ini adalah inti dari suatu objek, dan setiap objek termasuk dalam kelas tertentu yang mendefinisikan karakteristik dan perilakunya.

Jadi saat kami membuat tipe data baru dalam bahasa objek, hampir semua bahasa ini menggunakan kata kunci "kelas". Ketika Anda melihat kata "tipe", pikirkan "kelas", dan sebaliknya Beberapa orang membedakan keduanya dengan menunjukkan bahwa tipe mendefinisikan antarmuka, sedangkan kelas adalah implementasi konkret dari antarmuka..

Karena kelas mendefinisikan sekumpulan objek dengan karakteristik identik (anggota data) dan perilaku (fungsionalitas), kelas sebenarnya adalah tipe data, karena, misalnya, bilangan floating point juga memiliki sejumlah karakteristik dan perilaku. Perbedaannya adalah bahwa programmer mendefinisikan kelas untuk mewakili beberapa aspek tugas, daripada menggunakan tipe yang sudah ada yang mewakili unit penyimpanan data di mesin. Anda memperluas bahasa pemrograman dengan menambahkan tipe data baru yang sesuai dengan kebutuhan Anda. Sistem pemrograman menyukai kelas baru dan memberi mereka perhatian yang sama persis dengan tipe bawaan.

Pendekatan berorientasi objek tidak terbatas pada membangun model. Apakah Anda setuju atau tidak bahwa program apa pun adalah model sistem yang Anda kembangkan, penggunaan teknologi OOP dengan mudah mengurangi sejumlah besar masalah menjadi solusi sederhana.

Setelah kelas baru didefinisikan, Anda dapat membuat sejumlah objek dari kelas itu, dan kemudian memanipulasinya seolah-olah mereka adalah bagian dari masalah yang dihadapi. Faktanya, salah satu kesulitan utama dalam OOP adalah membangun korespondensi satu-ke-satu antara objek di ruang masalah dan objek di ruang solusi.

Tetapi bagaimana Anda membuat objek melakukan apa yang Anda inginkan? Harus ada mekanisme untuk mengirim permintaan ke objek untuk melakukan beberapa tindakan - menyelesaikan transaksi, menggambar di layar, dll. Setiap objek hanya dapat melakukan rentang permintaan tertentu. Kueri yang dapat Anda kirim ke objek ditentukan oleh antarmukanya, dan antarmuka objek ditentukan oleh jenisnya. Contoh paling sederhana adalah bola lampu listrik:

Cahaya lt = Cahaya baru() ;
lt.pada();

Antarmuka mendefinisikan permintaan apa yang dapat Anda buat ke objek tertentu. Namun, kode yang mengeksekusi kueri juga harus ada di suatu tempat. Kode ini, bersama dengan data tersembunyi, membuat implementasi. Dari sudut pandang pemrograman prosedural, apa yang terjadi tidak begitu sulit. Tipe berisi metode untuk setiap permintaan yang mungkin, dan ketika permintaan tertentu diterima, metode yang sesuai dipanggil. Proses ini biasanya digabungkan menjadi satu: "mengirim pesan" (mengirimkan permintaan) ke suatu objek, dan memprosesnya oleh suatu objek (mengeksekusi kode).

Dalam contoh ini, ada tipe (kelas) bernama lampu (lampu), objek beton tipe lampu Dengan nama Dia , dan kelas mendukung berbagai kueri objek lampu : Mematikan bohlam, menyalakannya, membuatnya lebih terang, atau meredupkannya. Anda membuat objek lampu , mendefinisikan "referensi" untuk itu ( Dia ) dan memanggil operator baru untuk membuat instance baru dari jenis itu. Untuk mengirim pesan ke suatu objek, Anda harus menentukan nama objek dan mengaitkannya dengan permintaan yang diinginkan dengan sebuah titik. Dari sudut pandang pengguna kelas yang telah ditentukan, ini cukup untuk beroperasi pada objeknya.

Bagan yang ditunjukkan di atas mengikuti format UML (Bahasa Pemodelan Terpadu). Setiap kelas diwakili oleh persegi panjang, semua bidang data yang dijelaskan ditempatkan di bagian tengahnya, dan metode (fungsi objek yang Anda kirimi pesan) dicantumkan di bagian bawah persegi panjang.

Sering di chart UML hanya nama kelas dan metode publik yang ditampilkan, dan bagian tengah tidak ada. Jika Anda hanya tertarik pada nama kelas, Anda dapat melewati bagian bawah juga.

Fasilitas menyediakan layanan

Saat Anda mencoba mendesain atau memahami struktur program, sering kali membantu untuk menganggap objek sebagai "penyedia layanan". Program Anda menyediakan layanan kepada pengguna, dan melakukannya melalui layanan yang disediakan oleh objek lain. Tujuan Anda adalah untuk menghasilkan (atau lebih baik lagi, temukan di perpustakaan kelas) kumpulan objek yang akan optimal untuk memecahkan masalah Anda.

Untuk memulai, tanyakan pada diri sendiri, "Jika saya bisa secara ajaib mengeluarkan benda dari topi, benda mana yang akan dapat menyelesaikan masalah saya sekarang?" Misalkan Anda sedang mengembangkan program akuntansi. Satu dapat membayangkan satu set objek yang menyediakan jendela standar untuk memasukkan informasi akuntansi, satu set objek yang melakukan perhitungan akuntansi, sebuah objek yang mencetak cek dan faktur pada berbagai printer. Mungkin beberapa dari objek ini sudah ada, dan untuk objek lain, ada baiknya mencari tahu seperti apa bentuknya. Layanan apa yang dapat disediakan oleh fasilitas tersebut, dan fasilitas apa yang mereka perlukan untuk melakukan pekerjaan mereka? Jika Anda terus seperti ini, cepat atau lambat Anda akan berkata, "Benda ini cukup sederhana sehingga kita bisa duduk dan menuliskannya," atau "Tentu saja benda seperti itu sudah ada." Ini adalah cara yang masuk akal untuk mendistribusikan solusi masalah ke objek yang terpisah.

Mewakili objek sebagai penyedia layanan memiliki manfaat tambahan: membantu meningkatkan konektivitas ( kepaduan) objek. Konektivitas yang baik - kualitas penting produk perangkat lunak: itu berarti bahwa berbagai aspek komponen perangkat lunak (seperti objek, meskipun dapat juga merujuk ke metode atau pustaka objek) cocok bersama-sama. Satu dari kesalahan Umum diperbolehkan ketika mendesain suatu objek adalah membuatnya terlalu jenuh dengan sejumlah besar properti dan kemampuan. Misalnya, ketika mengembangkan modul yang mencetak cek, Anda mungkin ingin "tahu" semua tentang pemformatan dan pencetakan.

Jika Anda memikirkannya, kemungkinan besar Anda akan sampai pada kesimpulan bahwa ini terlalu banyak untuk satu objek, dan Anda akan pergi ke tiga objek atau lebih. Satu objek akan menjadi katalog dari semua bentuk cek yang mungkin dan dapat ditanyakan tentang bagaimana cek harus dicetak. Objek atau kumpulan objek lain akan bertanggung jawab atas antarmuka pencetakan umum yang "tahu" segalanya tentang berbagai jenis printer (tetapi tidak "mengerti" apa pun dalam akuntansi - lebih baik membeli objek seperti itu daripada mengembangkannya sendiri). Akhirnya, objek ketiga hanya akan menggunakan layanan dari objek yang dijelaskan untuk menyelesaikan tugas. Dengan demikian, setiap objek adalah kumpulan layanan yang terhubung yang ditawarkannya. Dalam proyek berorientasi objek yang terencana dengan baik, setiap objek melakukan pekerjaan yang baik dalam melakukan satu tugas tertentu tanpa mencoba melakukan lebih dari yang dibutuhkan. Seperti yang ditunjukkan, ini tidak hanya memungkinkan Anda untuk menentukan objek mana yang akan dibeli (objek dengan antarmuka cetak), tetapi juga memungkinkan Anda untuk mendapatkan objek yang kemudian dapat digunakan di tempat lain (katalog tanda terima).

Mewakili objek sebagai penyedia layanan sangat menyederhanakan tugas. Ini berguna tidak hanya selama pengembangan, tetapi juga ketika seseorang mencoba memahami kode Anda atau menggunakan kembali objek - maka ia akan dapat mengevaluasi objek secara memadai untuk tingkat layanan yang diberikan, dan ini akan sangat menyederhanakan integrasi yang terakhir ke dalam proyek lain.

Implementasi tersembunyi

Hal ini berguna untuk membagi programmer menjadi pencipta kelas(mereka yang membuat tipe data baru) dan programmer klienSaya berterima kasih atas istilah ini kepada teman saya Scott Meyers.(konsumen kelas yang menggunakan tipe data dalam aplikasinya). Tujuan yang kedua adalah untuk mengumpulkan kelas sebanyak mungkin untuk terlibat dalam pengembangan program yang cepat. Tujuan dari pembuat kelas adalah untuk membangun kelas yang hanya memperlihatkan apa yang dibutuhkan oleh pemrogram klien dan menyembunyikan yang lainnya. Mengapa? Pemrogram klien tidak akan dapat mengakses bagian yang tersembunyi, yang berarti bahwa pembuat kelas memiliki kesempatan untuk mengubahnya secara sewenang-wenang tanpa takut akan menyakiti seseorang. Bagian "tersembunyi" biasanya merupakan bagian yang paling "rapuh" dari objek, yang dapat dengan mudah dirusak oleh pemrogram klien yang ceroboh atau bodoh, jadi menyembunyikan implementasi akan mengurangi jumlah kesalahan dalam program.

Dalam hubungan apa pun, penting untuk memiliki beberapa batasan yang tidak dilanggar oleh salah satu peserta. Dengan membuat perpustakaan, Anda menjalin hubungan dengan programmer klien. Dia adalah seorang programmer seperti Anda, tetapi akan menggunakan perpustakaan Anda untuk membuat aplikasi (dan mungkin perpustakaan tingkat yang lebih tinggi). Jika Anda memberikan akses ke semua anggota kelas kepada siapa pun, pemrogram klien dapat melakukan apa pun yang dia inginkan dengan kelas tersebut, dan tidak mungkin Anda dapat membuatnya "bermain sesuai aturan". Bahkan jika nanti Anda perlu membatasi akses ke anggota tertentu dari kelas Anda, ini tidak dapat dilakukan tanpa mekanisme kontrol akses. Seluruh struktur kelas terbuka untuk semua pendatang.

Jadi, alasan pertama untuk membatasi akses adalah kebutuhan untuk melindungi detail "rapuh" dari pemrogram klien - bagian dari "dapur" internal yang bukan bagian dari antarmuka yang digunakan pengguna untuk memecahkan masalah mereka. Bahkan, ini juga berguna bagi pengguna - mereka akan segera melihat apa yang penting bagi mereka dan apa yang dapat mereka abaikan.

Alasan kedua munculnya pembatasan akses adalah keinginan untuk mengizinkan pengembang perpustakaan mengubah mekanisme internal kelas tanpa khawatir tentang bagaimana hal ini akan mempengaruhi pemrogram klien. Misalnya, Anda dapat mengimplementasikan kelas tertentu dengan tergesa-gesa untuk mempercepat pengembangan program, dan kemudian menulis ulang untuk meningkatkan kecepatan. Jika Anda telah memisahkan dan melindungi antarmuka dan implementasi dengan benar, ini seharusnya tidak sulit sama sekali.

Jawa menggunakan tiga kata kunci eksplisit yang mencirikan tingkat akses: privasi Umum dan terlindung . Tujuan dan penggunaannya sangat sederhana. Penentu akses ini menentukan siapa yang berhak menggunakan definisi yang mengikutinya. Kata publik berarti bahwa definisi berikut tersedia untuk semua orang. Sebaliknya, kata pribadi berarti klausa yang mengikutinya hanya tersedia untuk pembuat tipe, di dalam metodenya. Ketentuan pribadi - "tembok benteng" antara Anda dan klien-programmer. Jika seseorang mencoba menggunakan pribadi -members, itu akan dihentikan oleh kesalahan kompilasi. penentu terlindung bertindak mirip dengan pribadi , dengan satu pengecualian - kelas turunan memiliki akses ke anggota yang ditandai terlindung tetapi tidak memiliki akses ke pribadi -members (kita akan membahas warisan segera).

PADA Jawa ada juga akses "default" yang digunakan jika tidak ada penentu yang terdaftar. Hal ini juga kadang-kadang disebut akses dalam-paket ( akses paket) karena kelas dapat menggunakan anggota teman dari kelas lain dalam paket mereka, tetapi di luar paket, anggota teman yang sama memperoleh status pribadi .

Implementasi Penggunaan Kembali

Kelas yang dihasilkan dan diuji harus (idealnya) menjadi blok kode yang berguna. Namun, ternyata mencapai tujuan ini jauh lebih sulit daripada yang dipikirkan banyak orang; pengembangan objek yang dapat digunakan kembali membutuhkan pengalaman dan pemahaman tentang esensi materi. Tapi begitu Anda melakukannya dengan benar konstruksi yang bagus, itu hanya akan meminta implementasi di program lain. Penggunaan kembali kode adalah salah satu manfaat paling mengesankan dari bahasa berorientasi objek.

Cara termudah untuk menggunakan kembali kelas adalah dengan membuat objeknya secara langsung, tetapi Anda juga dapat menempatkan objek kelas tersebut di dalam kelas baru. Kami menyebutnya injeksi objek (pembuatan objek anggota). Kelas baru dapat berisi sejumlah objek dari tipe lain, dalam kombinasi apa pun yang diperlukan untuk mencapai fungsionalitas yang diinginkan. Karena kami sedang menyusun kelas baru dari kelas yang sudah ada, metode ini disebut komposisi(ketika komposisi dilakukan secara dinamis, biasanya dinamai pengumpulan). Komposisi sering disebut sebagai hubungan "memiliki" ( mempunyai sebuah), seperti, misalnya, dalam kalimat "Mobil memiliki mesin."

(Dalam diagram UML, komposisi ditunjukkan dengan berlian yang diisi, menunjukkan, misalnya, bahwa hanya ada satu mobil. Saya biasanya menggunakan bentuk hubungan yang lebih umum: hanya garis, tidak ada berlian, yang berarti asosiasi (tautan). Ini biasanya cukup untuk sebagian besar bagan di mana perbedaan antara komposisi dan agregasi tidak signifikan bagi Anda.)

Komposisi adalah alat yang sangat fleksibel. Objek anggota kelas baru Anda biasanya dideklarasikan sebagai pribadi ( pribadi ), yang membuatnya tidak dapat diakses oleh pemrogram klien yang menggunakan kelas. Ini memungkinkan perubahan dibuat pada objek anggota ini tanpa mengubah kode klien yang ada. Anda juga dapat mengubah anggota ini saat runtime untuk mengontrol perilaku program Anda secara dinamis. Warisan yang dijelaskan di bawah ini tidak memiliki fleksibilitas ini karena kompiler memberlakukan batasan tertentu pada kelas yang dibuat menggunakan warisan.

Warisan memainkan peran penting dalam pemrograman berorientasi objek, sehingga sering diberi banyak perhatian, dan seorang pemula mungkin berpikir bahwa warisan harus diterapkan di mana-mana. Dan ini penuh dengan penciptaan solusi yang rumit dan tidak perlu. Sebagai gantinya, saat membuat kelas baru, Anda harus terlebih dahulu mengevaluasi kemungkinan komposisi, karena lebih sederhana dan lebih fleksibel. Jika Anda mengadopsi pendekatan yang disarankan, konstruksi pemrograman Anda akan menjadi lebih jelas. Dan saat Anda memperoleh pengalaman praktis, tidak akan sulit untuk memahami di mana warisan harus digunakan.

Warisan

Dengan sendirinya, gagasan tentang suatu objek sangat nyaman. Objek memungkinkan Anda untuk menggabungkan data dan fungsionalitas pada tingkat konseptual, yaitu, Anda dapat mewakili konsep yang diinginkan dari ruang tugas alih-alih mengkonkretkannya menggunakan dialek mesin. Konsep-konsep ini membentuk unit dasar bahasa pemrograman, dijelaskan dengan kata kunci class.

Tetapi Anda harus mengakui, akan sangat memalukan untuk membuat semacam kelas, dan kemudian melakukan semua pekerjaan lagi untuk kelas yang serupa. Jauh lebih rasional untuk mengambil kelas yang sudah jadi, "mengkloningnya", dan kemudian membuat penambahan dan pembaruan pada klon yang dihasilkan. Ini persis seperti yang Anda dapatkan sebagai hasil dari pewarisan, dengan satu pengecualian - jika kelas asli (juga disebut kelas * dasar, superclass atau kelas induk) berubah, maka semua perubahan tercermin dalam "klon" (disebut kelas turunan) , kelas yang diwarisi, subkelas atau kelas anak).

(Panah (segitiga kosong) dalam diagram UML menunjuk dari kelas turunan ke kelas dasar. Seperti yang akan segera Anda lihat, mungkin ada lebih dari satu kelas turunan.)

Tipe mendefinisikan lebih dari sekedar properti dari sekelompok objek; itu juga terkait dengan jenis lain. Kedua jenis ini mungkin memiliki kesamaan dan perilaku, tetapi berbeda dalam jumlah karakteristik, serta kemampuan untuk memproses lebih banyak pesan (atau memprosesnya secara berbeda). Untuk mengekspresikan kesamaan tipe ini, pewarisan menggunakan konsep tipe dasar dan turunan. Tipe dasar berisi semua karakteristik dan tindakan yang umum untuk semua tipe yang diturunkan darinya. Anda membuat tipe dasar untuk mewakili dasar pemahaman Anda tentang beberapa objek di sistem Anda. Tipe lain diturunkan dari tipe dasar, mengekspresikan implementasi lain dari entitas ini.

Misalnya, mesin daur ulang memilah sampah. Jenis dasarnya adalah "sampah", dan setiap potongan sampah memiliki berat, biaya, dll., dan dapat dihancurkan, dicairkan, atau diurai. Berdasarkan hal ini, jenis sampah yang lebih spesifik diwariskan, memiliki karakteristik tambahan (botol memiliki warna) atau sifat perilaku ( kaleng aluminium dapat dihancurkan, baja dapat ditarik oleh magnet). Selain itu, beberapa perilaku mungkin berbeda (biaya kertas tergantung pada jenis dan kondisinya). Warisan memungkinkan Anda membuat hierarki tipe yang menjelaskan masalah yang sedang dipecahkan dalam konteks tipenya.

Contoh kedua adalah contoh klasik dengan bentuk geometris. Jenis dasar di sini adalah "bentuk", dan setiap bentuk memiliki ukuran, warna, lokasi, dll. Setiap bentuk dapat digambar, dihapus, dipindahkan, dicat, dll. Selanjutnya, jenis bentuk tertentu diproduksi (diwariskan): lingkaran, persegi, segitiga, dll., yang masing-masing memiliki karakteristik dan perilaku tambahannya sendiri. Misalnya, beberapa bentuk mendukung operasi pencerminan. Ciri-ciri perilaku individu mungkin berbeda, seperti dalam hal menghitung luas suatu gambar. Hirarki tipe mewujudkan sifat bentuk yang serupa dan berbeda.

Mengurangi solusi ke konsep yang digunakan dalam contoh sangat mudah, karena Anda tidak memerlukan banyak model perantara yang menghubungkan deskripsi solusi dengan deskripsi masalah. Saat bekerja dengan objek, hierarki tipe menjadi model utama, jadi Anda beralih dari mendeskripsikan sistem di dunia nyata secara langsung ke mendeskripsikan sistem dalam kode. Faktanya, salah satu kesulitan dalam perencanaan berorientasi objek adalah sangat mudah bagi Anda untuk beralih dari awal masalah ke akhir solusi. Pikiran yang terlatih untuk solusi kompleks sering macet saat menggunakan pendekatan sederhana.

Dengan mewarisi dari tipe yang ada, Anda membuat tipe baru. Tipe baru ini tidak hanya berisi semua anggota dari tipe yang ada (walaupun anggota ditandai sebagai pribadi , tersembunyi dan tidak dapat diakses), tetapi, yang lebih penting, mengulangi antarmuka kelas dasar. Ini berarti bahwa semua pesan yang dapat Anda kirim ke kelas dasar, Anda juga dapat mengirim ke kelas turunan. Dan karena kami membedakan tipe kelas berdasarkan kumpulan pesan yang dapat kami kirimkan, ini berarti kelas turunan adalah kasus khusus dari kelas dasar. Dalam contoh sebelumnya, "lingkaran adalah gambar." Kesetaraan tipe yang dicapai dengan pewarisan adalah salah satu kondisi mendasar untuk memahami arti pemrograman berorientasi objek.

Karena kelas dasar dan turunan memiliki antarmuka utama yang sama, harus ada implementasi untuk antarmuka itu. Dengan kata lain, di suatu tempat pasti ada kode yang dieksekusi ketika suatu objek menerima pesan tertentu. Jika Anda hanya mewarisi kelas dan tidak melakukan apa pun, metode dari antarmuka kelas dasar akan diteruskan ke kelas turunan tidak berubah. Ini berarti bahwa objek dari kelas turunan tidak hanya dari jenis yang sama, tetapi juga memiliki perilaku yang sama, dan pada saat yang sama, pewarisan itu sendiri kehilangan maknanya.

Ada dua cara untuk mengubah kelas baru dari kelas dasar. Yang pertama cukup jelas: metode yang sama sekali baru ditambahkan ke kelas turunan. Mereka tidak lagi menjadi bagian dari antarmuka kelas dasar. Rupanya kelas dasar tidak melakukan semua tugas yang diperlukan, jadi Anda menambahkan beberapa metode. Namun, pendekatan pewarisan yang sederhana dan primitif seperti itu terkadang menjadi solusi ideal untuk masalah tersebut. Namun, satu hal yang perlu dipertimbangkan dengan hati-hati adalah bahwa kelas dasar mungkin juga memerlukan metode tambahan ini. Proses mengidentifikasi pola dan merevisi arsitektur adalah rutinitas sehari-hari dalam pemrograman berorientasi objek.

Sementara pewarisan terkadang menunjukkan bahwa antarmuka akan ditambah dengan metode baru (terutama dalam Jawa, di mana pewarisan dilambangkan dengan kata kunci meluas , yaitu, "perluas"), ini tidak perlu sama sekali. Cara kedua yang lebih penting untuk memodifikasi kelas adalah dengan mengubah perilaku sudah metode yang ada kelas dasar. Ini disebut overriding (atau overriding) suatu metode.

Untuk mengganti metode, Anda cukup membuat definisi baru dari metode tersebut di kelas turunan. Anda agak mengatakan "Saya menggunakan metode antarmuka yang sama, tetapi saya ingin melakukan hal yang berbeda untuk tipe baru saya."

Saat menggunakan pewarisan, pertanyaan yang jelas muncul: haruskah pewarisan menimpa metode hanya kelas dasar (dan tidak menambahkan metode baru yang tidak ada di kelas dasar)? Ini berarti bahwa kelas turunan akan memiliki tipe yang persis sama dengan kelas dasar, karena mereka memiliki antarmuka yang sama. Akibatnya, Anda dapat dengan bebas mengganti objek kelas dasar dengan objek kelas turunan. Anda dapat berbicara tentang penggantian yang lengkap, dan ini sering disebut prinsip substitusi. Dalam arti tertentu, cara pewarisan ini sangat ideal. Hubungan semacam ini antara kelas dasar dan kelas turunan sering disebut sebagai hubungan. "adalah sesuatu", karena seseorang dapat mengatakan "lingkaran adalah gambar". Untuk menentukan seberapa tepat pewarisan, cukup memeriksa apakah ada hubungan "ada" antara kelas dan seberapa dibenarkan itu.

Dalam kasus lain, antarmuka kelas turunan dilengkapi dengan elemen baru, yang mengarah ke ekstensinya. Tipe baru masih dapat digunakan sebagai pengganti tipe dasar, tetapi sekarang penggantian ini tidak ideal karena metode baru tidak tersedia dari tipe dasar. Hubungan seperti itu dijelaskan dengan ungkapan "mirip dengan" (ini adalah istilah saya); tipe baru berisi antarmuka tipe lama, tetapi juga termasuk metode baru, dan tipe ini tidak dapat dikatakan persis sama. Mari kita ambil AC sebagai contoh.

Misalkan rumah Anda dilengkapi dengan segalanya Peralatan yang diperlukan untuk mengontrol proses pendinginan. Bayangkan sekarang AC telah rusak dan Anda telah menggantinya dengan pemanas yang mampu memanaskan dan mendinginkan. Pemanas adalah "seperti" AC, tetapi bisa berbuat lebih banyak. Karena sistem kontrol rumah Anda hanya dapat mengontrol pendinginan, sistem ini terbatas dalam berkomunikasi dengan bagian pendingin fasilitas baru. Antarmuka objek baru telah diperpanjang, dan sistem yang ada tidak mengenali apa pun selain antarmuka asli.

Tentu saja, melihat hierarki ini, menjadi jelas bahwa kelas dasar "sistem pendingin" tidak cukup fleksibel; itu harus diganti namanya menjadi "sistem kontrol suhu" sehingga juga mencakup pemanasan - dan setelah itu prinsip substitusi akan berfungsi. Namun, diagram ini memberikan contoh tentang apa yang bisa terjadi dalam kenyataan.

Setelah mengenal prinsip substitusi, orang mungkin mendapat kesan bahwa pendekatan ini (penggantian penuh) adalah satu-satunya cara untuk berkembang. Secara umum, jika hierarki tipe Anda bekerja dengan cara ini, itu sangat bagus. Tetapi dalam beberapa situasi mutlak diperlukan untuk menambahkan metode baru ke antarmuka kelas turunan. Pada pemeriksaan lebih dekat, kedua kasus tampak cukup jelas.

Objek yang Dapat Dipertukarkan dan Polimorfisme

Saat menggunakan hierarki tipe, seringkali diperlukan untuk memperlakukan objek dari tipe tertentu sebagai tipe dasar. Ini memungkinkan Anda untuk menulis kode yang tidak bergantung pada tipe konkret. Jadi, dalam contoh bentuk, metode hanya memanipulasi bentuk, terlepas dari apakah itu lingkaran, persegi panjang, segitiga, atau beberapa bentuk yang belum ditentukan. Semua bentuk dapat digambar, dihapus, dan dipindahkan, dan metodenya hanya mengirim pesan ke objek bentuk; mereka tidak peduli bagaimana objek menangani pesan.

Kode tersebut tidak bergantung pada penambahan tipe baru, dan penambahan tipe baru adalah cara paling umum untuk memperluas program berorientasi objek untuk menangani situasi baru. Misalnya, Anda dapat membuat subkelas bentuk baru (pentagon) tanpa mengubah metode yang hanya berfungsi dengan bentuk umum. Kemampuan untuk memperluas program dengan mudah dengan memperkenalkan jenis turunan baru sangat penting karena sangat meningkatkan arsitektur program sementara pada saat yang sama mengurangi biaya pemeliharaan perangkat lunak.

Namun, ketika mencoba merujuk pada objek dari tipe turunan sebagai tipe dasar (lingkaran sebagai sosok, sepeda sebagai kendaraan, dandang sebagai burung, dll.), satu masalah muncul. Jika suatu metode akan memberi tahu sosok umum untuk menggambar dirinya sendiri, atau kendaraan untuk mengikuti jalur tertentu, atau seekor burung untuk terbang, kompilator tidak dapat mengetahui dengan tepat bagian kode mana yang akan dieksekusi. Itulah intinya - ketika sebuah pesan dikirim, programmer tidak ingin tahu kode apa yang sedang dieksekusi; metode menggambar dapat diterapkan pada lingkaran, persegi panjang, dan segitiga dengan keberhasilan yang sama, dan objek akan mengeksekusi kode yang benar, tergantung pada tipe karakteristiknya.

Jika Anda tidak perlu mengetahui bagian kode mana yang sedang dieksekusi, maka saat Anda menambahkan subtipe baru, kode implementasinya bisa berbeda tanpa memerlukan perubahan pada metode pemanggilannya. Jika kompiler tidak tahu persis kode apa yang harus dieksekusi, apa fungsinya?

PADA contoh berikutnya Sebuah Objek Pengendali Burung (kontrol burung) hanya dapat bekerja dengan objek generik burung (burung), tidak mengetahui jenis persisnya. Dari sudut pandang Pengendali Burung ini nyaman karena Anda tidak perlu menulis kode khusus untuk memeriksa jenis objek yang digunakan untuk itu burung , untuk menangani beberapa perilaku khusus. Bagaimana bisa terjadi ketika Anda memanggil metode move (), tanpa menentukan tipe yang tepat? burung , tindakan yang benar dilakukan - objek angsa (angsa) berlari, terbang atau berenang, dan objek pinguin (penguin) berlari atau berenang?

Jawabannya dijelaskan Fitur utama pemrograman berorientasi objek: kompiler tidak dapat memanggil fungsi seperti itu dengan cara tradisional. Saat memanggil fungsi yang dibuat oleh kompiler non-OOP, gunakan pengikatan awal- banyak yang tidak tahu istilah ini hanya karena mereka tidak membayangkan pilihan lain. Dengan pengikatan awal, kompiler menghasilkan panggilan fungsi dengan nama pemberian, dan linker mengikat panggilan ini ke alamat absolut dari kode yang akan dieksekusi. Di OOP, program tidak dapat menentukan alamat kode sampai runtime, jadi ketika mengirim pesan ke suatu objek, mekanisme yang berbeda harus bekerja.

Untuk mengatasi masalah ini, bahasa pemrograman berorientasi objek menggunakan konsep pengikatan terlambat. Saat Anda mengirim pesan ke suatu objek, kode yang dipanggil tidak diketahui sampai waktu berjalan. Kompilator hanya memastikan bahwa metode itu ada, memeriksa jenis parameternya dan mengembalikan nilai, tetapi tidak tahu jenis kode apa yang akan dieksekusi.

Untuk menerapkan late binding, Jawa menggunakan cuplikan kode khusus alih-alih panggilan absolut. Kode ini menghitung alamat badan metode berdasarkan informasi yang disimpan dalam objek (proses ini dibahas dengan sangat rinci dalam Bab 7 tentang polimorfisme). Dengan demikian, setiap objek dapat berperilaku berbeda, tergantung pada konten dari potongan kode khusus ini. Saat Anda mengirim pesan, objek sebenarnya memutuskan apa yang harus dilakukan dengannya.

Beberapa bahasa mengharuskan Anda untuk secara eksplisit menentukan bahwa suatu metode harus menggunakan mekanisme pengikatan lambat yang fleksibel (dalam C++ ada kata kunci untuk ini maya). Dalam bahasa ini, metode tidak ditautkan secara dinamis secara default. PADA Jawa late binding dilakukan secara default, dan Anda tidak perlu mengingat untuk menambahkan kata kunci apa pun untuk memberikan polimorfisme.

Ingat contoh dengan bentuk. Sebuah keluarga kelas (berdasarkan antarmuka yang sama) ditunjukkan dalam diagram sebelumnya dalam bab ini. Untuk mendemonstrasikan polimorfisme, kami akan menulis cuplikan kode yang mengabaikan spesifikasi tipe dan hanya berfungsi pada kelas dasar. Kode ini dipisahkan dari tipe spesifik, sehingga lebih mudah untuk ditulis dan dipahami. Dan jika jenis baru (misalnya, segi enam) ditambahkan melalui pewarisan, maka kode yang Anda tulis untuk jenis gambar baru akan berfungsi sama baiknya dengan kode untuk jenis yang ada. Dengan demikian, program menjadi extensible.

Katakanlah Anda menulis Jawa metode berikut (Anda akan segera mempelajari cara melakukannya):

void doSomething(Bentuk bentuk) (
bentuk. hapus(); // hapus
//...
bentuk.draw(); // seri
}

Metode ini bekerja dengan gambar umum ( membentuk ), yaitu, tidak tergantung pada jenis objek tertentu yang digambar atau dihapus. Kami sekarang menggunakan metode panggilan lakukan sesuatu() di bagian lain dari program:

Lingkaran lingkaran = Lingkaran baru() ; // lingkaran
Segitiga segitiga = segitiga baru() ; // segitiga
Baris baris = baris baru(); // garis
melakukanSesuatu(lingkaran);
melakukan Sesuatu(segitiga);
melakukanSesuatu(baris);

Panggilan metode lakukan sesuatu() secara otomatis bekerja dengan benar, terlepas dari jenis objek yang sebenarnya.

Ini sebenarnya fakta yang cukup penting. Pertimbangkan baris:

melakukanSesuatu(lingkaran);

Di sinilah hal berikut terjadi: pada metode yang mengharapkan objek membentuk , objek "lingkaran" dilewatkan ( Lingkaran ). Karena lingkaran ( Lingkaran ) secara bersamaan merupakan angka ( membentuk ), maka caranya lakukan sesuatu() dan memperlakukannya seperti sosok. Dengan kata lain, pesan apa pun yang dapat dikirim oleh metode ini membentuk , juga diterima Lingkaran . Tindakan ini benar-benar aman dan sama logisnya.

Kami mengacu pada proses menangani tipe turunan ini seolah-olah itu adalah tipe dasar. upcasting. Kata transformasi berarti bahwa objek tersebut diperlakukan sebagai milik tipe yang berbeda, dan naik itu karena dalam diagram pewarisan, kelas dasar biasanya berada di atas dan kelas turunan tersebar di bagian bawah. Ini berarti bahwa konversi ke tipe dasar adalah gerakan ke atas di sepanjang diagram, dan oleh karena itu "ke atas".

Program berorientasi objek hampir selalu berisi upcast, karena itulah cara Anda menghilangkan kebutuhan untuk mengetahui jenis objek yang sedang Anda kerjakan. Lihatlah tubuh metodenya lakukan sesuatu() :

bentuk. hapus();
// ...
bentuk.draw();

Perhatikan bahwa itu tidak mengatakan "jika Anda adalah objek Lingkaran , lakukan, dan jika Anda adalah objek Kotak lakukan ini dan itu." Kode tersebut dengan tindakan terpisah untuk setiap jenis yang mungkin membentuk akan membingungkan dan harus diubah setiap kali subtipe baru ditambahkan membentuk . Jadi, Anda hanya mengatakan: "Anda adalah sosok, dan saya tahu bahwa Anda dapat menggambar dan menghapus diri sendiri, baik, lakukan, dan urus sendiri detailnya."

Dalam kode metode lakukan sesuatu() Yang menarik adalah semuanya berjalan dengan baik. Saat dipanggil seri() untuk objek Lingkaran kode lain dieksekusi, dan bukan kode yang berfungsi saat dipanggil seri() untuk objek Kotak atau garis , dan kapan seri() diterapkan pada sosok yang tidak dikenal membentuk , perilaku yang benar disediakan dengan menggunakan tipe nyata membentuk . itu di derajat tertinggi menarik, karena, seperti disebutkan sedikit sebelumnya, ketika kompiler menghasilkan kode lakukan sesuatu() , ia tidak tahu persis dengan jenis apa ia bekerja. Dengan demikian, orang akan mengharapkan versi metode dipanggil seri() dan menghapus() dari kelas dasar membentuk , bukan varian mereka dari kelas konkret Lingkaran , Kotak atau garis . Namun semuanya bekerja dengan benar berkat polimorfisme. Kompiler dan sistem runtime menangani semua detail; yang perlu Anda ketahui adalah bahwa itu akan terjadi... dan yang lebih penting, bagaimana membangun program menggunakan pendekatan ini. Saat Anda mengirim pesan ke objek, objek akan memilih perilaku yang benar menggunakan upcast.

Hirarki akar tunggal

Tak lama setelah penampilan C++ pertanyaan dari OOP mulai dibahas secara aktif - haruskah semua kelas diwarisi dari satu kelas dasar? PADA Jawa(seperti di hampir semua bahasa OOP lainnya kecuali C++) Pertanyaan ini dijawab dengan setuju. Seluruh tipe hierarki didasarkan pada satu kelas dasar Obyek . Ternyata hierarki akar tunggal memiliki banyak keunggulan.

Semua objek dalam hierarki berakar tunggal berbagi beberapa antarmuka umum, sehingga pada umumnya mereka semua dapat dianggap sebagai satu tipe yang mendasarinya. PADA C++ pilihan lain dipilih - nenek moyang yang sama tidak ada dalam bahasa ini. Dalam hal kompatibilitas dengan kode lama, model ini lebih sesuai dengan tradisi. C, dan Anda mungkin berpikir bahwa itu tidak terlalu terbatas. Tetapi segera setelah kebutuhan untuk pemrograman berorientasi objek yang lengkap muncul, Anda harus membuat hierarki kelas Anda sendiri untuk mendapatkan manfaat yang sama yang dibangun ke dalam bahasa OOP lainnya. Dan di perpustakaan kelas baru, Anda mungkin menemukan beberapa antarmuka yang tidak kompatibel. Memasukkan antarmuka baru ini ke dalam arsitektur program Anda akan membutuhkan usaha ekstra (dan mungkin pewarisan berganda). Apakah "fleksibilitas" ekstra sepadan? C++ biaya serupa? Jika Anda membutuhkannya (mis. investasi besar untuk pengembangan kode C), maka Anda tidak akan menjadi pecundang. Jika pengembangan dimulai dari awal, pendekatannya Jawa terlihat lebih produktif.

Semua objek dalam hierarki root tunggal dijamin memiliki beberapa fungsi umum. Anda tahu bahwa operasi dasar tertentu dapat dilakukan pada objek apa pun dalam sistem. Semua objek dengan mudah dibuat di tumpukan dinamis, dan argumen yang lewat sangat disederhanakan.

Hirarki root tunggal mempermudah penerapan pengumpulan sampah - salah satu peningkatan terpenting Jawa dibandingkan dengan C++. Karena informasi tipe dijamin ada di salah satu objek pada saat dijalankan, tidak akan pernah ada objek dalam sistem yang tipenya tidak dapat ditentukan. Ini sangat penting ketika melakukan operasi sistem seperti menangani pengecualian dan untuk fleksibilitas pemrograman yang lebih besar.

Wadah

Seringkali tidak diketahui sebelumnya berapa banyak objek yang dibutuhkan untuk memecahkan masalah tertentu dan berapa lama mereka akan ada. Juga tidak jelas bagaimana cara menyimpan benda-benda tersebut. Berapa banyak memori yang harus dialokasikan untuk menyimpan objek-objek ini? Tidak diketahui, karena informasi ini hanya akan tersedia saat program sedang berjalan.

Banyak masalah dalam pemrograman berorientasi objek diselesaikan tindakan sederhana: Anda sedang membuat objek jenis lain. Jenis objek baru yang memecahkan masalah khusus ini berisi referensi ke objek lain. Tentu saja, array, yang didukung di sebagian besar bahasa, juga dapat memainkan peran ini. Namun, objek baru, biasanya disebut wadah(atau koleksi, tetapi dalam Jawa istilah ini digunakan dalam arti yang berbeda) akan kebutuhan berkembang untuk mengakomodasi apa pun yang Anda masukkan ke dalamnya. Oleh karena itu, Anda tidak perlu mengetahui sebelumnya berapa banyak objek yang dirancang untuk kapasitas wadah. Cukup buat wadah dan itu akan mengurus detailnya.

Untungnya, bahasa OOP yang baik hadir dengan satu set wadah yang sudah jadi. PADA C++ itu bagian dari perpustakaan standar C++, terkadang disebut perpustakaan template standar (Perpustakaan Template Standar, STL). obrolan ringan hadir dengan berbagai wadah yang sangat luas. Jawa juga berisi wadah di perpustakaan standarnya. Untuk beberapa perpustakaan, dianggap cukup untuk memiliki satu wadah untuk semua kebutuhan, tetapi di tempat lain (misalnya, di .) Jawa) ada berbagai wadah untuk semua kesempatan: beberapa jenis daftar yang berbeda Daftar (untuk menyimpan urutan elemen), peta Peta (juga dikenal sebagai array asosiatif, memungkinkan Anda untuk mengasosiasikan objek dengan objek lain), serta set mengatur (memberikan nilai unik untuk setiap jenis). Pustaka kontainer juga dapat berisi antrian, pohon, tumpukan, dan sebagainya.

Dari sudut pandang desain, yang Anda butuhkan hanyalah wadah yang dapat menyelesaikan masalah Anda. Jika satu jenis wadah memenuhi semua kebutuhan, tidak ada alasan untuk menggunakan jenis lain. Ada dua alasan mengapa Anda harus memilih dari wadah yang tersedia. Pertama, container menyediakan berbagai antarmuka dan interaksi. Perilaku dan antarmuka tumpukan berbeda dari antrian, yang berperilaku berbeda dari kumpulan atau daftar. Salah satu wadah ini mampu menyediakan lebih dari solusi efektif tugas Anda dibandingkan dengan yang lain. Kedua, wadah yang berbeda melakukan operasi yang sama dengan cara yang berbeda. contoh terbaik- ini Daftar Array dan Daftar Tertaut . Keduanya adalah urutan sederhana yang dapat memiliki antarmuka dan perilaku yang identik. Tetapi beberapa operasi berbeda secara signifikan dalam waktu eksekusi. Katakanlah waktu pengambilan sampel elemen arbitrer di Daftar Array selalu tetap sama terlepas dari elemen mana yang dipilih. Namun, dalam Daftar Tertaut tidak menguntungkan untuk bekerja dengan akses acak - semakin jauh ke bawah daftar elemen, semakin besar penundaan yang menyebabkan pencariannya. Di sisi lain, jika Anda perlu memasukkan elemen di tengah daftar, Daftar Tertaut lakukan lebih cepat dari Daftar Array . Ini dan operasi lainnya adalah efisiensi yang berbeda bergantung kepada struktur internal wadah. Pada tahap perencanaan program, Anda dapat memilih daftar Daftar Tertaut , lalu, selama proses pengoptimalan, alihkan ke Daftar Array . Karena sifat abstrak dari antarmuka Daftar transisi seperti itu akan membutuhkan sedikit perubahan dalam kode.

Jenis parameter (generik)

Sebelum rilis Jawa SE5 kontainer hanya bisa menyimpan data Obyek - satu-satunya tipe universal Jawa. Hirarki akar tunggal berarti bahwa objek apa pun dapat dianggap sebagai Obyek , jadi wadah dengan elemen Obyek cocok untuk penyimpanan benda apapun Tipe primitif tidak dapat disimpan dalam wadah, tetapi berkat mekanismenya kemasan otomatis(kotak otomatis) Jawa SE5 pembatasan ini tidak penting. Topik ini akan dibahas secara lebih rinci nanti dalam buku ini..

Saat bekerja dengan wadah seperti itu, Anda cukup memasukkan referensi objek ke dalamnya, dan kemudian mengambilnya kembali. Tetapi jika wadah hanya mampu menyimpan Obyek , kemudian ketika referensi ke objek dari jenis lain ditempatkan di dalamnya, konversi ke Obyek , yaitu, hilangnya "individualitas" objek. Saat mengambilnya kembali, Anda mendapatkan referensi ke Obyek , bukan referensi ke jenis yang ditempatkan di penampung. Bagaimana cara mengubahnya menjadi jenis objek tertentu yang ditempatkan dalam wadah?

Masalahnya diselesaikan dengan konversi tipe yang sama, tetapi kali ini Anda tidak menggunakan upcast (naik hierarki pewarisan ke tipe dasar). Anda sekarang menggunakan metode mengonversi hierarki pewarisan (ke tipe anak). Metode ini ditelepon konversi ke bawah. Dalam kasus upcast, diketahui bahwa lingkaran adalah gambar, sehingga konversi diketahui aman, tetapi dalam kasus reverse cast (untuk tipe anak), tidak mungkin untuk mengatakan terlebih dahulu apakah sebuah contoh mewakili Obyek Sebuah Objek Lingkaran atau membentuk , jadi downcasting hanya aman jika Anda tahu persis jenis objeknya.

Namun, bahayanya tidak begitu besar - downcasting ke tipe yang salah akan menghasilkan kesalahan run-time yang disebut pengecualian(Lihat di bawah). Tetapi ketika mengambil referensi objek dari sebuah wadah, Anda perlu mengingat jenis objek yang sebenarnya untuk melakukan downcast yang benar.

Pengecekan tipe downcasting dan runtime membutuhkan waktu ekstra dan usaha ekstra dari programmer. Atau mungkin Anda entah bagaimana dapat membuat wadah yang mengetahui jenis objek yang disimpan, dan dengan demikian menghilangkan kebutuhan untuk konversi jenis dan potensi kesalahan? Solusinya disebut mekanisme jenis parameterisasi. Tipe parameter adalah kelas yang dapat secara otomatis diadaptasi oleh kompiler untuk bekerja dengan tipe tertentu. Misalnya, kompiler mungkin mengonfigurasi wadah berparameter untuk menyimpan dan mengambil hanya bentuk ( membentuk ).

Salah satu perubahan terpenting Jawa SE5 adalah dukungan untuk tipe parameter ( obat generik). Jenis parameterisasi mudah dikenali oleh kurung sudut yang menyertakan nama jenis parameter; misalnya wadah Daftar Array , dirancang untuk menyimpan objek membentuk , dibuat seperti ini:

Daftar Array< Shape >bentuk = ArrayList baru< Shape > () ;

Banyak komponen perpustakaan standar juga telah dimodifikasi untuk menggunakan tipe generik. Seperti yang akan segera Anda lihat, tipe generik muncul di banyak contoh program dalam buku ini.

Penciptaan, penggunaan objek dan masa hidupnya

Satu dari aspek kritis bekerja dengan objek - organisasi penciptaan dan penghancurannya. Untuk keberadaan setiap objek, beberapa sumber daya diperlukan, terutama memori. Ketika suatu objek tidak lagi dibutuhkan, itu harus dihancurkan sehingga sumber daya yang didudukinya dapat tersedia untuk orang lain. Dalam situasi sederhana, tugas tersebut tampaknya tidak sulit: Anda membuat objek, menggunakannya selama diperlukan, lalu menghancurkannya. Namun, situasi yang lebih kompleks sering terjadi dalam praktik.

Katakanlah, misalnya, Anda sedang mengembangkan sistem untuk mengatur lalu lintas udara. (Model yang sama juga berlaku untuk kontrol tare di gudang, atau sistem penyewaan video, atau kandang hewan liar.) Pada awalnya, semuanya tampak sederhana: wadah pesawat dibuat, kemudian pesawat baru dibangun, yang ditempatkan di wadah dari area kontrol lalu lintas udara tertentu. Adapun pelepasan sumber daya, objek yang sesuai dihancurkan begitu saja ketika pesawat meninggalkan zona pelacakan.

Tapi mungkin ada sistem registrasi pesawat lain, dan data ini tidak memerlukan perhatian yang cermat seperti fungsi utama pengelolaan. Mungkin itu catatan rencana penerbangan dari semua pesawat kecil yang meninggalkan bandara. Beginilah penampakan kontainer kedua untuk pesawat kecil; setiap kali objek pesawat baru dibuat dalam sistem, itu juga termasuk dalam wadah kedua jika pesawatnya kecil. Selanjutnya, beberapa proses latar belakang bekerja dengan objek dalam wadah ini pada saat-saat sibuk minimal.

Sekarang tugasnya menjadi lebih rumit: bagaimana Anda tahu kapan harus menghapus objek? Bahkan jika Anda sudah selesai dengan objek, ada kemungkinan bahwa sistem lain masih berinteraksi dengannya. Pertanyaan yang sama muncul dalam sejumlah situasi lain, dan dalam sistem perangkat lunak di mana perlu untuk menghapus objek secara eksplisit setelah bekerja dengannya selesai (misalnya, dalam C++), menjadi cukup kompleks.

Di mana data objek disimpan dan bagaimana masa pakainya ditentukan? PADA C++ Efisiensi diutamakan, sehingga programmer diberi pilihan. Untuk pencapaian kecepatan tertinggi lokasi eksekusi dan masa pakai dapat ditentukan pada saat penulisan program. Dalam hal ini, objek didorong ke tumpukan (variabel seperti itu disebut otomatis) atau ke area penyimpanan statis. Jadi faktor utamanya adalah kecepatan membuat dan menghancurkan objek, dan ini bisa sangat berharga dalam beberapa situasi. Namun, ini datang dengan mengorbankan fleksibilitas, karena jumlah objek, masa pakainya, dan jenisnya harus diketahui dengan tepat pada tahap desain program. Saat memecahkan masalah profil yang lebih luas - pengembangan sistem desain berbantuan komputer
(CAD), kontrol inventaris atau kontrol lalu lintas udara - pendekatan ini mungkin terlalu terbatas.

Cara kedua adalah membuat objek secara dinamis di area memori yang disebut "heap" ( tumpukan). Dalam hal ini, jumlah objek, tipe persisnya, dan masa pakainya tetap tidak diketahui hingga program dimulai. Semua ini ditentukan "on the fly" saat program sedang berjalan. Jika Anda membutuhkan objek baru, Anda cukup membuatnya di heap saat dibutuhkan. Karena heap dikelola secara dinamis, diperlukan waktu lebih lama untuk mengalokasikan memori dari heap selama eksekusi program daripada saat mengalokasikan memori pada stack. (Hanya dibutuhkan satu instruksi mesin untuk mengalokasikan memori pada tumpukan, memindahkan penunjuk tumpukan ke bawah, dan membebaskannya dilakukan dengan menggerakkan penunjuk ini ke atas. Waktu yang dibutuhkan untuk mengalokasikan memori pada tumpukan tergantung pada struktur penyimpanan.)

Pendekatan dinamis mengasumsikan bahwa objek berukuran besar dan kompleks, sehingga waktu ekstra yang diperlukan untuk mengalokasikan dan membatalkan alokasi memori tidak akan berdampak signifikan pada proses pembuatannya. Kemudian, fleksibilitas tambahan sangat penting untuk memecahkan masalah pemrograman dasar.

PADA Jawa hanya pendekatan kedua yang digunakan Jenis primitif, yang akan dibahas selanjutnya, adalah kasus khusus.. Kata kunci digunakan setiap kali sebuah objek dibuat. baru untuk membangun instance dinamis.

Namun, ada faktor lain, yaitu umur benda. Dalam bahasa yang mendukung pembuatan objek di tumpukan, kompiler menentukan berapa lama suatu objek digunakan dan dapat secara otomatis menghancurkannya. Namun, ketika sebuah objek dibuat di heap, kompiler tidak tahu tentang masa pakai objek. Dalam bahasa seperti C++, penghancuran objek harus secara eksplisit dibingkai dalam program; jika ini tidak dilakukan, terjadi kebocoran memori (masalah umum dalam program C++). PADA Jawa ada mekanisme yang disebut pengumpulan sampah; itu secara otomatis mendeteksi ketika suatu objek tidak lagi digunakan dan menghancurkannya. Pengumpul sampah sangat berguna karena menghemat banyak kerumitan bagi programmer. Lebih penting lagi, pengumpul sampah memberi Anda lebih banyak keyakinan bahwa masalah kebocoran memori yang berbahaya tidak menyusup ke dalam program Anda (yang membawa lebih dari satu proyek di C++).

PADA Jawa pengumpul sampah dirancang sedemikian rupa sehingga dapat menangani masalah mengosongkan memori itu sendiri (ini tidak mempengaruhi aspek lain dari akhir kehidupan suatu objek). Pengumpul sampah "tahu" ketika suatu objek tidak lagi digunakan dan menggunakan pengetahuannya untuk secara otomatis membatalkan alokasi memori. Karena fakta ini (bersama dengan fakta bahwa semua objek mewarisi dari satu kelas dasar Obyek dan dibuat hanya di heap) Jawa jauh lebih mudah daripada pemrograman C++. Pengembang harus mengambil keputusan lebih sedikit dan mengatasi lebih sedikit rintangan.

Penanganan Pengecualian: Menangani Kesalahan

Sejak awal bahasa pemrograman, penanganan kesalahan telah menjadi salah satu topik yang paling rumit. Sangat sulit untuk mengembangkan mekanisme penanganan kesalahan yang baik, begitu banyak bahasa mengabaikan masalah ini, menyerahkannya kepada pengembang perpustakaan perangkat lunak. Yang terakhir memberikan solusi setengah jalan yang bekerja dalam banyak situasi, tetapi seringkali dapat dengan mudah dilewati (biasanya hanya dengan tidak memperhatikannya). Masalah utama dengan banyak mekanisme penanganan pengecualian adalah bahwa mereka bergantung pada kepatuhan hati-hati programmer terhadap aturan yang tidak ditegakkan oleh bahasa. Jika programmer ceroboh - dan ini sering terjadi ketika pekerjaan sedang terburu-buru - ia dapat dengan mudah melupakan mekanisme ini.

Mekanisme penanganan eksepsi membangun penanganan kesalahan langsung ke dalam bahasa pemrograman, atau bahkan ke dalam sistem operasi. Pengecualian adalah objek yang dilemparkan ke lokasi kesalahan, yang kemudian dapat "ditangkap" oleh penangan pengecualian yang sesuai yang dirancang untuk jenis kesalahan tertentu. Penanganan pengecualian tampaknya menentukan jalur eksekusi program paralel yang berlaku ketika sesuatu tidak berjalan sesuai rencana. Dan karena mendefinisikan jalur eksekusi terpisah, kode penanganan kesalahan tidak tercampur dengan kode normal. Ini menyederhanakan penulisan program karena Anda tidak harus terus-menerus memeriksa kemungkinan kesalahan. Selain itu, pengecualian tidak seperti kode kesalahan numerik yang dikembalikan oleh suatu metode, atau set bendera jika terjadi situasi masalah, yang terakhir dapat diabaikan. Pengecualian tidak dapat diabaikan, dijamin akan ditangani di suatu tempat. Akhirnya, pengecualian memungkinkan untuk memulihkan operasi normal program setelah operasi yang salah. Alih-alih hanya menghentikan program, Anda dapat memperbaiki situasi dan melanjutkan menjalankannya; sehingga meningkatkan keandalan program.

Mekanisme penanganan pengecualian di Jawa menonjol dari bahasa-bahasa lainnya karena bahasa tersebut dibangun ke dalam bahasa tersebut sejak awal dan merupakan tanggung jawab pengembang untuk menggunakannya. Ini adalah satu-satunya cara yang dapat diterima untuk melaporkan kesalahan. Jika Anda tidak menulis kode untuk penanganan pengecualian yang tepat, Anda akan mendapatkan kesalahan pada waktu kompilasi. Pendekatan yang konsisten seperti itu terkadang sangat menyederhanakan penanganan kesalahan.

Perlu dicatat bahwa penanganan pengecualian bukanlah fitur dari bahasa berorientasi objek, meskipun dalam bahasa ini pengecualian biasanya diwakili oleh objek. Mekanisme seperti itu ada bahkan sebelum munculnya bahasa berorientasi objek.

Pemrograman paralel

Salah satu konsep dasar pemrograman adalah ide untuk melakukan banyak hal secara bersamaan. Banyak tugas memerlukan program untuk menghentikan pekerjaannya saat ini, menyelesaikan beberapa tugas lain, dan kemudian kembali ke proses utama. Masalahnya diselesaikan dengan cara yang berbeda.
Pada awalnya, programmer yang mengetahui arsitektur mesin menulis prosedur penanganan interupsi, yaitu penghentian proses utama dilakukan di tingkat perangkat keras. Solusi ini bekerja dengan baik, tetapi kompleks dan non-seluler, yang membuatnya jauh lebih sulit untuk mem-porting program semacam itu ke komputer jenis baru.

Terkadang interupsi benar-benar diperlukan untuk memproses operasi tugas kritis waktu, tetapi ada seluruh kelas tugas di mana Anda hanya perlu memecah tugas menjadi beberapa bagian yang dieksekusi secara terpisah sehingga program bereaksi lebih cepat terhadap pengaruh eksternal. Bagian program yang dieksekusi secara terpisah ini disebut aliran, dan seluruh prinsip disebut konkurensi(konkurensi), atau komputasi paralel. Contoh umum dari konkurensi adalah antarmuka pengguna. Dalam program berulir, pengguna dapat menekan tombol dan mendapatkan respons cepat tanpa menunggu program menyelesaikan operasi saat ini.

Biasanya, utas hanya menentukan bagaimana waktu satu prosesor dialokasikan. Tetapi jika sistem operasi mendukung banyak prosesor, setiap utas dapat ditetapkan ke prosesor terpisah; ini adalah bagaimana paralelisme sejati dicapai. Salah satu fitur paralelisme yang bagus, pada tingkat bahasa, adalah bahwa programmer tidak perlu mengetahui apakah ada satu atau lebih prosesor dalam sistem. Program ini secara logis dibagi menjadi utas, dan jika mesin memiliki lebih dari satu prosesor, itu berjalan lebih cepat tanpa pengaturan khusus.

Semua ini memberi kesan bahwa aliran sangat mudah digunakan. Tapi ada masalah: sumber daya bersama. Jika beberapa utas mencoba mengakses sumber daya yang sama secara bersamaan, masalah akan muncul. Misalnya, dua proses tidak dapat secara bersamaan mengirim informasi ke printer. Untuk mencegah konflik, sumber daya bersama (seperti printer) harus dikunci saat digunakan. Utas mengunci sumber daya, menyelesaikan operasinya, lalu melepaskan kunci sehingga orang lain dapat mengakses sumber daya.

Dukungan konkurensi dibangun ke dalam bahasa Jawa, dan dengan keluaran Jawa SE5 itu menambahkan dukungan yang signifikan di tingkat perpustakaan.

Jawa dan Internet

Jika sebuah Jawa adalah bahasa pemrograman lain, muncul pertanyaan: mengapa begitu penting dan mengapa disajikan sebagai langkah revolusioner dalam pengembangan perangkat lunak? Dari sudut pandang tugas pemrograman tradisional, jawabannya tidak langsung jelas. Meskipun bahasa Jawa berguna ketika membangun aplikasi yang berdiri sendiri, aplikasi yang paling penting adalah dan tetap pemrograman untuk jaringan World Wide Web.

Apa itu Web?

Sepintas, Web terlihat agak misterius karena banyaknya istilah baru seperti "berselancar", "kehadiran" dan "halaman rumah". Untuk memahami apa ini, penting untuk memahami gambaran besarnya - tetapi pertama-tama Anda perlu memahami interaksi sistem klien / server, yang merupakan salah satu yang paling tugas yang menantang komputasi komputer.

Komputasi Klien/Server

Ide dasar di balik sistem klien/server adalah bahwa Anda memiliki gudang informasi terpusat - biasanya dalam bentuk database - dan informasi tersebut dikirimkan atas permintaan beberapa kelompok orang atau komputer. Dalam sistem klien/server, penyimpanan informasi terpusat memainkan peran kunci, yang biasanya memungkinkan data untuk dimodifikasi sedemikian rupa sehingga perubahan ini disebarkan ke pengguna informasi. Semua bersama-sama: gudang informasi, perangkat lunak, yang mendistribusikan informasi, dan komputer tempat perangkat lunak dan data disimpan disebut server. Perangkat lunak pada mesin pengguna yang berkomunikasi dengan server, menerima informasi, memprosesnya, dan kemudian menampilkannya dengan tepat disebut klien.

Jadi konsep dasar komputasi klien/server tidak terlalu rumit. Masalah muncul karena satu server mencoba melayani banyak klien secara bersamaan. Biasanya, sistem manajemen basis data terlibat dalam solusi, dan pengembang mencoba "mengoptimalkan" struktur data dengan mendistribusikannya ke dalam tabel. Selain itu, sistem sering mengizinkan klien untuk menambahkan informasi baru ke server. Dan ini berarti bahwa informasi baru klien harus dilindungi dari kehilangan selama penyimpanan dalam database, serta dari kemungkinan menimpanya dengan data dari klien lain. (Ini disebut pemrosesan transaksi.) Ketika Anda mengubah perangkat lunak klien, Anda tidak hanya harus mengkompilasi dan mengujinya, tetapi juga menginstalnya pada mesin klien, yang bisa jauh lebih sulit dan mahal daripada yang Anda kira. Sangat sulit untuk mengatur dukungan untuk banyak sistem operasi dan arsitektur komputer yang berbeda. Akhirnya, perlu diperhitungkan faktor terpenting kinerja: server dapat menerima ratusan permintaan pada saat yang sama, dan penundaan sekecil apa pun mengancam dengan konsekuensi serius. Untuk mengurangi latensi, pemrogram mencoba mendistribusikan perhitungan, seringkali bahkan pada mesin klien, dan terkadang mentransfernya ke mesin server tambahan, menggunakan apa yang disebut perangkat tengah (perangkat tengah). (Program proxy juga mempermudah pemeliharaan program.)

Ide sederhana untuk menyebarkan informasi antar manusia memiliki begitu banyak tingkat kerumitan dalam implementasinya sehingga secara umum, solusinya tampaknya tidak mungkin tercapai. Namun itu sangat penting: sekitar setengah dari semua tugas pemrograman didasarkan padanya. Ini terlibat dalam memecahkan masalah mulai dari pemrosesan pesanan dan transaksi kartu kredit hingga penyebaran semua jenis data - ilmiah, pemerintah, harga saham ... daftarnya tidak ada habisnya. Di masa lalu, Anda harus membuat solusi terpisah untuk setiap tugas baru. Solusi ini tidak mudah dibuat, bahkan lebih sulit digunakan, dan pengguna harus mempelajari antarmuka baru dengan setiap program baru. Tugas komputasi klien/server membutuhkan pendekatan yang lebih luas.

Web itu seperti server raksasa

Faktanya, web adalah salah satu sistem klien/server yang sangat besar. Namun, itu tidak semua: jaringan tunggal semua server dan klien hidup berdampingan secara bersamaan. Namun, fakta ini seharusnya tidak menarik bagi Anda, karena biasanya Anda terhubung dan berinteraksi hanya dengan satu server (bahkan jika Anda harus mencarinya di seluruh dunia).

Pada awalnya, pertukaran informasi searah yang sederhana digunakan. Anda membuat permintaan ke server, itu mengirimi Anda file yang program pemirsa Anda (yaitu, klien) diproses untuk Anda. Namun segera, hanya mendapatkan halaman statis dari server tidak cukup. Pengguna ingin memanfaatkan sepenuhnya sistem klien/server, mengirim informasi dari klien ke server untuk, misalnya, menelusuri database server, menambahkan informasi baru ke server, atau memesan (yang memerlukan tindakan keamanan khusus) . Kami terus mengamati perubahan ini dalam proses pengembangan web.

Alat penjelajahan web (browser) merupakan langkah maju yang besar: mereka memperkenalkan konsep informasi yang ditampilkan dengan cara yang sama pada semua jenis komputer. Namun, browser pertama masih primitif dan dengan cepat berhenti memenuhi persyaratan. Mereka ternyata tidak terlalu interaktif dan memperlambat kerja server dan Internet secara keseluruhan - untuk tindakan apa pun yang memerlukan pemrograman, Anda harus mengirim informasi ke server dan menunggu untuk memprosesnya. Terkadang Anda harus menunggu beberapa menit hanya untuk mengetahui bahwa Anda melewatkan satu huruf dalam permintaan. Karena browser hanya sebagai penampil, browser tidak dapat melakukan tugas pemrograman yang paling sederhana sekalipun. (Di sisi lain, ini menjamin keamanan - pengguna dilindungi dari menjalankan program yang mengandung virus atau bug.)

Berbagai pendekatan telah dilakukan untuk mengatasi masalah-masalah tersebut. Untuk memulainya, standar tampilan grafik telah ditingkatkan sehingga browser dapat menampilkan animasi dan video. Tugas yang tersisa membutuhkan kemampuan untuk menjalankan program di mesin klien, di dalam browser. Ini disebut pemrograman sisi klien.

Pemrograman Sisi Klien

Awalnya, sistem interaksi server-browser dirancang untuk konten interaktif, tetapi dukungan untuk interaktivitas ini sepenuhnya dipercayakan ke server. Server menghasilkan halaman statis untuk browser klien, yang hanya memproses dan menampilkannya. Standar HTML mendukung input paling sederhana: bidang teks, tombol radio, kotak centang, daftar, dan drop-down, bersama dengan tombol yang hanya dapat melakukan dua hal: mengatur ulang data formulir dan mengirimkannya ke server. Informasi yang dikirim diproses oleh antarmuka CGI (Antarmuka Gerbang Umum), didukung oleh semua server web. Teks permintaan menunjukkan CGI bagaimana menangani data. Paling sering, berdasarkan permintaan, sebuah program diluncurkan dari direktori cgi-bin di server. (Sesuai dengan alamat halaman di browser, setelah mengirimkan data formulir, Anda terkadang dapat melihat substring dalam kekacauan karakter cgi-bin.) Program tersebut dapat ditulis dalam hampir semua bahasa. Biasanya digunakan Perl, karena berorientasi teks dan juga bahasa yang ditafsirkan, oleh karena itu, dapat digunakan di server mana pun, terlepas dari jenis prosesor atau sistem operasinya. Namun, bahasa Python(Bahasa favorit saya - pergi ke www.Python.org) secara bertahap memenangkan kembali "wilayah" darinya karena kekuatan dan kesederhanaannya.

Banyak server web yang kuat saat ini beroperasi sepenuhnya berdasarkan CGI; pada prinsipnya, teknologi ini memungkinkan Anda untuk menyelesaikan hampir semua masalah. Namun, server web dibangun di atas CGI program sulit untuk dipertahankan dan memiliki masalah daya tanggap. Waktu merespon CGI-program tergantung pada jumlah informasi yang dikirim, serta pada beban server dan jaringan. (Karena semua peluncuran yang disebutkan CGI program mungkin memakan waktu lama). Perancang awal web tidak memperkirakan seberapa cepat sumber daya sistem akan habis karena digunakan dalam berbagai aplikasi. Misalnya, hampir tidak mungkin untuk menampilkan grafik waktu nyata di dalamnya, karena dengan perubahan situasi apa pun, Anda perlu membuat file GIF baru dan mentransfernya ke klien. Tidak diragukan lagi Anda pernah mengalami pengalaman pahit sendiri - misalnya, dari sekadar mengirimkan data formulir. Anda menekan tombol untuk mengirim informasi; server dimulai CGI- program yang mendeteksi kesalahan, menghasilkan HTML- halaman yang memberi tahu Anda tentang hal itu, dan kemudian mengirimkan halaman ini ke arah Anda; Anda harus mengetik ulang data dan coba lagi. Tidak hanya ini lambat, itu juga tidak elegan.

Masalahnya diselesaikan dengan pemrograman di sisi klien. Sebagai aturan, browser berjalan di komputer canggih yang mampu menyelesaikan berbagai tugas, dan dengan pendekatan standar berdasarkan HTML komputer hanya menunggu untuk dilayani halaman berikutnya. Dengan pemrograman sisi klien, browser diberikan semua pekerjaan yang dapat dilakukannya, dan bagi pengguna, ini berarti penjelajahan web yang lebih cepat dan interaktivitas yang lebih baik.

Namun, membahas tentang pemrograman client tidak jauh berbeda dengan pembahasan tentang pemrograman pada umumnya. Kondisinya sama, tetapi platformnya berbeda: browser menyerupai sistem operasi yang sangat terpotong. Anda tetap harus memprogram, jadi pemrograman sisi klien menciptakan serangkaian masalah dan solusi yang memusingkan. Bagian ini diakhiri dengan gambaran umum tentang beberapa masalah dan pendekatan yang melekat dalam pemrograman sisi klien.

Modul ekspansi

Salah satu area terpenting dalam pemrograman klien adalah pengembangan modul ekstensi ( plug-in). Pendekatan ini memungkinkan programmer untuk menambahkan fungsionalitas baru ke browser dengan mengunduh program kecil yang dibangun ke dalam browser. Faktanya, mulai saat ini, browser memperoleh fungsionalitas baru. (Modul ekstensi hanya dimuat sekali.) Plugin telah menyediakan browser dengan sejumlah inovasi yang cepat dan kuat, tetapi menulis modul seperti itu bukanlah tugas yang mudah, dan kecil kemungkinan Anda ingin membuat ekstensi setiap kali Anda membuat situs baru. Nilai plug-in untuk pemrograman klien adalah bahwa mereka memungkinkan programmer berpengalaman untuk menambahkan fitur baru ke browser tanpa meminta izin dari pembuatnya. Dengan demikian, modul ekstensi menyediakan "pintu belakang" untuk mengintegrasikan bahasa pemrograman baru di sisi klien (walaupun tidak semua bahasa diimplementasikan dalam modul tersebut).

Bahasa skrip

Perkembangan plug-in telah melahirkan banyak bahasa scripting. Menggunakan bahasa skrip, Anda menyematkan program klien langsung ke HTML-page, dan modul yang memproses bahasa ini secara otomatis diaktifkan saat melihatnya. Bahasa skrip biasanya cukup mudah dipelajari; pada intinya, script code adalah teks yang merupakan bagian dari HTML-pages, sehingga memuat dengan sangat cepat sebagai bagian dari satu permintaan ke server selama pengambilan halaman. Harga untuk ini adalah siapa pun dapat melihat (dan mencuri) kode Anda. Namun, sepertinya Anda tidak akan menulis sesuatu yang ditiru dan canggih dalam bahasa skrip, jadi masalah penyalinan kode tidak terlalu buruk.

Bahasa skrip yang didukung oleh hampir semua browser tanpa menginstal modul tambahan adalah JavaScript(memiliki sedikit kesamaan dengan Jawa; nama itu digunakan untuk "mengambil" sepotong kesuksesan Jawa di pasar). Sayangnya, implementasi asli JavaScript di browser yang berbeda sangat berbeda satu sama lain dan bahkan antara versi yang berbeda dari browser yang sama. Standardisasi JavaScript dalam bentuk Skrip ECMA berguna, tetapi butuh waktu agar dukungannya muncul di semua browser (selain itu, perusahaan Microsoft secara aktif mempromosikan bahasa mereka sendiri VBScript, samar-samar menyerupai JavaScript). Dalam kasus umum, pengembang harus membatasi dirinya pada kemungkinan minimum JavaScript sehingga kodenya dijamin work di semua browser. Mengenai penanganan kesalahan dan kode debug JavaScript, maka ini adalah tugas yang paling sulit. Hanya baru-baru ini pengembang dapat membuat yang benar-benar sistem yang kompleks ditulis dalam JavaScript(perusahaan Google, melayani Gmail), dan itu membutuhkan antusiasme dan pengalaman tertinggi.

Ini menunjukkan bahwa bahasa skrip yang digunakan di browser dirancang untuk berbagai tugas tertentu, terutama untuk membuat antarmuka pengguna grafis yang lebih kaya dan lebih interaktif ( GUI). Namun, bahasa skrip dapat digunakan untuk 80% tugas pemrograman klien. Tugas Anda mungkin hanya di 80% itu. Karena bahasa scripting membuatnya mudah dan cepat untuk dibuat kode pemrograman, Anda harus terlebih dahulu mempertimbangkan bahasa seperti itu sebelum beralih ke solusi teknologi yang lebih kompleks seperti Jawa.

Jawa

Jika bahasa scripting mengambil 80% dari tugas pemrograman klien, lalu siapa yang dapat menangani 20% lainnya? Bagi mereka, solusi paling populer saat ini adalah Jawa. Tidak hanya itu bahasa pemrograman yang kuat yang dirancang dengan keamanan, kompatibilitas platform, dan internasionalisasi dalam pikiran, tetapi juga alat yang terus berkembang dengan fitur dan perpustakaan baru yang elegan sesuai dengan tugas pemrograman tradisional yang kompleks: multitasking, akses database, pemrograman jaringan, dan komputasi terdistribusi. Pemrograman klien Jawa bermuara pada pengembangan applet, serta penggunaan paket Mulai Web Java.

Applet adalah program mini yang hanya dapat berjalan di dalam browser. Applet secara otomatis dimuat sebagai bagian dari halaman web (dengan cara yang sama, misalnya, grafik dimuat). Ketika applet diaktifkan, itu mengeksekusi program. Ini adalah salah satu keuntungan dari applet - memungkinkan Anda untuk secara otomatis mendistribusikan program ke klien dari server tepat ketika pengguna membutuhkan program ini, dan bukan sebelumnya. Pengguna menerima versi terbaru dari program klien, tanpa masalah dan kesulitan yang terkait dengan penginstalan ulang. Menurut ideologi Jawa, programmer hanya membuat satu program yang secara otomatis berjalan di semua komputer yang memiliki browser dengan penerjemah bawaan Jawa. (Hal ini berlaku untuk hampir semua komputer.) Karena Jawa adalah bahasa pemrograman yang lengkap, sebanyak mungkin pekerjaan harus dilakukan di sisi klien sebelum (atau setelah) memanggil server. Misalnya, Anda tidak perlu mengirim permintaan melalui Internet untuk mengetahui bahwa ada kesalahan dalam data yang diterima atau beberapa parameter, dan komputer klien dapat dengan cepat menggambar semacam grafik tanpa menunggu server melakukannya dan mengirim kembali file gambar. Skema ini tidak hanya memberikan manfaat kecepatan dan daya tanggap langsung, tetapi juga mengurangi beban pada transportasi jaringan utama dan server, mencegah perlambatan dalam pengalaman Internet secara keseluruhan.

Alternatif

Sejujurnya, applet Jawa tidak membenarkan antusiasme awal. Pada penampilan pertama Jawa semua orang sangat antusias dengan applet karena mereka memungkinkan pemrograman sisi klien yang serius, peningkatan responsivitas, dan pengurangan bandwidth untuk aplikasi Internet. Applet diprediksi memiliki masa depan yang cerah.

Memang, sejumlah applet yang sangat menarik dapat ditemukan di Web. Namun transisi massal ke applet tidak terjadi. Mungkin masalah utamanya adalah mengunduh paket 10 MB untuk menginstal lingkungan Lingkungan Waktu Proses Java (JRE) terlalu menakutkan untuk rata-rata pengguna. Fakta bahwa perusahaan Microsoft tidak menyala JRE dalam pengiriman Internet Explorer, akhirnya memutuskan nasib applet. Bagaimanapun, applet Jawa belum banyak digunakan.

Namun, applet dan aplikasi Mulai Web Java sangat berguna dalam beberapa situasi. Jika konfigurasi komputer pengguna akhir terkendali (misalnya, dalam organisasi), penggunaan teknologi ini untuk mendistribusikan dan memperbarui aplikasi klien cukup dibenarkan; menghemat banyak waktu, tenaga dan uang (terutama dengan sering update).

.NET dan C#

Untuk beberapa waktu pesaing utama Jawa-applet dianggap sebagai komponen ActiveX dari perusahaan Microsoft, meskipun mereka membutuhkan kehadiran di mesin klien jendela. Sekarang Microsoft menentang Jawa pesaing penuh: ini adalah platform .BERSIH dan bahasa pemrograman DARI#. Platform .BERSIH kira-kira sama dengan mesin virtual Jawa(JVM) dan perpustakaan Jawa, dan bahasa DARI# memiliki kemiripan yang jelas dengan bahasa Jawa. Tanpa ragu, ini adalah yang terbaik yang dibuat Microsoft di bidang bahasa dan lingkungan pemrograman. Tentu saja, para pengembang Microsoft memiliki beberapa keuntungan; mereka melihat itu di Jawa berhasil dan apa yang tidak, dan dapat membangun fakta-fakta ini, tetapi hasilnya ternyata cukup layak. Untuk pertama kalinya sejak kelahirannya, Jawa ada pesaing nyata. Pengembang dari Matahari harus melihat DARI#, cari tahu mengapa pemrogram mungkin ingin beralih ke bahasa ini, dan lakukan segala upaya untuk meningkatkannya secara serius Jawa di Jawa SE5.

PADA saat ini pertanyaan utamanya adalah apakah Microsoft akan mengizinkan porting penuh dari .BERSIH ke platform lain. PADA Microsoft mengklaim bahwa tidak ada masalah dalam hal ini, dan proyek mono() menyediakan implementasi parsial .BERSIH untuk linux. Namun, karena implementasi ini tidak lengkap, untuk saat ini Microsoft tidak memutuskan untuk membuang bagian apa pun darinya, untuk bertaruh .BERSIH sebagai teknologi lintas platform masih awal.

Internet dan intranet

Web menyediakan solusi paling umum untuk tugas klien/server, jadi masuk akal untuk menggunakan teknologi yang sama untuk memecahkan masalah tertentu; ini terutama berlaku untuk interaksi klien / server klasik di dalam perusahaan. Pendekatan klien/server tradisional memiliki masalah dengan perbedaan jenis komputer klien, menambah kesulitan menginstal program baru untuk klien; kedua masalah diselesaikan oleh browser dan pemrograman sisi klien. Ketika teknologi web digunakan untuk membentuk jaringan informasi dalam suatu perusahaan, jaringan seperti itu disebut intranet. Intranet memberikan lebih banyak keamanan daripada Internet karena Anda dapat mengontrol akses secara fisik ke server perusahaan Anda. Dalam hal pembelajaran, jauh lebih mudah bagi seseorang yang memahami konsep browser untuk memahami halaman dan applet yang berbeda, sehingga waktu untuk menguasai sistem baru berkurang.

Masalah keamanan membawa kita ke salah satu arah yang secara otomatis muncul dalam pemrograman klien. Jika program Anda berjalan di Internet, maka Anda tidak tahu platform apa yang akan dijalankannya. Perhatian khusus harus diberikan untuk menghindari penyebaran kode yang salah. Di sini kita membutuhkan solusi lintas platform dan aman, seperti Jawa atau bahasa skrip.

Intranet memiliki batasan lain. Cukup sering, semua mesin di jaringan berjalan di platform Intel/Windows. Di intranet, Anda bertanggung jawab atas kualitas kode Anda dan dapat memperbaiki bug saat ditemukan. Selain itu, Anda mungkin sudah memiliki kumpulan solusi yang terbukti bekerja di sistem klien/server yang lebih tradisional, sementara perangkat lunak baru harus diinstal secara manual pada mesin klien dengan setiap peningkatan. Waktu yang dihabiskan untuk pembaruan adalah argumen terkuat yang mendukung teknologi browser, di mana pembaruan dilakukan tanpa terlihat dan secara otomatis (hal yang sama dapat dilakukan Mulai Web Java). Jika Anda terlibat dalam pemeliharaan intranet, lebih bijaksana untuk mengambil jalur yang memungkinkan Anda memanfaatkan apa yang sudah Anda miliki tanpa harus menulis ulang program dalam bahasa baru.

Ketika dihadapkan dengan banyaknya tugas pemrograman klien yang dapat membuat bingung desainer mana pun, yang terbaik adalah mengevaluasinya dalam hal rasio biaya/manfaat. Pertimbangkan keterbatasan masalah Anda dan coba bayangkan cara terpendek untuk menyelesaikannya. Karena pemrograman klien masih pemrograman, teknologi pengembangan yang menjanjikan solusi tercepat selalu relevan. Sikap proaktif ini akan memberi Anda kesempatan untuk bersiap menghadapi masalah pemrograman yang tak terhindarkan.

Pemrograman Sisi Server

Diskusi kami telah melewati subjek pemrograman sisi server, yang dianggap paling banyak oleh banyak orang titik kuat Jawa. Apa yang terjadi ketika Anda mengirim permintaan ke server? Lebih sering daripada tidak, permintaan bermuara pada permintaan "kirim saya file ini" yang sederhana. Browser kemudian memproses file dengan tepat: as HTML-halaman seperti gambar seperti Jawa-applet, seperti skrip, dll.

Permintaan yang lebih kompleks ke server biasanya melibatkan pengaksesan database. Dalam kasus yang paling umum, pencarian basis data yang kompleks diminta, yang hasilnya kemudian diubah oleh server menjadi HTML-halaman dan mengirimkan kepada Anda. (Tentu saja, jika klien dapat melakukan beberapa tindakan menggunakan Jawa atau bahasa scripting, data dapat diproses olehnya, yang akan lebih cepat dan mengurangi beban server.) Atau Anda mungkin perlu mendaftar di database saat bergabung dengan grup, atau checkout, yang akan memerlukan perubahan pada database. Permintaan tersebut harus diproses oleh beberapa kode di server; secara umum, inilah yang disebut pemrograman sisi server. Secara tradisional, pemrograman server dilakukan pada Perl, Python, C++ atau bahasa lain yang memungkinkan Anda membuat program CGI, tetapi ada opsi yang lebih menarik. Ini termasuk yang didasarkan pada Jawa server web yang memungkinkan Anda melakukan pemrograman sisi server di Jawa menggunakan apa yang disebut servlet. Servlet dan keturunannya JSP, adalah dua alasan utama mengapa perusahaan konten web pindah ke Jawa, terutama karena mereka memecahkan masalah ketidakcocokan lintas-browser.

Terlepas dari semua pembicaraan tentang Jawa sebagai bahasa pemrograman internet, Jawa pada kenyataannya, ini adalah bahasa pemrograman lengkap yang mampu menyelesaikan hampir semua masalah yang diselesaikan dalam bahasa lain. Keuntungan Jawa tidak terbatas pada portabilitas yang baik: itu adalah kesesuaian untuk memecahkan masalah pemrograman, dan ketahanan kesalahan, dan perpustakaan standar yang besar, dan banyak pengembangan pihak ketiga - baik yang sudah ada maupun yang terus muncul.

Ringkasan

Anda tahu seperti apa program prosedural: definisi data dan panggilan fungsi. Mencari tahu tujuan dari program semacam itu membutuhkan usaha dengan melihat fungsi dan membuat gambaran besar dalam pikiran Anda. Karena itulah pembuatan program semacam itu memerlukan penggunaan alat perantara - mereka sendiri lebih berorientasi pada komputer, dan bukan pada tugas yang sedang diselesaikan.

Karena OOP menambahkan banyak konsep baru ke konsep yang sudah tersedia dalam bahasa prosedural, wajar untuk mengasumsikan bahwa kode tersebut Jawa akan jauh lebih rumit daripada metode serupa dalam bahasa prosedural. Tapi di sini kejutan yang menyenangkan menanti Anda: program yang ditulis dengan baik di Jawa biasanya jauh lebih mudah dipahami daripada rekan proseduralnya. Yang Anda lihat hanyalah definisi objek yang mewakili konsep ruang keputusan (bukan konsep implementasi komputer), dan pesan yang dikirim ke objek yang mewakili tindakan di ruang itu. Salah satu kelebihan OOP adalah program yang dirancang dengan baik dapat dipahami hanya dengan melihat kode sumbernya. Selain itu, Anda biasanya harus menulis lebih sedikit kode, karena banyak tugas sudah dapat diselesaikan dengan mudah. perpustakaan yang ada kelas.

Pemrograman dan bahasa berorientasi objek Jawa tidak cocok untuk semua orang. Sangat penting untuk mengetahui kebutuhan Anda terlebih dahulu untuk memutuskan apakah beralih ke Jawa atau lebih baik memilih sistem pemrograman lain (termasuk yang sedang Anda gunakan). Jika Anda tahu bahwa di masa mendatang Anda akan dihadapkan pada kebutuhan yang sangat spesifik atau pekerjaan Anda akan dikenakan pembatasan yang Jawa tidak mengatasi, lebih baik untuk mempertimbangkan kemungkinan lain (khususnya, saya sarankan untuk melihat lebih dekat pada bahasa ular piton,). Memilih Jawa, Anda perlu memahami opsi lain apa yang tersedia dan mengapa Anda memilih jalur ini.

Pertukaran pesan:

Kirim langsung ke sisi ini: http://website/javabooks/Thinking_in_Java_4th_edition.html Kirim kode BB: Thinking_in_Java_4th_edition
html-pesan: