CodeGym/Java Blog/Willekeurig/Opeenvolging van acties tijdens het maken van objecten
John Squirrels
Niveau 41
San Francisco

Opeenvolging van acties tijdens het maken van objecten

Gepubliceerd in de groep Willekeurig
Hoi! De les van vandaag zal nogal... uh... veelzijdig zijn :) in die zin dat we een breed scala aan onderwerpen zullen behandelen, maar ze zullen allemaal betrekking hebben op het proces van het maken van objecten . Volgorde van acties tijdens het maken van objecten - 1We zullen het van begin tot eind analyseren: hoe constructors worden genoemd, hoe en in welke volgorde velden (inclusief statische velden) worden geïnitialiseerd, enz. We hebben eerder enkele van de punten besproken die in het artikel worden besproken, zodat u er een blik op kunt werpen het materiaal op constructors van basisklassen . Laten we eerst eens kijken hoe een object wordt gemaakt. U herinnert zich nog goed hoe dit proces eruitziet vanuit het standpunt van een ontwikkelaar: hij maakt een klasse, schrijft new, en alles is klaar :) Hier zullen we het hebben over wat er in de computer en de Java-machine gebeurt als we schrijven, bijvoorbeeld:
Cat cat = new Cat();
We hebben hier eerder over gesproken, maar voor het geval we u eraan herinneren:
  • Eerst wordt geheugen voor het opslaan van het object toegewezen.
  • Vervolgens maakt de Java-machine een verwijzing naar het object (in ons geval is de verwijzing Cat cat).
  • Ten slotte worden variabelen geïnitialiseerd en wordt de constructor aangeroepen (we gaan dit proces in meer detail bekijken).
Bovendien herinnert u zich waarschijnlijk uit de les over de levenscyclus van objecten dat een object net zo lang meegaat als er minstens één verwijzing naar is. Als er geen meer zijn, wordt het object een prooi voor de vuilnisman. Volgorde van acties tijdens het maken van objecten - 2Deze eerste twee punten zouden geen speciale vragen moeten oproepen. Geheugentoewijzing is een eenvoudig proces en er zijn slechts twee mogelijke uitkomsten: er is geheugen of er is geen geheugen :) En het maken van een link is niet ongebruikelijk. Maar het derde punt vertegenwoordigt een hele reeks bewerkingen die in strikte volgorde worden uitgevoerd. Ik ben geen fan van proppen voor tests, maar je moet dit proces goed begrijpen en je moet deze reeks bewerkingen onthouden. Toen we het in vorige lessen hadden over het maken van objecten, wist je nog niet echt iets van overerving, dus sommige dingen uitleggen was problematisch. Nu weet je best veel en kunnen we deze vraag eindelijk volledig bekijken :) Dus het derde punt zegt " Ten slotte worden variabelen geïnitialiseerd en wordt de constructor aangeroepen. " Maar in welke volgorde gebeurt dit allemaal? Laten we voor een beter begrip twee supereenvoudige klassen maken: een ouder en een kind:
public class Vehicle {

   public static int vehicleCounter = 0;

   private String description = "Vehicle";
   public Vehicle() {
   }

   public String getDescription() {
       return description;
   }
}

public class Truck extends Vehicle {

   private static int truckCounter = 0;

   private int yearOfManufacture;
   private String model;
   private int maxSpeed;

   public Truck(int yearOfManufacture, String model, int maxSpeed) {
       this.yearOfManufacture = yearOfManufacture;
       this.model = model;
       this.maxSpeed = maxSpeed;

       Vehicle.vehicleCounter++;
       truckCounter++;
   }
}
De Truckklasse is een implementatie van een vrachtwagen met velden die het jaar, het model en de maximale snelheid vertegenwoordigen. Nu willen we zo'n object maken:
public class Main {

   public static void main(String[] args) throws IOException {

       Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
   }
}
Voor de Java-machine ziet het proces er als volgt uit:
  1. Het eerste dat gebeurt, is dat de statische variabelen van de Vehicleklasse worden geïnitialiseerd . Ja, ik zei de Vehicleklas, niet Truck. Statische variabelen worden geïnitialiseerd voordat constructors worden aangeroepen, en dit begint in de bovenliggende klasse. Laten we proberen dit te verifiëren. We stellen het vehicleCounterveld in de Vehicleklasse gelijk aan 10 en proberen het weer te geven in zowel de Vehicleen Truckconstructors.

    public class Vehicle {
    
       public static int vehicleCounter = 10;
       private String description = "Vehicle";
    
       public Vehicle() {
           System.out.println(vehicleCounter);
       }
    
       public String getDescription() {
           return description;
       }
    }
    
    public class Truck extends Vehicle {
    
       private static int truckCount = 0;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
           System.out.println(vehicleCounter);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCount++;
       }
    }

    We hebben de instructie println met opzet helemaal aan het begin van de Truckconstructor geplaatst om er zeker van te zijn dat de velden van de vrachtwagen nog niet zijn geïnitialiseerd wanneer vehicleCounterwordt weergegeven.

    En hier is het resultaat:

    10
    10
  2. Nadat de statische variabelen van de bovenliggende klasse zijn geïnitialiseerd, worden de statische variabelen van de onderliggende klasse geïnitialiseerd. In ons geval is dit het truckCounterveld van de Truckklasse.

    Laten we nog een experiment doen waarbij we proberen de waarde van truckCounterbinnen de Truckconstructor weer te geven voordat de andere velden worden geïnitialiseerd:

    public class Truck extends Vehicle {
    
       private static int truckCounter = 10;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
           System.out.println(truckCounter);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCounter++;
       }
    }

    Zoals u kunt zien, is de waarde 10 al toegewezen aan onze statische variabele wanneer de Truckconstructor begint.

  3. Het is nog steeds geen tijd voor de constructeurs! Variabele initialisatie gaat door. De niet-statische variabelen van de bovenliggende klasse worden als derde geïnitialiseerd. Zoals je kunt zien, bemoeilijkt overerving het proces van het maken van een object aanzienlijk, maar je kunt er niets aan doen: je moet gewoon een aantal dingen onthouden tijdens het programmeren :)

    Bij wijze van experiment kunnen we een beginwaarde toekennen aan de descriptionvariabele in Vehicleclass en deze vervolgens wijzigen in de constructor.

    public class Vehicle {
    
       public static int vehicleCounter = 10;
    
       private String description = "Initial value of the description field";
    
       public Vehicle() {
           System.out.println(description);
           description = "Vehicle";
           System.out.println(description);
       }
    
       public String getDescription() {
           return description;
       }
    }

    Laten we onze main()methode uitvoeren die een vrachtwagen maakt:

    public class Main {
    
       public static void main(String[] args) throws IOException {
    
           Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
       }
    }

    We krijgen het volgende resultaat:

    Initial value of the description field
    Vehicle

    Dit bewijst dat wanneer de Vehicleconstructor begint, het descriptionveld al een waarde heeft gekregen.

  4. Eindelijk is het tijd voor de constructeurs! Om precies te zijn, het is tijd voor de constructor van de basisklasse. Het wordt aangeroepen in de vierde stap van het objectcreatieproces.

    Dit is ook vrij eenvoudig te verifiëren. Laten we proberen twee regels naar de console uit te voeren: één binnen de Vehicleconstructor van de basisklasse, de tweede binnen de Truckconstructor. We moeten ervan overtuigd zijn dat de regel binnenin Vehicleals eerste wordt weergegeven:

    public Vehicle() {
    
       System.out.println("Hello from the Vehicle constructor!");
    }
    
    public Truck(int yearOfManufacture, String model, int maxSpeed) {
    
       System.out.println("Hello from the Truck constructor!");
       this.yearOfManufacture = yearOfManufacture;
       this.model = model;
       this.maxSpeed = maxSpeed;
    
       Vehicle.vehicleCounter++;
       truckCounter++;
    }

    We zullen onze main()methode uitvoeren en naar het resultaat kijken:

    Hello from the Vehicle constructor!
    Hello from the Truck constructor!

    Uitstekend. Dat betekent dat we ons niet vergissen :) Laten we verder gaan.

  5. Nu is het tijd voor initialisatie van de niet-statische velden van de onderliggende klasse, dwz onze Truckklasse. De velden direct binnen de klasse die wordt geïnstantieerd, worden pas in de vijfde stap geïnitialiseerd! Verrassend, maar waar :) Nogmaals, we zullen een eenvoudige controle uitvoeren — net als bij de ouderklasse: we geven een beginwaarde aan de maxSpeedvariabele en in de Truckconstructor controleren we of de waarde was toegewezen voordat de constructor startte:

    public class Truck extends Vehicle {
    
       private static int truckCounter = 10;
    
       private int yearOfManufacture;
       private String model;
       private int maxSpeed = 150;
    
       public Truck(int yearOfManufacture, String model, int maxSpeed) {
    
           System.out.println("Initial value of maxSpeed = " + this.maxSpeed);
           this.yearOfManufacture = yearOfManufacture;
           this.model = model;
           this.maxSpeed = maxSpeed;
    
           Vehicle.vehicleCounter++;
           truckCounter++;
       }
    }

    Console-uitvoer:

    Initial value of maxSpeed = 150

    Zoals u kunt zien,  is wanneer de Truck constructor start maxSpeed al gelijk aan 150!

  6. De constructor van de Truckonderliggende klasse wordt aangeroepen.

    En pas op dit punt, als laatste, zal de constructor van de klasse die we instantiëren worden aangeroepen!

    Pas in de zesde stap krijgen de velden de waarden toegewezen die we als argumenten doorgeven aan onze vrachtwagen.

    Zoals u kunt zien, is het "construeren" van een vrachtwagen, dwz het maken van objecten, niet eenvoudig. Maar het lijkt erop dat we het in de kleinste delen hebben opgesplitst :)

Opeenvolging van acties tijdens het maken van objecten - 3 Waarom is het zo belangrijk om dit proces goed te begrijpen? Stel je voor hoe onverwacht de resultaten van het maken van een gewoon object zouden kunnen zijn als je niet precies wist wat er "onder de motorkap" gebeurde :) Nu is het tijd om terug te keren naar de cursus en enkele taken te voltooien! Veel succes en tot snel! :)
Opmerkingen
  • Populair
  • Nieuw
  • Oud
Je moet ingelogd zijn om opmerkingen te kunnen maken
Deze pagina heeft nog geen opmerkingen