CodeGym /Java-blogg /Tilfeldig /Java-klasser: skrive dine egne klasser, konstruktører
John Squirrels
Nivå
San Francisco

Java-klasser: skrive dine egne klasser, konstruktører

Publisert i gruppen
Hei! I dag skal vi snakke om klasser i Java. Du kan si at klasser utgjør hjørnesteinen i Java-programmering. Når du blir programmerer, vil nesten hele jobben din være å skrive dine egne klasser som har ulike funksjoner. La oss se hva det betyr og hvordan det fungerer. :) Som du vet er Java et objektorientert programmeringsspråk. Alle programmer består av objekter som på en eller annen måte er relatert til hverandre. En klasse er i hovedsak en mal for et objekt. Det bestemmer hvordan objektet vil se ut og hvilke funksjoner det vil ha. Hvert objekt er et objekt av en eller annen klasse. Tenk på dette veldig enkle eksemplet:

public class Cat {

    String name;
    int age;

}
La oss si at vi skriver et program som involverer katter av en eller annen grunn (vi har for eksempel en veterinærklinikk som tilbyr tilgang til en nettkonto). Vi har laget en Cat- klasse, og erklært to variabler i den: String name og int age . Disse medlemsvariablene kalles felt. I hovedsak er dette en mal for alle kattene vi skal lage i fremtiden. Hvert Cat- objekt vil ha to variabler: et navn og en alder.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
    }

}
Slik fungerer det! Vi lager en katt, gir den et navn og alder, og viser alt på konsollen. Lett som bare det. :) Oftere enn ikke beskriver klasser ting og fenomener i den virkelige verden. En katt, et bord, en person, et lyn, en side i en bok, et hjul – du lager alle disse tingene i programmene dine ved å bruke individuelle klasser. For nå, la oss fokusere på variablene vi erklærte i Cat- klassen. De kalles felt, eller instansvariabler. Navnet deres sier egentlig alt. Hver forekomst (eller objekt) av Cat -klassen vil ha disse variablene. Hver katt vi lager vil ha sin egen navnevariabel og sin egen aldervariabel. Dette er fornuftig - det er i grunnen slik det er med ekte katter. :) I tillegg til instansvariabler finnes det også klassevariabler (statiske variabler). La oss avslutte vårt eksempel:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        Cat fluffy = new Cat();
        fluffy.age = 5;
        fluffy.name = "Fluffy";
        count++;

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
        System.out.println("We created a cat named " + fluffy.name + ". His age is " + fluffy.age);

        System.out.println("Total number of cats = " + count);
    }
}
Konsollutgang: Vi laget en katt som heter Smudge. Hans alder er 3. Vi skapte en katt som heter Fluffy. Hans alder er 5 Totalt antall katter = 2 Nå har klassen vår en ny variabel kalt count. Den er ansvarlig for å telle de opprettede kattene. Hver gang vi skaper en katt i hovedsakmetoden øker vi denne variabelen med 1. Denne variabelen er deklarert ved å bruke nøkkelordet static. Det betyr at den tilhører klassen, ikke til et spesifikt objekt i klassen. Noe som selvfølgelig gir mening: hver katts navn tilhører den spesifikke katten, men vi trenger én katteteller som gjelder for dem alle. Dette er nøyaktig hva nøkkelordet static oppnår: det gjør tellevariabelen til en enkelt variabel for alle kattene. Merk: når vi viser variabelen, bruker vi ikke smudge.count eller fluffy.count. Den tilhører verken Smudge eller Fluffy; den tilhører hele Cat- klassen. Det er derfor det bare teller. Du kan også skrive Cat.count. Det vil også være riktig. Når vi viser navnevariabelen, ville vi ikke gjøre følgende:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        System.out.println("We created a cat named " + name + ". His age is " + smudge.age);

        System.out.println("Total number of cats = " + count);
    }
}
Dette er en feil! Hver katt har sitt eget navn. Kompilatoren blir forvirret her. "Skriv ut et navn til konsollen? Hvems navn?" :/"

Metoder

I tillegg til variabler har hver klasse metoder. Vi vil snakke om dem mer detaljert i en egen leksjon, men de generelle prinsippene er ganske enkle. Metoder definerer klassens funksjonalitet, dvs. hva objekter i klassen din kan gjøre. Du er allerede kjent med en av disse metodene: main() -metoden. Men, som du kanskje husker, er hovedmetoden statisk, noe som betyr at den tilhører hele klassen (logikken er den samme som med variabler). Standard, ikke-statiske metoder kan imidlertid bare kalles på spesifikke objekter vi har laget. Hvis vi for eksempel vil skrive en katteklasse, må vi vite hvilke funksjoner en katt i programmet vårt skal ha. På den forutsetningen, la oss skrive et par metoder for katten vår:

public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Pounce!");
    }

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        smudge.sayMeow();
        smudge.jump();

    }
}
Sjekk det ut! Nå er klassen vår mye nærmere å ligne en katt! Nå har vi ikke bare en katt med et navn ("Smudge") og en alder (3). Han kan også si mjau og hoppe! Hva slags katt ville det vært uten den "funksjonaliteten"? :) Vi tar et spesifikt objekt (smudge) og kaller dets sayMeow() og jump()- metoder. La oss se på konsollen: Mjau! Slå til! En ekte katt! :)

Lage dine egne klasser. Abstraksjon

I fremtiden må du skrive dine egne klasser. Hva må du passe på når du skriver dem? Hvis vi snakker om variabler, må du bruke noe som kalles abstraksjon. Abstraksjon er ett av de fire grunnleggende prinsippene for objektorientert programmering. Det betyr å trekke ut de viktigste og mest betydningsfulle egenskapene til en gjenstand, og omvendt å kaste bort de som er mindre eller ubetydelige. La oss for eksempel lage et arkivskap for ansatte i selskapet. For å lage medarbeiderobjekter har vi skrevet en medarbeiderklasse. Hvilke egenskaper er viktige beskrivelser av en ansatt for vårt firmas arkivskap? Navn, fødselsdato, SSN og ansatt-ID. Men det er usannsynlig at vi trenger den ansattes høyde, øyenfarge eller hårfarge for selskapets ansattes rekord. Bedrifter trenger ikke denne informasjonen. Så, i Employee- klassen erklærer vi følgende variabler: String name , int age , int socialSecurityNumber og int employeeId. Og vi utelater unødvendig informasjon (som øyenfarge). Med andre ord, vi skaper en abstraksjon. Men hvis vi lager et arkivskap for modellbyråer, endrer situasjonen seg dramatisk. En modells høyde, øyenfarge og hårfarge er viktige egenskaper, men hennes SSN er absolutt irrelevant for oss. Så i Model- klassen må vi lage følgende variabler: String height , String hair , String eyes . Det er slik abstraksjon fungerer – det er enkelt! :)

Konstruktører

La oss gå tilbake til katteksemplet vårt.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();

        System.out.println("Here the program does something for 2 hours...");

        smudge.age = 3;
        smudge.name = "Smudge";

    }
}
Se over denne koden og prøv å finne ut hva som er galt med programmet vårt. Programmet vårt hadde en katt uten navn eller alder i 2 timer! Selvfølgelig er dette iboende feil. Veterinærklinikkens database bør ikke inneholde katter uten informasjon. For øyeblikket er katten vår prisgitt programmereren. Vi stoler på at han ikke glemmer å spesifisere navn og alder, og at alt ordner seg. Hvis han glemmer, vil databasen ha et problem: ikke navngitte katter. Hvordan kan vi løse dette problemet? Vi må på en eller annen måte hindre at katter blir skapt uten navn og alder. Det er her konstruktører kommer til unnsetning. La oss gi et eksempel:

public class Cat {

    String name;
    int age;

    // Constructor for the Cat class
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
    }
}
I hovedsak er en konstruktør en mal for objekter i en klasse. I dette tilfellet indikerer vi at to argumenter, en String og en int , må spesifiseres for hvert katteobjekt . Hvis vi prøver å lage en navnløs katt nå, vil det ikke fungere.

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Nå som klassen har en konstruktør, vet Java-kompilatoren hvordan objektene skal se ut, og tillater ikke at objekter opprettes uten å spesifisere argumentene. La oss nå undersøke nøkkelordet dette, som du ser inne i konstruktøren. Det er enkelt også. Nøkkelordet dette er for å indikere et bestemt objekt. Koden i konstruktøren

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
kan tolkes nesten ordrett: "Navnet på denne katten (den vi lager) = argumentet som sendes inn for konstruktørens navneparameter. Alderen til denne katten (den vi lager) = argumentet sendt inn for konstruktørens aldersparameter." Etter at konstruktøren har kjørt, kan du bekrefte at alle nødvendige verdier er tilordnet katten vår:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
        System.out.println(smudge.name);
        System.out.println(smudge.age);
    }
}
Konsollutgang: Smudge 5 Når konstruktøren ble kalt:

Cat smudge = new Cat("Smudge", 5);
Dette er hva som faktisk skjedde internt:

this.name = "Smudge";
this.age = 5;
Og verdiene til argumentene som ble sendt til konstruktøren ble tilordnet flekkerobjektet ( det er det dette refererer til i dette tilfellet). Faktisk, selv om du ikke erklærer noen konstruktører i en klasse, vil den fortsatt kalle en konstruktør! Men hvordan er det mulig? О_О Fordi alle Java-klasser har en såkalt standardkonstruktør. Det krever ingen argumenter, men det påkalles hver gang du oppretter et objekt av en klasse.

public class Cat {

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Ved første øyekast er dette kanskje ikke åpenbart. Vi laget et objekt, så hva? Hvor gjør konstruktøren noe her? For å se det, la oss eksplisitt skrive en tom konstruktør for Cat- klassen. På innsiden vil vi sende ut en setning til konsollen. Hvis setningen vises, ble konstruktøren påkalt.

public class Cat {

    public Cat() {
        System.out.println("A cat has been created!");
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Konsollutgang: En katt er opprettet! Der er bekreftelsen. Standardkonstruktøren er alltid usynlig til stede i klassene dine. Men du må vite en ting til om det. Standardkonstruktøren blir eliminert fra en klasse når du oppretter en konstruktør med argumenter. Faktisk har vi allerede sett bevis på dette ovenfor. Det sto i denne koden:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Vi kunne ikke lage en Cat uten navn og alder, fordi vi erklærte en Cat- konstruktør med streng- og int-parametere. Dette førte til at standardkonstruktøren umiddelbart forsvant fra klassen. Så husk at hvis du trenger flere konstruktører i klassen din, inkludert en konstruktør uten argumenter, må du deklarere det separat. Klinikken vår ønsker å gjøre gode gjerninger og hjelpe hjemløse kattunger hvis navn og alder er ukjent. Da skal koden vår se slik ut:

public class Cat {

    String name;
    int age;

    // For cats with owners
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // For street cats
    public Cat() {
    }

    public static void main(String[] args) {
        
        Cat smudge = new Cat("Smudge", 5);
        Cat streetCat = new Cat();
    }
}
Nå som vi har spesifisert en eksplisitt standardkonstruktør, kan vi lage begge typer katter. I konstruktøren kan du tilordne verdier direkte. Du trenger ikke alltid ta dem fra argumenter. For eksempel kan vi merke alle gatekatter i databasen ved å bruke "Gatekatt nr. <antall>" som mal. :

public class Cat {

    String name;
    int age;

    static int count = 0;

    public Cat() {
        count++;
        this.name = "Street cat No. " + count;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat streetCat1 = new Cat();
        Cat streetCat2 = new Cat();
        System.out.println(streetCat1.name);
        System.out.println(streetCat2.name);
    }
}
Vi har en tellevariabel , som teller gatekattene våre. Hver gang standardkonstruktøren kjøres, øker vi antallet med 1 og knytter dette tallet til kattens navn. Rekkefølgen av argumenter er veldig viktig for konstruktører. La oss bytte navn og aldersargumenter som er sendt til konstruktøren vår.

public class Cat {

    String name;
    int age;

    public Cat(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 10); // Error!
    }
}
Vi fikk en feil! Konstruktøren fastsetter tydelig at når et Cat- objekt opprettes, må det sendes et tall og en streng, i denne rekkefølgen. Så koden vår fungerer ikke. Husk og respekter denne regelen når du erklærer dine egne klasser:

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}

public Cat(int age, String name) {
    this.age = age;
    this.name = name;
}
Dette er to helt forskjellige konstruktører! Fullfør nå et par oppgaver for å styrke forståelsen av materialet. :)
  1. Antikvitetsmuseet.

    Din oppgave er å designe en Artifact- klasse.
    Det finnes tre typer gjenstander på museet.
    Vi vet ingenting om den første typen bortsett fra serienummeret tildelt av museet (for eksempel: 212121).
    For den andre typen kjenner vi serienummeret og kulturen som skapte det (for eksempel: 212121, "aztekerne").
    For den tredje typen kjenner vi serienummeret, kulturen som skapte det, og århundret det ble opprettet i (for eksempel: 212121, "Aztecs", 12).

    Lag en artefaktklasse som beskriver antikvitetene som er oppbevart på museet, og skriv det nødvendige settet med konstruktører for klassen. Deretter, i main()- metoden, lag en artefakt av hver type.

    
    public class Artifact {
        
        // Write your code here
    
        public static void main(String[] args) {
            // Write your code here
        }
    }
    
  2. Dating nettsted

    La oss lage en brukerdatabase for et datingnettsted.
    Men her er problemet: du glemte den nødvendige rekkefølgen på argumentene, og det er ingen teknisk dokumentasjon tilgjengelig.
    Design en brukerklasse , som vil ha følgende felt: navn ( streng ), alder ( kort ) og høyde ( int ).
    Opprett passende antall konstruktører, slik at navn, alder og høyde kan spesifiseres i hvilken som helst rekkefølge.

    
    public class User {
    
        String name;
        short age;
        int height;
    
        // Write your code here
    
        public static void main(String[] args) {
            
        }
    }
    
For å forsterke det du lærte, foreslår vi at du ser en videoleksjon fra vårt Java-kurs
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION