CodeGym /Java Blog /Willekeurig /Java Classes: je eigen klassen schrijven, constructors
John Squirrels
Niveau 41
San Francisco

Java Classes: je eigen klassen schrijven, constructors

Gepubliceerd in de groep Willekeurig
Hoi! Vandaag zullen we het hebben over lessen in Java. Je zou kunnen zeggen dat klassen de hoeksteen vormen van Java-programmering. Als je programmeur wordt, bestaat bijna je hele baan uit het schrijven van je eigen klassen met verschillende functies. Laten we eens kijken wat dat betekent en hoe het werkt. :) Zoals u weet, is Java een objectgeoriënteerde programmeertaal. Alle programma's bestaan ​​uit objecten die op de een of andere manier met elkaar in verband staan. Een klasse is in wezen een sjabloon voor een object. Het bepaalt hoe het object eruit komt te zien en welke functies het zal hebben. Elk object is een object van een bepaalde klasse. Beschouw dit zeer eenvoudige voorbeeld:

public class Cat {

    String name;
    int age;

}
Laten we zeggen dat we om de een of andere reden een programma schrijven waarbij katten betrokken zijn (we hebben bijvoorbeeld een dierenkliniek die toegang biedt tot een online account). We hebben een Cat- klasse gemaakt en daarin twee variabelen gedeclareerd: String name en int age . Deze lidvariabelen worden velden genoemd. In wezen is dit een sjabloon voor alle katten die we in de toekomst zullen maken. Elk Cat- object heeft twee variabelen: een naam en een leeftijd.

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

}
Dit is hoe het werkt! We maken een kat, geven hem een ​​naam en leeftijd en laten alles zien op de console. Fluitje van een cent. :) Vaker wel dan niet beschrijven lessen dingen en fenomenen in de echte wereld. Een kat, een tafel, een persoon, een bliksemschicht, een pagina van een boek, een wiel - je maakt al deze dingen in je programma's met behulp van individuele klassen. Laten we ons nu concentreren op de variabelen die we in de klasse Cat hebben gedeclareerd . Ze worden velden of instantievariabelen genoemd. Hun naam zegt eigenlijk alles. Elke instantie (of elk object) van de klasse Cat heeft deze variabelen. Elke kat die we maken, heeft zijn eigen naamvariabele en zijn eigen leeftijdvariabel. Dit is logisch - het is eigenlijk hoe het is met echte katten. :) Naast instantievariabelen zijn er ook klassevariabelen (statische variabelen). Laten we ons voorbeeld afmaken:

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);
    }
}
Console-uitvoer: we hebben een kat gemaakt met de naam Smudge. Zijn leeftijd is 3. We hebben een kat gemaakt met de naam Fluffy. Zijn leeftijd is 5 Totaal aantal katten = 2 Nu heeft onze klas een nieuwe variabele genaamd count. Het is verantwoordelijk voor het tellen van de gecreëerde katten. Elke keer creëren we een kat in het algemeenmethode verhogen we deze variabele met 1. Deze variabele wordt gedeclareerd met het sleutelwoord static. Dat betekent dat het tot de klasse behoort, niet tot een specifiek object van de klasse. Wat natuurlijk logisch is: de naam van elke kat hoort bij die specifieke kat, maar we hebben één kattenteller nodig die voor ze allemaal geldt. Dit is precies wat het trefwoord static bereikt: het maakt de count-variabele een enkele variabele voor alle katten. Opmerking: wanneer we de variabele weergeven, gebruiken we geen smudge.count of fluffy.count. Het is niet van Smudge of Fluffy; het behoort tot de gehele Cat- klasse. Daarom is het gewoon tellen. U kunt ook Cat.count schrijven. Dat zou ook juist zijn. Wanneer we de naamvariabele weergeven, zouden we het volgende niet doen:

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);
    }
}
Dit is een fout! Elke kat heeft zijn eigen naam. De compiler raakt hier in de war. "Een naam naar de console sturen? Wiens naam?" :/"

methoden

Naast variabelen heeft elke klasse methoden. We zullen er in een aparte les dieper op ingaan, maar de algemene principes zijn vrij eenvoudig. Methoden definiëren de functionaliteit van uw klasse, dwz wat objecten van uw klasse kunnen doen. Een van deze methodes ken je al: de main() methode. Maar, zoals u zich wellicht herinnert, is de hoofdmethode statisch, wat betekent dat deze tot de hele klasse behoort (de logica is dezelfde als bij variabelen). Standaard, niet-statische methoden kunnen echter alleen worden aangeroepen voor specifieke objecten die we hebben gemaakt. Als we bijvoorbeeld een kattenklasse willen schrijven, moeten we weten welke functies een kat in ons programma moet hebben. Laten we op basis daarvan een aantal methoden voor onze kat schrijven:

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();

    }
}
Bekijken! Nu lijkt onze klas veel meer op een kat! Nu hebben we niet alleen een kat met een naam ("Smudge") en een leeftijd (3). Hij kan ook miauwen en springen! Wat voor kat zou het zijn zonder die "functionaliteit"? :) We nemen een specifiek object (smudge) en roepen de methoden sayMeow() en jump() aan . Laten we naar de console kijken: miauw! Bespringen! Een echte kat! :)

Je eigen klassen maken. Abstractie

In de toekomst zul je je eigen lessen moeten schrijven. Waar moet je op letten als je ze schrijft? Als we het hebben over variabelen, dan moet je gebruik maken van iets dat abstractie wordt genoemd. Abstractie is een van de vier basisprincipes van objectgeoriënteerd programmeren. Het betekent het extraheren van de belangrijkste en meest significante kenmerken van een item, en omgekeerd, het terzijde schuiven van de ondergeschikte of onbeduidende kenmerken. Laten we bijvoorbeeld een archiefkast maken voor werknemers van het bedrijf. Om werknemersobjecten te maken, hebben we een werknemer geschrevenklas. Welke kenmerken zijn belangrijke descriptoren van een werknemer voor de archiefkast van ons bedrijf? Naam, geboortedatum, SSN en werknemers-ID. Maar het is onwaarschijnlijk dat we de lengte, oogkleur of haarkleur van de werknemer nodig hebben voor het werknemersdossier van het bedrijf. Bedrijven hebben deze informatie niet nodig. In de klasse Employee declareren we dus de volgende variabelen: String name , int age , int socialSecurityNumber en int employeeId. En onnodige informatie (zoals oogkleur) laten we weg. Met andere woorden, we creëren een abstractie. Als we echter een archiefkast maken voor modellenbureaus, verandert de situatie drastisch. De lengte, oogkleur en haarkleur van een model zijn belangrijke kenmerken, maar haar SSN is absoluut niet relevant voor ons. In de klasse Model moeten we dus de volgende variabelen maken: String height , String hair , String eyes . Dat is hoe abstractie werkt - het is gemakkelijk! :)

Constructeurs

Laten we teruggaan naar ons kattenvoorbeeld.

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";

    }
}
Bekijk deze code en probeer erachter te komen wat er mis is met ons programma. Ons programma had 2 uur lang een kat zonder naam of leeftijd! Dit is natuurlijk per definitie verkeerd. De database van de dierenkliniek mag geen katten bevatten zonder informatie. Momenteel is onze kat overgeleverd aan de programmeur. We vertrouwen erop dat hij niet vergeet een naam en leeftijd op te geven en dat alles goed komt. Als hij het vergeet, heeft de database een probleem: naamloze katten. Hoe kunnen we dit probleem oplossen? We moeten op de een of andere manier voorkomen dat katten worden gecreëerd zonder naam en leeftijd. Hier komen constructeurs te hulp. Laten we een voorbeeld geven:

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);
    }
}
In wezen is een constructor een sjabloon voor objecten van een klasse. In dit geval geven we aan dat voor elk cat -object twee argumenten, een String en een int , moeten worden opgegeven . Als we nu een naamloze kat proberen te creëren, zal dat niet lukken.

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!
    }
}
Nu de klasse een constructor heeft, weet de Java-compiler hoe de objecten eruit moeten zien en staat het niet toe dat objecten worden gemaakt zonder de argumenten te specificeren. Laten we nu het sleutelwoord this onderzoeken, dat u in de constructor ziet. Het is ook eenvoudig. Het sleutelwoord this is om een ​​bepaald object aan te duiden. De code in de constructor

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
kan bijna letterlijk worden geïnterpreteerd: "De naam van deze kat (degene die we aan het maken zijn) = het argument dat is doorgegeven voor de naamparameter van de constructeur. De leeftijd van deze kat (degene die we aan het maken zijn) = het argument dat is doorgegeven voor de constructor's leeftijdsparameter." Nadat de constructor is uitgevoerd, kunt u controleren of alle benodigde waarden aan onze kat zijn toegewezen:

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);
    }
}
Console-uitvoer: Smudge 5 Toen de constructor werd aangeroepen:

Cat smudge = new Cat("Smudge", 5);
Dit is wat er intern gebeurde:

this.name = "Smudge";
this.age = 5;
En de waarden van de argumenten die aan de constructor werden doorgegeven, werden toegewezen aan het smudge- object (daar verwijst dit in dit geval naar). Zelfs als je geen constructors in een klasse declareert, zal het nog steeds een constructor aanroepen! Maar hoe kan dat? О_О Omdat alle Java-klassen een zogenaamde standaardconstructor hebben. Er zijn geen argumenten voor nodig, maar het wordt elke keer aangeroepen wanneer u een object van een willekeurige klasse maakt.

public class Cat {

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Op het eerste gezicht is dit misschien niet vanzelfsprekend. We hebben een object gemaakt, dus wat? Waar doet de constructeur hier iets? Om het te zien, schrijven we expliciet een lege constructor voor de klasse Cat . Binnenin zullen we een zin naar de console sturen. Als de zin wordt weergegeven, is de constructor aangeroepen.

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
    }
}
Console-uitvoer: er is een kat gemaakt! Daar is de bevestiging. De standaard constructor is altijd onzichtbaar aanwezig in je klassen. Maar je moet er nog één ding over weten. De standaardconstructor wordt uit een klasse geëlimineerd zodra u een constructor met argumenten maakt. In feite hebben we hierboven al het bewijs hiervan gezien. Het stond in deze code:

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!
    }
}
We konden geen Cat maken zonder naam en leeftijd, omdat we een Cat- constructor met string- en int-parameters hebben gedeclareerd. Hierdoor verdween de standaardconstructor onmiddellijk uit de klasse. Onthoud dus dat als u meerdere constructors in uw klasse nodig heeft, inclusief een constructor zonder argumenten, u deze afzonderlijk moet declareren. Onze kliniek wil goede daden verrichten en dakloze kittens helpen waarvan de naam en leeftijd onbekend zijn. Dan zou onze code er zo uit moeten zien:

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();
    }
}
Nu we een expliciete standaardconstructor hebben opgegeven, kunnen we beide typen katten maken. In de constructor kunt u direct waarden toekennen. Je hoeft ze niet altijd uit argumenten te halen. We kunnen bijvoorbeeld alle straatkatten in de database labelen met "Straatkatten nr. <count>" als sjabloon. :

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);
    }
}
We hebben een telvariabele , die onze straatkatten telt. Elke keer dat de standaardconstructor wordt uitgevoerd, verhogen we het aantal met 1 en koppelen we dit nummer aan de naam van de kat. De volgorde van argumenten is erg belangrijk voor constructeurs. Laten we de argumenten voor naam en leeftijd die aan onze constructor zijn doorgegeven, omwisselen.

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!
    }
}
We hebben een fout! De constructor geeft duidelijk aan dat wanneer een Cat- object wordt gemaakt, het een nummer en een tekenreeks moet worden doorgegeven, in deze volgorde. Onze code werkt dus niet. Zorg ervoor dat u deze regel onthoudt en respecteert bij het declareren van uw eigen klassen:

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

public Cat(int age, String name) {
    this.age = age;
    this.name = name;
}
Dit zijn twee totaal verschillende constructeurs! Voer nu een paar taken uit om uw begrip van het materiaal te verstevigen. :)
  1. Museum van Oudheden.

    Het is jouw taak om een ​​Artifact- klasse te ontwerpen.
    Er worden drie soorten artefacten in het museum bewaard.
    Van het eerste type weten we niets behalve het door het museum toegekende serienummer (bijvoorbeeld: 212121).
    Van het tweede type kennen we het serienummer en de cultuur die het heeft gemaakt (bijvoorbeeld: 212121, "Azteken").
    Van het derde type kennen we het serienummer, de cultuur waarin het is gemaakt en de eeuw waarin het is gemaakt (bijvoorbeeld: 212121, "Azteken", 12).

    Maak een Artifact- klasse die de antiquiteiten beschrijft die in het museum worden bewaard en schrijf de vereiste set constructors voor de klasse. Maak vervolgens in de methode main() één artefact van elke soort.

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

    Laten we een gebruikersdatabase maken voor een datingwebsite.
    Maar hier is het probleem: u bent de vereiste volgorde van de argumenten vergeten en er is geen technische documentatie beschikbaar.
    Ontwerp een User- klasse, die de volgende velden zal hebben: name ( String ), age ( short ) en height ( int ).
    Maak het juiste aantal constructors aan, zodat de naam, leeftijd en lengte in willekeurige volgorde kunnen worden opgegeven.

    
    public class User {
    
        String name;
        short age;
        int height;
    
        // Write your code here
    
        public static void main(String[] args) {
            
        }
    }
    
Om te versterken wat je hebt geleerd, raden we je aan een videoles van onze Java-cursus te bekijken
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION