1. Objek dan kelas

Hari ini Anda akan belajar sedikit tentang cara kerja program Java pada umumnya. Inilah berita besarnya: setiap program Java terdiri dari kelas dan objek.

Anda sudah tahu apa itu class, tapi apa itu object?

Saya akan mulai dengan sebuah analogi. Bayangkan Anda ingin membuat kapal kecil. Pertama Anda perlu membuat cetak biru dan kemudian memberikannya ke pabrik, di mana kapal akan dibangun sesuai dengan cetak biru tersebut. Atau mungkin lusinan. Atau kapal sebanyak yang Anda suka. Lusinan kapal identik dibangun menurut satu cetak biru. Itu yang penting di sini.

Itu sama dalam pemrograman Java.

Cetak biru

Seorang programmer seperti seorang desainer. Seorang desainer membuat cetak biru, dan seorang programmer Java menulis kelas. Bagian dibuat berdasarkan cetak biru, dan objek dibuat berdasarkan kelas.

Pertama, kita menulis kelas (membuat cetak biru), dan kemudian, saat program berjalan, mesin Java membuat objek berdasarkan kelas ini. Dengan cara yang sama kapal dibuat dari cetak biru.

Hanya ada satu cetak biru, tetapi bisa ada banyak kapal. Kapal-kapal itu berbeda — mereka memiliki nama yang berbeda dan membawa muatan yang berbeda. Tapi mereka sangat mirip: mereka semua memiliki desain yang sama dan dapat melakukan tugas serupa.

Atau inilah analogi lain...

Sarang semut

Sarang semut adalah contoh yang baik tentang bagaimana objek berinteraksi. Ada tiga kelas semut di sarang semut sederhana: ratu, prajurit, dan pekerja.

Jumlah semut tiap kelas berbeda-beda. Ada satu ratu untuk seluruh sarang semut, tetapi ada puluhan tentara, dan ratusan semut pekerja. Tiga kelas dan ratusan objek. Semut berinteraksi satu sama lain — dengan semut dari kelas yang sama dan dengan semut dari kelas lain — menurut aturan yang kaku.

Ini adalah contoh sempurna. Semuanya persis seperti ini dalam program tipikal. Ada objek utama yang membuat objek dari semua kelas lainnya. Objek mulai berinteraksi satu sama lain dan dengan "dunia luar" program. Perilaku objek di-hardcode secara internal.

Kedua analogi ini adalah dua sisi dari mata uang yang sama. Kebenaran ada di tengah. Contoh pertama (tentang cetak biru dan kapal) menunjukkan hubungan antara kelas dan objek dari kelas tersebut. Ini adalah analogi yang kuat. Contoh kedua (tentang sarang semut) menunjukkan hubungan antara kelas tertulis dan objek yang ada saat program berjalan.

Anda harus terlebih dahulu menulis kelas untuk setiap objek yang akan ada dalam program, dan kemudian juga menjelaskan bagaimana mereka berinteraksi. Ya, itu benar, tapi ini lebih mudah dari kedengarannya.

Di Java, semua entitas adalah objek saat runtime, dan menulis program adalah tentang menjelaskan berbagai cara objek berinteraksi. Objek cukup memanggil metode satu sama lain dan meneruskan data yang diperlukan kepada mereka.

Dokumentasi

Dan bagaimana Anda tahu data apa yang akan diteruskan ke metode? Orang-orang yang datang sebelum Anda memikirkan segalanya.

Setiap kelas biasanya memiliki deskripsi yang mengatakan untuk apa kelas itu dibuat. Juga, setiap metode publik biasanya memiliki deskripsi yang menunjukkan apa yang dilakukannya dan data apa yang perlu diteruskan ke sana.

Untuk menggunakan kelas, Anda harus memiliki gambaran umum tentang fungsinya. Dan Anda perlu tahu persis apa yang dilakukan masing-masing metode. Tetapi Anda sama sekali tidak perlu tahu bagaimana melakukannya. Ini seperti tongkat sihir.

Mari kita lihat kode untuk menyalin file:

Menyalin file c:\\data.txt ke file c:\\result.txt
package com.codegym.lesson2;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy
{
   public static void main(String[] args) throws IOException
   {
      FileInputStream fileInputStream = new FileInputStream("c:\\data.txt");
      FileOutputStream fileOutputStream = new FileOutputStream("c:\\result.txt");

      while (fileInputStream.available() > 0)
      {
         int data = fileInputStream.read();
         fileOutputStream.write(data);
      }

      fileInputStream.close();
      fileOutputStream.close();
   }
}

Jika Anda membaca kode ini baris demi baris, Anda dapat menebak fungsinya secara umum. Meskipun itu membutuhkan pengalaman dan latihan. Setelah beberapa saat, kode ini akan tampak familier dan dapat dimengerti oleh Anda.


2. Merancang program

Desain program adalah keseluruhan seni. Ini sekaligus sederhana dan sulit. Sederhana, karena tidak ada hukum yang tegas: apapun yang tidak dilarang diperbolehkan. Nah, dan itu juga yang membuatnya sulit: ada banyak cara untuk melakukan sesuatu dan tidak mudah menemukan yang terbaik.

Merancang program seperti menulis buku. Di satu sisi, Anda hanya menulis huruf, kata, dan kalimat. Di sisi lain, plot, karakter, kontradiksi internal, konflik, gaya penceritaan, intrik, dll.

Hal utama adalah memahami untuk siapa Anda menulis kode. Dan Anda menulis kode untuk pemrogram lain .

Pengembangan produk pasti berarti membuat perubahan: sesuatu ditambahkan di sini, sesuatu yang lain dihapus di sana, sesuatu didesain ulang. Begitulah proyek besar, besar dan raksasa lahir dari iterasi kecil.

Yang paling penting untuk kode adalah kode itu harus dapat dimengerti oleh pemrogram lain. Kode yang salah yang dapat dimengerti dapat diperbaiki. Kode yang benar tetapi tidak dapat dipahami tidak dapat diperbaiki.  Yang bisa Anda lakukan hanyalah membuangnya.

Jadi bagaimana Anda menulis kode yang baik dan bersih?

Melakukan ini membutuhkan tiga hal:

  • Menulis kode yang baik dan mudah dipahami di dalam metode — ini adalah persyaratan termudah
  • Memutuskan entitas mana yang harus disertakan dalam program
  • Memisahkan program menjadi bagian-bagian logis dengan benar

Apa yang ada di balik konsep-konsep ini?

Menulis kode yang baik di dalam metode

Bahkan jika Anda memiliki keterampilan bahasa Inggris dasar, Anda mungkin telah memperhatikan betapa mudahnya membaca kode sebagai kalimat bahasa Inggris kadang-kadang:

  • class Cat extends Pet— Ini berarti class Cat memperluas class Pet
  • while(stream.ready())- selama aliran siap ...
  • if (a<b) return a; else return b— jika akurang dari b, maka return a, jika tidak return b.

Ini disengaja. Java adalah salah satu dari beberapa bahasa yang memudahkan penulisan kode dokumentasi mandiri, yaitu kode yang dapat dimengerti tanpa komentar. Dalam kode Java yang bagus, banyak metode membaca seperti kalimat bahasa Inggris.

Saat menulis kode, tugas Anda adalah membuatnya sesederhana dan seringkas mungkin. Coba pikirkan apakah kode Anda mudah dibaca dan Anda akan mulai bergerak ke arah yang benar.

Di Jawa, merupakan kebiasaan untuk menulis kode yang mudah dibaca. Sebaiknya, semua kode untuk suatu metode akan dimuat dalam satu layar (yaitu 20-30 baris). Ini adalah norma bagi seluruh masyarakat Jawa. Jika kode dapat diperbaiki, itu harus diperbaiki.

Cara terbaik untuk mempelajari cara menulis kode yang baik adalah melalui latihan. Tulis banyak kode, pelajari kode orang lain, dan minta kolega yang lebih berpengalaman untuk meninjau kode Anda.

Dan ingatlah bahwa saat Anda berkata pada diri sendiri "pergilah dengan cukup baik", pertumbuhan Anda berhenti.

Memutuskan entitas mana yang harus disertakan dalam program

Anda perlu menulis kode yang dapat dipahami oleh pemrogram lain. Jika 9 dari 10 pemrogram akan menyertakan kelas A, B, dan C dalam desain program, maka Anda juga harus membuat kelas A, B, dan C dalam program Anda. Anda harus menulis kode yang dapat dipahami orang lain.

Hebat, berfungsi, cepat, tetapi kode non-standar adalah kode yang buruk.

Anda perlu mempelajari proyek orang lain: ini adalah cara terbaik, tercepat, dan termudah untuk menyerap semua kebijaksanaan yang telah terakumulasi dalam industri TI selama beberapa dekade.

Omong-omong, Anda sudah memiliki akses ke proyek yang luar biasa, populer, dan terdokumentasi dengan baik — Java SDK . Mulailah dengan itu.

Menganalisis kelas dan bagaimana mereka diatur. Pikirkan mengapa beberapa metode statis dan yang lainnya tidak. Mengapa metode memiliki parameter spesifik yang mereka miliki tetapi tidak yang lain. Mengapa tepatnya metode ini, dan mengapa kelas diberi nama sesuai namanya, dan mengapa terkandung dalam paket khusus mereka.

Setelah Anda mulai memahami jawaban atas semua pertanyaan ini, Anda akan dapat menulis kode yang dapat dipahami orang lain.

Karena itu, saya ingin memperingatkan Anda agar tidak menganalisis kode dalam metode Java SDK. Banyak metode ditulis ulang untuk memaksimalkan kecepatan, dan keterbacaannya dipertanyakan.

Memisahkan program menjadi bagian-bagian logis dengan benar

Hampir setiap program dibagi menjadi beberapa bagian atau modul. Setiap bagian bertanggung jawab atas aspek programnya sendiri.

Komputer memiliki motherboard, monitor, dan keyboard — ini semua adalah bagian yang terpisah dan digabungkan secara longgar. Terlebih lagi, mereka berinteraksi dengan cara standar: USB, HDMI, dll. Jika Anda menumpahkan kopi ke keyboard, Anda cukup mencucinya di wastafel, biarkan mengering, lalu lanjutkan menggunakannya.

Tapi laptop adalah contoh arsitektur monolitik: sepertinya kita bisa membedakan bagian logis yang terpisah, tapi jauh lebih terintegrasi. Di MacBookPro, Anda harus membongkar setengah dari laptop untuk membersihkan keyboard. Dan menumpahkan kopi Anda di laptop adalah alasan untuk memesan laptop baru. Bukan secangkir kopi baru.


3. Membuat kelas Anda sendiri

Tetapi karena Anda baru belajar memprogram, Anda harus memulai dari yang kecil dengan belajar membuat kelas Anda sendiri.

Tentu saja, Anda telah membuat kelas, tetapi Anda perlu belajar untuk memahami kelas apa yang harus disertakan dalam program, bagaimana seharusnya diberi nama, dan metode apa yang harus dimiliki. Dan bagaimana mereka harus berinteraksi satu sama lain.

Daftar entitas

Jika Anda tidak tahu harus mulai dari mana, mulailah dari awal.

Ketika Anda pertama kali mulai merancang sebuah program, Anda cukup mengambil selembar kertas dan menuliskan daftar entitas (objek) yang harus ada dalam program tersebut. Dan kemudian tulis kode sesuai dengan prinsip bahwa setiap entitas adalah kelas yang terpisah.

Contoh

Katakanlah Anda ingin menulis permainan catur. Anda membutuhkan entitas berikut: papan catur dan 6 jenis bidak catur. Potongan-potongan bergerak dengan cara yang berbeda dan memiliki nilai yang berbeda. Masuk akal bahwa mereka adalah kelas yang terpisah. Memang, saat pertama kali memulai, semakin banyak kelas, semakin baik.

Sangat jarang bertemu programmer pemula yang menulis sepuluh kelas, bukan dua. Alih-alih menulis sepuluh kelas, pemula suka menulis dua kelas atau mungkin hanya satu. Jadi tolong tulis lebih banyak kelas, rekan programmer saya. Dan kode Anda akan menjadi lebih jelas bagi semua orang kecuali mungkin Anda 😛

Catur

Katakanlah kita memutuskan untuk menulis kelas untuk catur: seperti apa kelas ini?

Apakah papan catur hanya berupa larik 8 kali 8? Lebih baik membuat kelas terpisah yang secara internal menyimpan referensi ke array. Kemudian Anda dapat menambahkan banyak metode berguna ke kelas "papan catur", misalnya, untuk memeriksa apakah sel tertentu kosong atau terisi.

Secara umum, saat Anda memulai, selalu berpedoman pada prinsip ini: Program memiliki berbagai entitas, dan entitas memiliki tipe. Tipe ini adalah kelas.


4. Variabel dan metode statis

Juga jangan lupa untuk menggunakan variabel dan metode statis. Jika Anda memiliki satu bidak catur yang berinteraksi dengan yang lain di papan catur, maka kode Anda memerlukan metode yang mengacu pada bidak pertama dan kedua serta papan catur.

Variabel statis, yang dapat diakses dari mana saja dalam program, biasanya digunakan untuk menghindari terus-menerus menyebarkan referensi ke objek yang "selalu ada".

Misalnya, seperti ini:

Kode Catatan
public class ChessBoard
{
   public static ChessBoard board = new ChessBoard();
   public ChessItem[][] cells = new ChessItem[8][8];
   ...
}

public class Game
{
   public static void main(String[] args)
   {
      var board = ChessBoard.board;
      board.cells[0][3] = new King(Color.WHITE);
      board.cells[0][4] = new Queen(Color.WHITE);
      ...
   }
}


Referensi ke satu ChessBoardobjek.
Array dua dimensi 8x8, bukan variabel statis.








Tambahkan potongan ke papan.

Atau alih-alih variabel statis, Anda dapat membuat metode yang mengembalikan objek tunggal. Misalnya, seperti ini:

public class ChessBoard
{
   private static ChessBoard board = new ChessBoard();
   public static ChessBoard getBoard()
   {
      return board;
   }

   public ChessItem[][] cells = new ChessItem[8][8];
   ...
}

public class Game
{
   public static void main(String[] args)
   {
      var board = ChessBoard.getBoard();
      board.cells[0][3] = new King(Color.WHITE);
      board.cells[0][4] = new Queen(Color.WHITE);
      ...
   }
}