1. Objekter og klasser

I dag vil du lære litt om hvordan et typisk Java-program fungerer. Her er de store nyhetene: hvert Java-program består av klasser og objekter.

Du vet allerede hva klasser er, men hva er objekter?

Jeg starter med en analogi. Tenk deg at du vil lage et lite skip. Først må du lage en blåkopi og deretter gi den til fabrikken, hvor et skip skal bygges i henhold til tegningen. Eller kanskje dusin. Eller så mange skip du vil. Dusinvis av identiske skip er bygget i henhold til en enkelt plan. Det er det viktige her.

Det er det samme i Java-programmering.

Tegninger

En programmerer er som en designer. En designer lager tegninger, og en Java-programmerer skriver klasser. Deler lages basert på tegningene, og objekter lages basert på klasser.

Først skriver vi klasser (lager tegninger), og deretter, mens programmet kjører, lager Java-maskinen objekter basert på disse klassene. På samme måte som skip er laget av tegninger.

Det er bare én blåkopi, men det kan være mange skip. Skipene er forskjellige - de har forskjellige navn og frakter forskjellige laster. Men de er veldig like: de deler alle samme design og kan utføre lignende oppgaver.

Eller her er en annen analogi...

Myrtue

En maurtue er et godt eksempel på hvordan gjenstander samhandler. Det er tre klasser av maur i en enkel maurtue: dronningen, soldater og arbeidere.

Antall maur i hver klasse er forskjellig. Det er en enkelt dronning for hele maurtuen, men det er dusinvis av soldater og hundrevis av arbeidermaur. Tre klasser og hundrevis av gjenstander. Maur samhandler med hverandre - med maur i samme klasse og med maur fra andre klasser - i henhold til strenge regler.

Dette er det perfekte eksempelet. Alt er akkurat slik i et typisk program. Det er et primærobjekt som lager objekter av alle de andre klassene. Objektene begynner å samhandle med hverandre og med programmets «verden utenfor». Objektenes oppførsel er internt hardkodet.

Disse to analogiene er to sider av samme sak. Sannheten er i midten. Det første eksemplet (om en blåkopi og skip) viser forholdet mellom en klasse og objekter i den klassen. Dette er en sterk analogi. Det andre eksemplet (om en maurtue) viser forholdet mellom de skrevne klassene og objektene som eksisterer mens programmet kjører.

Du må først skrive klasser for hvert objekt som vil eksistere i programmet, og deretter også beskrive hvordan de samhandler. Ja, det stemmer, men det er enklere enn det høres ut.

I Java er alle entiteter objekter under kjøring, og å skrive et program handler om å beskrive de forskjellige måtene objekter samhandler på. Objekter kaller ganske enkelt hverandres metoder og sender de nødvendige dataene til dem.

Dokumentasjon

Og hvordan vet du hvilke data du skal sende til metoder? Menneskene som kom før deg tenkte på alt.

Hver klasse har vanligvis en beskrivelse som sier hva den ble laget for. Dessuten har hver offentlig metode vanligvis en beskrivelse som indikerer hva den gjør og hvilke data som må sendes til den.

For å bruke en klasse, må du ha en generell ide om hva den gjør. Og du må vite nøyaktig hva hver metode gjør. Men du trenger ikke i det hele tatt vite hvordan den gjør det. Det er som en tryllestav.

La oss ta en titt på koden for å kopiere en fil:

Kopierer 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 leser denne koden linje for linje, kan du gjette hva den gjør i generelle termer. Selv om det krever erfaring og øvelse. Etter en stund vil denne koden virke kjent og forståelig for deg.


2. Designe et program

Programdesign er en hel kunst. Det er enkelt og vanskelig på en gang. Enkelt, for det er ingen strenge lover: alt som ikke er forbudt er tillatt. Vel, og det er også det som gjør det vanskelig: det er mange måter å gjøre noe på, og det er ikke lett å finne den beste.

Å designe et program er som å skrive en bok. På den ene siden skriver du bare bokstaver, ord og setninger. På den annen side er handlingen, karakterene, interne motsetninger, konflikter, fortellerstil, intriger osv. viktig.

Det viktigste er å forstå hvem du skriver koden til. Og du skriver kode for andre programmerere .

Produktutvikling betyr uunngåelig å gjøre endringer: noe blir lagt til her, noe annet fjernet der, noe blir redesignet. Slik fødes store, enorme og gigantiske prosjekter fra små iterasjoner.

Det som betyr mest for koden er at den må være forståelig for andre programmerere. Feil kode som er forståelig kan rettes. Riktig, men uforståelig kode kan ikke forbedres.  Alt du kan gjøre er å forkaste den.

Så hvordan skriver du god, ren kode?

Å gjøre dette krever tre ting:

  • Å skrive god og forståelig kode i metoder - dette er det enkleste kravet
  • Bestemme hvilke enheter som skal inkluderes i programmet
  • Å dele opp programmet i logiske deler på riktig måte

Hva ligger bak disse konseptene?

Skrive god kode i metoder

Hvis du til og med har grunnleggende engelskkunnskaper, har du kanskje lagt merke til hvor enkelt det kan være å lese kode som engelske setninger noen ganger:

  • class Cat extends Pet— Dette betyr at Cat-klassen utvider Pet-klassen
  • while(stream.ready())- så lenge strømmen er klar...
  • if (a<b) return a; else return b— hvis aer mindre enn b, så returner a, ellers return b.

Dette er bevisst. Java er ett av flere språk som gjør det enkelt å skrive selvdokumenterende kode, altså kode som er forståelig uten kommentarer. I god Java-kode leses mange metoder akkurat som engelske setninger.

Når du skriver kode, er oppgaven din å gjøre det så enkelt og konsist som mulig. Bare tenk på om koden din er lett å lese, så begynner du å bevege deg i riktig retning.

I Java er det vanlig å skrive kode som er lett å lese. Helst vil all koden for en metode passe på en enkelt skjerm (dvs. 20-30 linjer). Dette er normen for hele Java-fellesskapet. Hvis koden kan forbedres, bør den forbedres.

Den beste måten å lære å skrive god kode på er gjennom praksis. Skriv mye kode, studer andres kode, og be mer erfarne kolleger om å gjennomgå koden din.

Og husk at i det øyeblikket du sier til deg selv "la godt nok i fred", stopper veksten din.

Bestemme hvilke enheter som skal inkluderes i programmet

Du må skrive kode som andre programmerere kan forstå. Hvis 9 av 10 programmerere vil inkludere klasse A, B og C i et programs design, bør du også lage klasse A, B og C i programmet ditt. Du må skrive kode som andre kan forstå.

Flott, fungerende, rask, men ikke-standard kode er dårlig kode.

Du må studere andres prosjekter: dette er den beste, raskeste og enkleste måten å suge til seg all visdommen som har samlet seg i IT-bransjen i flere tiår.

Og forresten, du har allerede tilgang til et utmerket, populært og godt dokumentert prosjekt – Java SDK . Start med det.

Analyser klassene og hvordan de er organisert. Tenk på hvorfor noen metoder er statiske og andre ikke. Hvorfor har metodene de spesifikke parameterne de har, men ikke andre. Hvorfor akkurat disse metodene, og hvorfor heter klassene det de heter, og hvorfor er de inneholdt i deres spesifikke pakker.

Når du begynner å forstå svarene på alle disse spørsmålene, vil du kunne skrive kode som andre kan forstå.

Når det er sagt, vil jeg advare deg mot å analysere koden i metodene til Java SDK. Mange av metodene ble skrevet om for å maksimere hastigheten, og deres lesbarhet er tvilsom.

Å dele opp programmet i logiske deler på riktig måte

Nesten hvert program er delt inn i deler eller moduler. Hver del er ansvarlig for sitt eget aspekt av programmet.

En datamaskin har et hovedkort, en skjerm og tastatur - disse er alle separate, løst sammenkoblede deler. Dessuten samhandler de på standardiserte måter: USB, HDMI osv. Hvis du søler kaffe på tastaturet, kan du ganske enkelt vaske den av i vasken, la den tørke og deretter fortsette å bruke den.

Men en bærbar datamaskin er et eksempel på en monolitisk arkitektur: det ser ut til at vi kan skjelne separate logiske deler, men de er mye mer integrert. På en MacBookPro må du demontere halvparten av den bærbare datamaskinen for å rengjøre tastaturet. Og å søle kaffen på en bærbar datamaskin er en grunn til å bestille en ny bærbar. Ikke en ny kopp kaffe.


3. Opprette dine egne klasser

Men siden du bare lærer å programmere, bør du begynne i det små ved å lære å lage dine egne klasser.

Selvfølgelig har du allerede opprettet klasser, men du må lære å forstå hvilke klasser som skal inkluderes i et program, hvordan de skal navngis og hvilke metoder de skal ha. Og hvordan de skal samhandle med hverandre.

Liste over enheter

Hvis du ikke vet hvor du skal begynne, start fra begynnelsen.

Når du først begynner å designe et program, kan du ganske enkelt ta et stykke papir og skrive ned en liste over enhetene (objektene) som skal være i programmet. Og skriv deretter kode i henhold til prinsippet om at hver enhet er en egen klasse.

Eksempel

La oss si at du vil skrive et sjakkspill. Du trenger følgende enheter: et sjakkbrett og 6 typer sjakkbrikker. Brikkene beveger seg på forskjellige måter og har forskjellige verdier. Det er fornuftig at de er separate klasser. Faktisk, når du først kommer i gang, jo flere klasser, jo bedre.

Det er svært sjelden å møte en nybegynner programmerer som skriver ti klasser i stedet for to. I stedet for å skrive ti klasser, elsker nybegynnere å skrive to klasser eller kanskje bare én. Så vær så snill å skrive flere klasser, mine andre programmerere. Og koden din vil bli tydeligere for alle bortsett fra kanskje deg 😛

Sjakk

Anta at vi bestemmer oss for å skrive klasser for sjakk: hvordan ville disse klassene se ut?

Er sjakkbrettet bare en 8 x 8-matrise? Det er bedre å lage en egen klasse som internt lagrer en referanse til en matrise. Deretter kan du legge til mange nyttige metoder til klassen "sjakkbrett", for eksempel for å sjekke om en bestemt celle er tom eller opptatt

Generelt, når du kommer i gang, må du alltid ledes av dette prinsippet: Et program har forskjellige enheter, og en enhet har en type. Denne typen er klassen.


4. Statiske variabler og metoder

Ikke glem å bruke statiske variabler og metoder. Hvis du har en sjakkbrikke som samhandler med en annen på sjakkbrettet, trenger koden din en metode som tar referanser til den første og andre brikken samt sjakkbrettet.

Statiske variabler, som kan nås fra hvor som helst i programmet, brukes vanligvis for å unngå konstant å sende rundt referanser til objekter som "alltid eksisterer".

For eksempel slik:

Kode Merk
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 referanse til et enkelt ChessBoardobjekt.
En 8x8 todimensjonal matrise, ikke en statisk variabel.








Legg bitene til brettet.

Eller i stedet for en statisk variabel, kan du lage en metode som returnerer et enkelttonobjekt. For eksempel slik:

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