1. Mga bagay at klase

Ngayon ay matututo ka ng kaunti tungkol sa kung paano gumagana ang isang karaniwang Java program. Narito ang malaking balita: bawat Java program ay binubuo ng mga klase at bagay.

Alam mo na kung ano ang mga klase, ngunit ano ang mga bagay?

Magsisimula ako sa isang pagkakatulad. Isipin na gusto mong gumawa ng isang maliit na barko. Una kailangan mong lumikha ng isang blueprint at pagkatapos ay ibigay ito sa pabrika, kung saan ang isang barko ay itatayo ayon sa blueprint. O marahil isang dosena. O kahit gaano karaming barko ang gusto mo. Dose-dosenang magkaparehong mga barko ang itinayo ayon sa iisang blueprint. Yun ang importante dito.

Ito ay pareho sa Java programming.

Mga blueprint

Ang isang programmer ay parang isang taga-disenyo. Ang isang taga-disenyo ay gumagawa ng mga blueprint, at isang Java programmer ang nagsusulat ng mga klase. Ang mga bahagi ay nilikha batay sa mga blueprint, at ang mga bagay ay nilikha batay sa mga klase.

Una, nagsusulat kami ng mga klase (gumawa ng mga blueprint), at pagkatapos, habang tumatakbo ang programa, ang Java machine ay lumilikha ng mga bagay batay sa mga klase na ito. Sa parehong paraan na ang mga barko ay nilikha mula sa mga blueprint.

Mayroon lamang isang blueprint, ngunit maaaring mayroong maraming mga barko. Ang mga barko ay naiiba - mayroon silang iba't ibang mga pangalan at nagdadala ng iba't ibang mga kargamento. Ngunit halos magkapareho sila: lahat sila ay may parehong disenyo at maaaring magsagawa ng mga katulad na gawain.

O narito ang isa pang pagkakatulad...

Anthill

Ang anthill ay isang magandang halimbawa kung paano nakikipag-ugnayan ang mga bagay. May tatlong klase ng langgam sa isang simpleng anthill: ang reyna, mga sundalo, at mga manggagawa.

Iba-iba ang bilang ng mga langgam sa bawat klase. Mayroong nag-iisang reyna para sa buong anthill, ngunit may dose-dosenang mga sundalo, at daan-daang manggagawang langgam. Tatlong klase at daan-daang bagay. Nakikipag-ugnayan ang mga langgam sa isa't isa — sa mga langgam ng kanilang parehong klase at sa mga langgam ng ibang klase — ayon sa mahigpit na mga panuntunan.

Ito ang perpektong halimbawa. Ang lahat ay eksakto tulad nito sa isang tipikal na programa. Mayroong pangunahing bagay na lumilikha ng mga bagay ng lahat ng iba pang mga klase. Ang mga bagay ay nagsisimulang makipag-ugnayan sa isa't isa at sa "labas ng mundo" ng programa. Ang pag-uugali ng mga bagay ay panloob na hardcoded.

Ang dalawang pagkakatulad na ito ay dalawang panig ng parehong barya. Ang katotohanan ay nasa gitna. Ang unang halimbawa (tungkol sa isang blueprint at mga barko) ay nagpapakita ng kaugnayan sa pagitan ng isang klase at mga bagay ng klase na iyon. Ito ay isang malakas na pagkakatulad. Ang pangalawang halimbawa (tungkol sa isang anthill) ay nagpapakita ng kaugnayan sa pagitan ng mga nakasulat na klase at ng mga bagay na umiiral habang tumatakbo ang programa.

Kailangan mo munang magsulat ng mga klase para sa bawat bagay na iiral sa programa, at pagkatapos ay ilarawan din kung paano sila nakikipag-ugnayan. Oo, tama iyan, ngunit ito ay mas madali kaysa sa tunog.

Sa Java, ang lahat ng entity ay mga object sa runtime, at ang pagsusulat ng isang program ay tungkol sa paglalarawan ng iba't ibang paraan kung saan nakikipag-ugnayan ang mga object. Ang mga bagay ay tumatawag lamang sa mga pamamaraan ng bawat isa at ipasa ang kinakailangang data sa kanila.

Dokumentasyon

At paano mo malalaman kung anong data ang ipapasa sa mga pamamaraan? Yung mga taong nauna sayo naisip lahat.

Ang bawat klase ay karaniwang may paglalarawan na nagsasabi kung para saan ito nilikha. Gayundin, karaniwang may paglalarawan ang bawat pampublikong pamamaraan na nagsasaad kung ano ang ginagawa nito at kung anong data ang kailangang ipasa dito.

Upang gumamit ng isang klase, kailangan mong magkaroon ng pangkalahatang ideya kung ano ang ginagawa nito. At kailangan mong malaman kung ano mismo ang ginagawa ng bawat pamamaraan. Ngunit hindi mo kailangang malaman kung paano ito ginagawa. Parang magic wand.

Tingnan natin ang code para sa pagkopya ng file:

Kinokopya ang c:\\data.txt file sa c:\\result.txt file
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();
   }
}

Kung babasahin mo ang code na ito sa bawat linya, maaari mong hulaan kung ano ang ginagawa nito sa mga pangkalahatang tuntunin. Bagama't nangangailangan iyon ng karanasan at pagsasanay. Pagkaraan ng ilang sandali, ang code na ito ay magiging pamilyar at naiintindihan mo.


2. Pagdidisenyo ng isang programa

Ang disenyo ng programa ay isang buong sining. Ito ay sabay-sabay na simple at mahirap. Simple, dahil walang mahigpit na batas: ang anumang hindi ipinagbabawal ay pinapayagan. Well, at iyon din ang nagpapahirap: maraming paraan para magawa ang isang bagay at hindi madaling mahanap ang pinakamahusay.

Ang pagdidisenyo ng isang programa ay parang pagsulat ng isang libro. Sa isang banda, sumusulat ka lang ng mga titik, salita, at pangungusap. Sa kabilang banda, mahalaga ang balangkas, mga tauhan, panloob na kontradiksyon, tunggalian, istilo ng pagkukuwento, intriga, atbp.

Ang pangunahing bagay ay upang maunawaan kung para kanino ka nagsusulat ng code. At sumulat ka ng code para sa iba pang mga programmer .

Ang pag-unlad ng produkto ay hindi maaaring hindi nangangahulugan ng paggawa ng mga pagbabago: may idinaragdag dito, may ibang inalis doon, may nababagong disenyo. Iyan ay kung gaano kalaki, napakalaking at naglalakihang mga proyekto ay ipinanganak mula sa maliliit na pag-ulit.

Ang pinakamahalaga para sa code ay dapat itong maunawaan ng ibang mga programmer. Maaaring itama ang maling code na naiintindihan. Ang tama ngunit hindi maintindihan na code ay hindi maaaring mapabuti.  Ang magagawa mo lang ay itapon ito.

Kaya paano ka magsulat ng mabuti, malinis na code?

Ang paggawa nito ay nangangailangan ng tatlong bagay:

  • Pagsusulat ng mabuti at nauunawaan na code sa loob ng mga pamamaraan — ito ang pinakamadaling kinakailangan
  • Pagpapasya kung aling mga entity ang dapat isama sa programa
  • Hatiin nang tama ang programa sa mga lohikal na bahagi

Ano ang nasa likod ng mga konseptong ito?

Pagsusulat ng magandang code sa loob ng mga pamamaraan

Kung mayroon kang mga pangunahing kasanayan sa Ingles, maaaring napansin mo kung gaano kadaling basahin ang code bilang mga pangungusap sa Ingles kung minsan:

  • class Cat extends Pet— Nangangahulugan ito na pinalawak ng klase ng Cat ang klase ng Alagang Hayop
  • while(stream.ready())— hangga't handa na ang batis...
  • if (a<b) return a; else return b— kung amas mababa sa b, pagkatapos ay bumalik a, kung hindi man ay bumalik b.

Ito ay sinadya. Ang Java ay isa sa ilang mga wika na nagpapadali sa pagsulat ng self-documenting code, ibig sabihin, ang code na naiintindihan nang walang mga komento. Sa magandang Java code, maraming paraan ang nagbabasa tulad ng mga pangungusap sa Ingles.

Kapag nagsusulat ng code, ang iyong gawain ay gawin itong simple at maigsi hangga't maaari. Isipin lamang kung ang iyong code ay madaling basahin at magsisimula kang lumipat sa tamang direksyon.

Sa Java, kaugalian na magsulat ng code na madaling basahin. Mas mabuti, ang lahat ng code para sa isang pamamaraan ay magkasya sa isang screen (ibig sabihin, 20-30 linya). Ito ang pamantayan para sa buong komunidad ng Java. Kung mapapabuti ang code, dapat itong pagbutihin.

Ang pinakamahusay na paraan upang matutunan kung paano magsulat ng magandang code ay sa pamamagitan ng pagsasanay. Sumulat ng maraming code, pag-aralan ang code ng iba, at hilingin sa mas maraming karanasang kasamahan na suriin ang iyong code.

At tandaan na sa sandaling sabihin mo sa iyong sarili na "mag-iwan ng sapat na mag-isa", huminto ang iyong paglaki.

Pagpapasya kung aling mga entity ang dapat isama sa programa

Kailangan mong magsulat ng code na mauunawaan ng ibang programmer. Kung 9 sa 10 programmer ang magsasama ng mga klase A, B at C sa disenyo ng isang programa, dapat ka ring gumawa ng mga klase A, B, at C sa iyong programa. Dapat kang magsulat ng code na mauunawaan ng iba.

Mahusay, gumagana, mabilis, ngunit hindi karaniwang code ay masamang code.

Kailangan mong pag-aralan ang mga proyekto ng ibang tao: ito ang pinakamahusay, pinakamabilis at pinakamadaling paraan upang matugunan ang lahat ng karunungan na naipon sa industriya ng IT sa loob ng mga dekada.

At siya nga pala, mayroon ka nang access sa isang mahusay, sikat, at mahusay na dokumentado na proyekto — ang Java SDK . Magsimula dito.

Suriin ang mga klase at kung paano sila nakaayos. Isipin kung bakit ang ilang mga pamamaraan ay static at ang iba ay hindi. Bakit ang mga pamamaraan ay may mga partikular na parameter na mayroon sila ngunit hindi sa iba. Bakit eksakto ang mga pamamaraang ito, at bakit pinangalanan ang mga klase kung ano ang pinangalanan sa kanila, at bakit nakapaloob ang mga ito sa kanilang mga partikular na pakete.

Kapag sinimulan mong maunawaan ang mga sagot sa lahat ng tanong na ito, makakasulat ka ng code na mauunawaan ng iba.

Iyon ay sinabi, gusto kong balaan ka laban sa pagsusuri ng code sa mga pamamaraan ng Java SDK. Marami sa mga pamamaraan ay muling isinulat upang i-maximize ang bilis, at ang kanilang pagiging madaling mabasa ay kaduda-dudang.

Hatiin nang tama ang programa sa mga lohikal na bahagi

Halos bawat programa ay nahahati sa mga bahagi o mga module. Ang bawat bahagi ay may pananagutan para sa sarili nitong aspeto ng programa.

Ang isang computer ay may motherboard, monitor, at keyboard — lahat ito ay magkahiwalay, maluwag na pinagsamang mga bahagi. Higit pa rito, nakikipag-ugnayan sila sa mga standardized na paraan: USB, HDMI, atbp. Kung magtapon ka ng kape sa iyong keyboard, maaari mo lang itong hugasan sa lababo, hayaang matuyo ito, at pagkatapos ay ipagpatuloy ang paggamit nito.

Ngunit ang isang laptop ay isang halimbawa ng isang monolitikong arkitektura: tila naiintindihan natin ang magkakahiwalay na mga lohikal na bahagi, ngunit mas pinagsama ang mga ito. Sa isang MacBookPro, kailangan mong i-disassemble ang kalahati ng laptop upang linisin ang keyboard. At ang pagtatapon ng iyong kape sa isang laptop ay isang dahilan para mag-order ng bagong laptop. Hindi bagong tasa ng kape.


3. Paglikha ng sarili mong mga klase

Ngunit dahil nag-aaral ka pa lang mag-program, dapat kang magsimula sa maliit sa pamamagitan ng pag-aaral na gumawa ng sarili mong mga klase.

Siyempre, nakagawa ka na ng mga klase, ngunit kailangan mong matutunang maunawaan kung anong mga klase ang dapat isama sa isang programa, kung paano dapat pangalanan ang mga ito, at kung anong mga pamamaraan ang dapat nilang taglayin. At kung paano sila dapat makipag-ugnayan sa isa't isa.

Listahan ng mga entity

Kung hindi mo alam kung saan magsisimula, magsimula sa simula.

Kapag nagsimula kang magdisenyo ng isang programa, maaari kang kumuha ng isang piraso ng papel at isulat ang isang listahan ng mga entity (mga bagay) na dapat nasa programa. At pagkatapos ay magsulat ng code ayon sa prinsipyo na ang bawat entity ay isang hiwalay na klase.

Halimbawa

Sabihin nating gusto mong magsulat ng larong chess. Kakailanganin mo ang mga sumusunod na entity: isang chessboard at 6 na uri ng mga piraso ng chess. Ang mga piraso ay gumagalaw sa iba't ibang paraan at may iba't ibang halaga. Makatuwiran na magkahiwalay sila ng mga klase. Sa katunayan, kapag nagsimula ka, mas maraming klase, mas mabuti.

Napakabihirang makatagpo ng isang baguhang programmer na nagsusulat ng sampung klase sa halip na dalawa. Sa halip na magsulat ng sampung klase, ang mga baguhan ay gustong magsulat ng dalawang klase o marahil isa lang. Kaya't mangyaring sumulat ng higit pang mga klase, aking mga kapwa programmer. At ang iyong code ay magiging mas malinaw sa lahat maliban marahil sa iyo 😛

Chess

Ipagpalagay na nagpasya kaming magsulat ng mga klase para sa chess: ano ang magiging hitsura ng mga klase na ito?

8 by 8 array lang ba ang chessboard? Mas mainam na lumikha ng isang hiwalay na klase na panloob na nag-iimbak ng isang reference sa isang array. Pagkatapos ay maaari kang magdagdag ng maraming kapaki-pakinabang na pamamaraan sa klase ng "chessboard", halimbawa, upang suriin kung ang isang partikular na cell ay walang laman o okupado.

Sa pangkalahatan, habang nagsisimula ka, laging gabayan ng prinsipyong ito: Ang isang programa ay may iba't ibang entity, at ang isang entity ay may isang uri. Ang ganitong uri ay ang klase.


4. Static na mga variable at pamamaraan

Huwag ding kalimutang gumamit ng mga static na variable at pamamaraan. Kung mayroon kang isang piraso ng chess na nakikipag-ugnayan sa isa pa sa chessboard, kung gayon ang iyong code ay nangangailangan ng isang paraan na kumukuha ng mga sanggunian sa una at pangalawang piraso pati na rin sa chessboard.

Ang mga static na variable, na maaaring ma-access mula sa kahit saan sa programa, ay karaniwang ginagamit upang maiwasan ang patuloy na pagpasa sa paligid ng mga sanggunian sa mga bagay na "palaging umiiral".

Halimbawa, tulad nito:

Code Tandaan
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);
      ...
   }
}


Isang sanggunian sa isang ChessBoardbagay.
Isang 8x8 two-dimensional array, hindi isang static na variable.








Idagdag ang mga piraso sa pisara.

O sa halip na isang static na variable, maaari kang lumikha ng isang paraan na nagbabalik ng singleton object. Halimbawa, tulad nito:

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);
      ...
   }
}