1. Objekter og klasser

I dag lærer du lidt om, hvordan et typisk Java-program fungerer. Her er den store nyhed: hvert Java-program består af klasser og objekter.

Du ved allerede, hvad klasser er, men hvad er objekter?

Jeg starter med en analogi. Forestil dig, at du vil lave et lille skib. Først skal du lave en plan og derefter give den til fabrikken, hvor et skib bliver bygget i henhold til tegningen. Eller måske dusin. Eller så mange skibe, du vil. Dusinvis af identiske skibe er bygget i henhold til en enkelt plan. Det er det vigtige her.

Det er det samme i Java-programmering.

Tegninger

En programmør er som en designer. En designer laver tegninger, og en Java-programmør skriver klasser. Dele oprettes ud fra tegningerne, og objekter oprettes ud fra klasser.

Først skriver vi klasser (laver tegninger), og derefter, mens programmet kører, opretter Java-maskinen objekter baseret på disse klasser. På samme måde som skibe er skabt ud fra tegninger.

Der er kun én plan, men der kan være mange skibe. Skibene er forskellige - de har forskellige navne og transporterer forskellige laster. Men de er meget ens: De deler alle det samme design og kan udføre lignende opgaver.

Eller her er en anden analogi...

Myretue

En myretue er et godt eksempel på, hvordan objekter interagerer. Der er tre klasser af myrer i en simpel myretue: dronningen, soldater og arbejdere.

Antallet af myrer i hver klasse er forskelligt. Der er en enkelt dronning for hele myretuen, men der er snesevis af soldater og hundredvis af arbejdsmyrer. Tre klasser og hundredvis af genstande. Myrer interagerer med hinanden - med myrer af deres samme klasse og med myrer af andre klasser - i henhold til stive regler.

Dette er det perfekte eksempel. Alt er præcis sådan i et typisk program. Der er et primært objekt, der skaber objekter af alle de andre klasser. Objekterne begynder at interagere med hinanden og med programmets "omverden". Objekternes adfærd er internt hardkodet.

Disse to analogier er to sider af samme sag. Sandheden er i midten. Det første eksempel (om en blueprint og skibe) viser forholdet mellem en klasse og objekter i denne klasse. Dette er en stærk analogi. Det andet eksempel (om en myretue) viser forholdet mellem de skrevne klasser og de objekter, der eksisterer, mens programmet kører.

Du skal først skrive klasser for hvert objekt, der vil eksistere i programmet, og derefter også beskrive, hvordan de interagerer. Ja, det er rigtigt, men det er nemmere end det lyder.

I Java er alle entiteter objekter under kørsel, og at skrive et program handler om at beskrive de forskellige måder, objekter interagerer på. Objekter kalder simpelthen hinandens metoder og sender de nødvendige data til dem.

Dokumentation

Og hvordan ved du, hvilke data der skal videregives til metoder? De mennesker, der kom før dig, tænkte på alt.

Hver klasse har typisk en beskrivelse, der siger, hvad den er lavet til. Desuden har hver offentlig metode normalt en beskrivelse, der angiver, hvad den gør, og hvilke data der skal videregives til den.

For at bruge en klasse skal du have en generel idé om, hvad den gør. Og du skal vide præcis, hvad hver metode gør. Men du behøver slet ikke at vide, hvordan den gør det. Det er som en tryllestav.

Lad os tage et kig på koden til kopiering af en fil:

Kopiering af filen c:\\data.txt til filen 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();
   }
}

Hvis du læser denne kode linje for linje, kan du gætte, hvad den generelt gør. Selvom det kræver erfaring og øvelse. Efter et stykke tid vil denne kode virke bekendt og forståelig for dig.


2. Design af et program

Programdesign er en hel kunst. Det er både enkelt og svært på én gang. Simpelt, fordi der ikke er nogen strenge love: Alt, der ikke er forbudt, er tilladt. Nå, og det er også det, der gør det svært: Der er mange måder at gøre noget på, og det er ikke nemt at finde den bedste.

At designe et program er som at skrive en bog. På den ene side skriver du bare bogstaver, ord og sætninger. På den anden side er plot, karakterer, interne modsætninger, konflikter, fortællestil, intriger osv. vigtige.

Det vigtigste er at forstå, hvem du skriver koden til. Og du skriver kode til andre programmører .

Produktudvikling betyder uundgåeligt at foretage ændringer: noget bliver tilføjet her, noget andet fjernet der, noget bliver redesignet. Sådan fødes store, enorme og gigantiske projekter fra små iterationer.

Det, der betyder mest for kode, er, at det skal være forståeligt for andre programmører. Forkert kode, der er forståelig, kan rettes. Korrekt, men uforståelig kode kan ikke forbedres.  Alt du kan gøre er at kassere det.

Så hvordan skriver man god, ren kode?

At gøre dette kræver tre ting:

  • At skrive god og forståelig kode inde i metoder - dette er det nemmeste krav
  • Beslutning om, hvilke enheder der skal inkluderes i programmet
  • Opdeling af programmet i logiske dele korrekt

Hvad ligger bag disse begreber?

At skrive god kode inde i metoder

Hvis du selv har grundlæggende engelskkundskaber, har du måske bemærket, hvor nemt det kan være at læse kode som engelske sætninger nogle gange:

  • class Cat extends Pet— Det betyder, at Cat-klassen udvider Pet-klassen
  • while(stream.ready())- så længe streamen er klar...
  • if (a<b) return a; else return b— hvis aer mindre end b, så returner a, ellers return b.

Dette er bevidst. Java er et af flere sprog, der gør det nemt at skrive selvdokumenterende kode, altså kode, der er forståelig uden kommentarer. I god Java-kode læses mange metoder ligesom engelske sætninger.

Når du skriver kode, er din opgave at gøre det så enkelt og kortfattet som muligt. Tænk bare over, om din kode er nem at læse, og du vil begynde at bevæge dig i den rigtige retning.

I Java er det kutyme at skrive kode, der er let at læse. Helst vil al koden til en metode passe på en enkelt skærm (dvs. 20-30 linjer). Dette er normen for hele Java-fællesskabet. Hvis koden kan forbedres, bør den forbedres.

Den bedste måde at lære at skrive god kode på er gennem øvelse. Skriv en masse kode, studer andres kode, og bed mere erfarne kolleger om at gennemgå din kode.

Og husk, at i det øjeblik du siger til dig selv "lad godt nok i fred", stopper din vækst.

Beslutning om, hvilke enheder der skal inkluderes i programmet

Du skal skrive kode, som andre programmører kan forstå. Hvis 9 ud af 10 programmører ville inkludere klasserne A, B og C i et programs design, så bør du også lave klasserne A, B og C i dit program. Du skal skrive kode, som andre kan forstå.

Fantastisk, fungerende, hurtig, men ikke-standard kode er dårlig kode.

Du er nødt til at studere andres projekter: dette er den bedste, hurtigste og nemmeste måde at opsuge al den visdom, der har akkumuleret i it-branchen i årtier.

Og i øvrigt har du allerede adgang til et fremragende, populært og veldokumenteret projekt - Java SDK . Start med det.

Analyser klasserne og hvordan de er organiseret. Tænk over, hvorfor nogle metoder er statiske, og andre ikke er. Hvorfor har metoderne de specifikke parametre, de har, men ikke andre. Hvorfor er disse metoder præcist, og hvorfor hedder klasserne det, de hedder, og hvorfor er de indeholdt i deres specifikke pakker.

Når du begynder at forstå svarene på alle disse spørgsmål, vil du være i stand til at skrive kode, som andre kan forstå.

Når det er sagt, vil jeg advare dig mod at analysere koden i metoderne i Java SDK. Mange af metoderne blev omskrevet for at maksimere hastigheden, og deres læsbarhed er tvivlsom.

Opdeling af programmet i logiske dele korrekt

Næsten hvert program er opdelt i dele eller moduler. Hver del er ansvarlig for sit eget aspekt af programmet.

En computer har et bundkort, en skærm og et tastatur - disse er alle separate, løst koblede dele. Desuden interagerer de på standardiserede måder: USB, HDMI osv. Hvis du spilder kaffe på dit tastatur, kan du blot vaske det af i vasken, lade det tørre og derefter fortsætte med at bruge det.

Men en bærbar computer er et eksempel på en monolitisk arkitektur: det ser ud til, at vi kan skelne separate logiske dele, men de er meget mere integrerede. På en MacBookPro skal du skille halvdelen af ​​den bærbare computer ad for at rense tastaturet. Og at spilde din kaffe på en bærbar computer er en grund til at bestille en ny bærbar. Ikke en ny kop kaffe.


3. Oprettelse af dine egne klasser

Men da du lige skal lære at programmere, bør du starte i det små ved at lære at lave dine egne klasser.

Du har selvfølgelig allerede oprettet klasser, men du skal lære at forstå, hvilke klasser der skal inkluderes i et program, hvordan de skal navngives, og hvilke metoder de skal have. Og hvordan de skal interagere med hinanden.

Liste over enheder

Hvis du ikke ved, hvor du skal starte, så start fra begyndelsen.

Når du først begynder at designe et program, kan du blot tage et stykke papir og skrive en liste ned over de enheder (objekter), der skal være i programmet. Og så skriv kode efter princippet om, at hver enhed er en separat klasse.

Eksempel

Lad os sige, at du vil skrive et skakspil. Du skal bruge følgende enheder: et skakbræt og 6 typer skakbrikker. Brikkerne bevæger sig på forskellige måder og har forskellige værdier. Det giver mening, at de er separate klasser. Faktisk, når du først kommer i gang, jo flere klasser, jo bedre.

Det er meget sjældent at møde en ny programmør, der skriver ti klasser i stedet for to. I stedet for at skrive ti klasser, elsker begyndere at skrive to klasser eller måske bare én. Så skriv venligst flere klasser, mine medprogrammører. Og din kode bliver tydeligere for alle undtagen måske dig 😛

Skak

Lad os sige, at vi beslutter os for at skrive klasser til skak: hvordan ville disse klasser se ud?

Er skakbrættet kun et 8 gange 8-array? Det er bedre at oprette en separat klasse, der internt gemmer en reference til et array. Så kan du tilføje en masse nyttige metoder til klassen "skakbræt", for eksempel for at kontrollere, om en bestemt celle er tom eller optaget

Generelt, når du kommer i gang, skal du altid være styret af dette princip: Et program har forskellige entiteter, og en enhed har en type. Denne type er klassen.


4. Statiske variable og metoder

Glem heller ikke at bruge statiske variabler og metoder. Hvis du har en skakbrik, der interagerer med en anden på skakbrættet, så har din kode brug for en metode, der tager referencer til den første og anden brik samt skakbrættet.

Statiske variabler, som kan tilgås fra hvor som helst i programmet, bruges typisk for at undgå konstant at gå rundt med referencer til objekter, der "altid eksisterer".

For eksempel sådan her:

Kode Bemærk
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);
      ...
   }
}


En reference til et enkelt ChessBoardobjekt.
Et 8x8 todimensionalt array, ikke en statisk variabel.








Tilføj stykkerne til brættet.

Eller i stedet for en statisk variabel kan du oprette en metode, der returnerer et singleton-objekt. For eksempel sådan her:

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