Constructor in Java wordt gebruikt om een instantie van de klasse te creëren. Constructors lijken veel op methoden behalve twee dingen – de naam is hetzelfde als de klassenaam en het heeft geen retourtype. Soms worden constructors ook wel speciale methoden genoemd om een object te initialiseren.
Constructor in Java
Wanneer we het new
sleutelwoord gebruiken om een instantie van een klasse te creëren, wordt de constructor aangeroepen en wordt het object van de klasse geretourneerd. Aangezien een constructor alleen het object aan de klasse kan retourneren, wordt dit impliciet gedaan door de Java runtime en we hoeven er geen retourtype aan toe te voegen. Als we een retourtype aan een constructor toevoegen, dan wordt het een methode van de klasse. Dit is de manier waarop de Java runtime onderscheid maakt tussen een normale methode en een constructor. Laten we aannemen dat we de volgende code hebben in de Employee
klasse.
public Employee() {
System.out.println("Employee Constructor");
}
public Employee Employee() {
System.out.println("Employee Method");
return new Employee();
}
Hier is de eerste een constructor, merk op dat er geen retourtype en geen retourverklaring is. De tweede is een normale methode waar we weer de eerste constructor aanroepen om de Employee instantie te krijgen en terug te geven. Het wordt aanbevolen om de methode naam niet hetzelfde te hebben als de klassenaam omdat dit verwarring schept.
Soorten Constructor in Java
Er zijn drie soorten constructors in Java.
- Standaard Constructor
- Geen-Argumenten constructor
- Geparametriseerde constructor
Laten we eens kijken naar al deze constructortypen met voorbeeldprogramma’s.
Standaard Constructor in Java
Het is niet altijd nodig om een constructor-implementatie in de klassencode te verstrekken. Als we geen constructor verstrekken, zorgt Java voor een standaardconstructorimplementatie die we kunnen gebruiken. Laten we eens kijken naar een eenvoudig programma waarin de standaardconstructor wordt gebruikt, aangezien we geen constructor expliciet zullen definiëren.
package com.journaldev.constructor;
public class Data {
public static void main(String[] args) {
Data d = new Data();
}
}
- De enige rol van de standaardconstructor is om het object te initialiseren en terug te geven aan de aanroepende code.
- De standaardconstructor is altijd zonder argument en wordt door de Java-compiler alleen geleverd wanneer er geen bestaande constructor is gedefinieerd.
- Meestal zijn we tevreden met de standaardconstructor zelf, omdat andere eigenschappen toegankelijk en geïnitialiseerd kunnen worden via getter- en setter-methoden.
Geen-Argumenten Constructor
Constructor zonder enige argument wordt een no-args constructor genoemd. Het is als het overschrijven van de standaardconstructor en wordt gebruikt om enkele pre-initialisatie taken uit te voeren, zoals het controleren van bronnen, netwerkverbindingen, logging, enz. Laten we snel kijken naar de no-args constructor in Java.
package com.journaldev.constructor;
public class Data {
//no-args constructor
public Data() {
System.out.println("No-Args Constructor");
}
public static void main(String[] args) {
Data d = new Data();
}
}
Wanneer we nu new Data()
zullen aanroepen, zal onze no-args constructor worden aangeroepen. Onderstaande afbeelding illustreert dit gedrag, controleer de console-uitvoer van het programma.
Geparametriseerde Constructor
Constructor met argumenten wordt een geparametriseerde constructor genoemd. Laten we kijken naar het voorbeeld van een geparametriseerde constructor in Java.
package com.journaldev.constructor;
public class Data {
private String name;
public Data(String n) {
System.out.println("Parameterized Constructor");
this.name = n;
}
public String getName() {
return name;
}
public static void main(String[] args) {
Data d = new Data("Java");
System.out.println(d.getName());
}
}
Constructor Overloading in Java
Wanneer we meer dan één constructor hebben, dan is het constructor overloading in Java. Laten we eens kijken naar een voorbeeld van constructor overloading in een Java-programma.
package com.journaldev.constructor;
public class Data {
private String name;
private int id;
//no-args constructor
public Data() {
this.name = "Default Name";
}
//een parameter constructor
public Data(String n) {
this.name = n;
}
//twee parameter constructor
public Data(String n, int i) {
this.name = n;
this.id = i;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "ID="+id+", Name="+name;
}
public static void main(String[] args) {
Data d = new Data();
System.out.println(d);
d = new Data("Java");
System.out.println(d);
d = new Data("Pankaj", 25);
System.out.println(d);
}
}
Private Constructor in Java
Merk op dat we abstract, final, static en synchronized sleutelwoorden niet kunnen gebruiken met constructors. We kunnen echter wel toegangmodifiers gebruiken om de instantiëring van een klasse-object te controleren. Het gebruik van public
en default
-toegang is nog steeds prima, maar wat is het nut van het maken van een constructor privé? In dat geval kan geen enkele andere klasse een instantie van de klasse maken. Nou, een constructor wordt privé gemaakt in het geval dat we het singleton-ontwerppatroon willen implementeren. Aangezien Java automatisch een standaardconstructor biedt, moeten we expliciet een constructor maken en deze privé houden. Cliëntklassen krijgen een hulpprogramma met een statische methode om de instantie van de klasse te verkrijgen. Een voorbeeld van een privéconstructor voor de klasse Data
wordt hieronder gegeven.
// privé constructor
private Data() {
//lege constructor voor implementatie van het singleton-patroon
//kan code bevatten die wordt gebruikt binnen de getInstance()-methode van de klasse
}
Constructor Chaining in Java
Wanneer een constructor een andere constructor van dezelfde klasse aanroept, wordt dit constructor chaining genoemd. We moeten het this
-trefwoord gebruiken om een andere constructor van de klasse aan te roepen. Soms wordt dit gebruikt om standaardwaarden van de klassevariabelen in te stellen. Let op dat een andere constructoraanroep de eerste instructie in het codeblok moet zijn. Ook mogen er geen recursieve aanroepen zijn die een oneindige lus zouden creëren. Laten we een voorbeeld bekijken van constructor chaining in een Java-programma.
package com.journaldev.constructor;
public class Employee {
private int id;
private String name;
public Employee() {
this("John Doe", 999);
System.out.println("Default Employee Created");
}
public Employee(int i) {
this("John Doe", i);
System.out.println("Employee Created with Default Name");
}
public Employee(String s, int i) {
this.id = i;
this.name = s;
System.out.println("Employee Created");
}
public static void main(String[] args) {
Employee emp = new Employee();
System.out.println(emp);
Employee emp1 = new Employee(10);
System.out.println(emp1);
Employee emp2 = new Employee("Pankaj", 20);
System.out.println(emp2);
}
@Override
public String toString() {
return "ID = "+id+", Name = "+name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I have overridden the toString() method to print some useful information about Employee object. Below is the output produced by above program.
Employee Created
Default Employee Created
ID = 999, Name = John Doe
Employee Created
Employee Created with Default Name
ID = 10, Name = John Doe
Employee Created
ID = 20, Name = Pankaj
Merk op hoe één constructor vanuit een andere constructor wordt aangeroepen, dat heet het constructor chaining proces.
Java Super Constructor
Soms wordt een klasse geërfd van een superklasse, in dat geval, als we de constructor van de superklasse moeten aanroepen, kunnen we dat doen met het super
trefwoord. Laten we eens kijken naar een voorbeeld van het gebruik van de constructor van de superklasse. Let op dat de aanroep van de superconstructor de eerste instructie moet zijn in de constructor van de onderliggende klasse. Ook bij het instantiëren van de constructor van de onderliggende klasse initialiseert Java eerst de superklasse en vervolgens de onderliggende klasse. Dus als de constructor van de superklasse niet expliciet wordt aangeroepen, wordt de standaard- of no-args-constructor door Java-runtime aangeroepen. Laten we deze concepten begrijpen aan de hand van een voorbeeldprogramma. Laten we aannemen dat we twee klassen hebben zoals hieronder.
package com.journaldev.constructor;
public class Person {
private int age;
public Person() {
System.out.println("Person Created");
}
public Person(int i) {
this.age = i;
System.out.println("Person Created with Age = " + i);
}
}
package com.journaldev.constructor;
public class Student extends Person {
private String name;
public Student() {
System.out.println("Student Created");
}
public Student(int i, String n) {
super(i); // super class constructor called
this.name = n;
System.out.println("Student Created with name = " + n);
}
}
Als we nu een Student-object maken zoals hieronder;
Student st = new Student();
Wat zal de geproduceerde output zijn? De output van de bovenstaande code zal zijn:
Person Created
Student Created
Dus de aanroep ging naar de no-args constructor van de Student-klasse omdat er geen superaanroep was in de eerste instructie, wordt de no-args of standaardconstructor van de Person-klasse aangeroepen. Vandaar de output. Wat als we de geparametriseerde constructor van de Student-klasse gebruiken als Student st = new Student(34, "Pankaj");
, de output zal zijn:
Person Created with Age = 34
Student Created with name = Pankaj
Hier is de output duidelijk omdat we expliciet de constructor van de superklasse aanroepen, dus Java hoeft geen extra werk te doen van hun kant.
Kopie Constructor in Java
Java copy constructor neemt het object van dezelfde klasse als argument en maakt er een kopie van. Soms hebben we een kopie van een ander object nodig om wat verwerking te doen. We kunnen dit doen op verschillende manieren:
- implementeren van kloon
- het leveren van een hulpmethode voor diepe kopie van het object.
- Hebben van een kopieconstructor
Latenn we nu zien hoe we een kopieconstructor moeten schrijven. Stel dat we een klasse Fruits
hebben zoals hieronder.
package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class Fruits {
private List<String> fruitsList;
public List<String> getFruitsList() {
return fruitsList;
}
public void setFruitsList(List<String> fruitsList) {
this.fruitsList = fruitsList;
}
public Fruits(List<String> fl) {
this.fruitsList = fl;
}
public Fruits(Fruits fr) {
List<String> fl = new ArrayList<>();
for (String f : fr.getFruitsList()) {
fl.add(f);
}
this.fruitsList = fl;
}
}
Merk op dat Fruits(Fruits fr)
een diepe kopie uitvoert om de kopie van het object terug te geven. Laten we eens kijken naar een testprogramma om te begrijpen waarom het beter is om een kopieconstructor te hebben om een object te kopiëren.
package com.journaldev.constructor;
import java.util.ArrayList;
import java.util.List;
public class CopyConstructorTest {
public static void main(String[] args) {
List<String> fl = new ArrayList<>();
fl.add("Mango");
fl.add("Orange");
Fruits fr = new Fruits(fl);
System.out.println(fr.getFruitsList());
Fruits frCopy = fr;
frCopy.getFruitsList().add("Apple");
System.out.println(fr.getFruitsList());
frCopy = new Fruits(fr);
frCopy.getFruitsList().add("Banana");
System.out.println(fr.getFruitsList());
System.out.println(frCopy.getFruitsList());
}
}
De uitvoer van het bovenstaande programma is:
[Mango, Orange]
[Mango, Orange, Apple]
[Mango, Orange, Apple]
[Mango, Orange, Apple, Banana]
Merk op dat wanneer de kopieconstructor wordt gebruikt, zowel het oorspronkelijke object als de kopie niet met elkaar verbonden zijn en eventuele wijzigingen in een van hen niet worden weerspiegeld in de andere. Dat is alles voor de constructor in Java.
Source:
https://www.digitalocean.com/community/tutorials/constructor-in-java