Konstruktoren (vollst.,kopier,standard)

sakizzo

Mitglied
Hi Leute!

Ich kann leider im Internet keine Erklärung zum Thema Kopierkonstruktor in Java finden.
Alles was ich mit meinem Basicwissen weiß, dass ein Standardkonstruktor der Konstruktor ohne Parameter ist, womit Standardwerte initialisiert werden.
Der vollständige Konstruktor ist dann der mit Parametern, womit man die Werte eines neuen Objektes initialisiert, die in den Parametern angegeben werden.

Was ist nun aber der Kopierkonstruktor?
Wie kann man den am Besten erklären?

Über eine verständliche Beschreibung würde ich mich sehr freuen,
Danke im Voraus, sakizzo
 
Hallo!

Ein Kopierkonstruktor dient der Erstellung einer Kopie eines Objektes der selben Klasse, und stellt eine alternative zur clone() Methode dar.

Ein solche Konstruktor übernimmt ein Objekt der eigenen Klasse als Parameter und initialisiert sich selbst auf Basis des übergebenen Objektes.

Hier ein Beispiel (Der Kopierkonstruktor ist der letzte der drei):

Java:
public class Person{
	
	private String vorname_ = "";
	private String nachname_ = "";

	public Person(){
		this.vorname_ = "Max";
		this.nachname_ = "Mustermann";
	}

	public Person(String vorname, String nachname){
		this.vorname_ = vorname;
		this.nachname_ = nachname;
	}

	public Person(Person person){
		this.vorname_ = person.getVorname();
		this.nachname_ = person.getNachname();
	}

	public String getVorname(){
		return vorname_;
	}

	public String getNachname(){
		return nachname_;
	}
}

mfg
Martin
 
Danke ersteinmal für deine Antwort, hilft schonmal weiter, habe jedoch noch einige Fragen:).

Wozu erstellt man eine Kopie eines Objektes?
Was gibt würde zur Standardausgabe gegeben werden, wenn man "person" (vom Kopierkonstruktor erstellt) übergibt?
Woher kommen die Werte?Also braucht man immer Getter Methoden dazu?
Ich verstehe den Sinn noch nicht so ganz....

sakizzo
 
Bleiben wir mal bei dem Beispiel mit den Personen. Mal angenommen, du hast eine Familie und alle Familienmitglieder wohnen noch im selben Haus. Das heißt, alle haben die selbe Adresse, die selbe Telefonnummer, den selben Nachnamen. Unterschiede gibt es lediglich im Geschlecht, dem Vornamen, dem Alter, dem Handy. Nun könnte man sich entsprechende Personen-Objekte erzeugen, welche dann mit allen Werten gefüttert werden. Allerdings macht das nicht sonderlich viel Spaß, wenn man viele Eigenschaften hat (und sich zudem auch noch viele ähneln)(Tippaufwand) und dass es nicht sonderlich schick aussieht und den Quellcode unnötigerweise aufbläht sollte auch klar sein. Man kann sich in so einem Fall einiges an Arbeit ersparen, indem man ein zweites Objekt auf der Basis des ersten erzeugt. Dabei kann man entweder die clone-Methode verwenden, oder aber einen Kopierkonstruktor. Bei der clone-Methode ist es so, dass das Objekt das Interface Cloneable implementieren muss. Dieses wird jedoch oft vergessen, was dann zu einer Fehlermeldung führt. Beim Kopierkonstruktor braucht man auf sowas nicht achten.

Welche Variante nun schöner aussieht oder welche einem eher gefällt, muss jeder für sich entscheiden.

Hier ein Beispiel:
Java:
package de.tutorials.sakizzo.kopierkonstruktor;

public class Person implements Cloneable {
	public enum Geschlecht {
		M, W
	}

	private Geschlecht	geschlecht;
	private String		handy;
	private String		nachname;
	private String		ort;
	private String		plz;
	private String		strasse;
	private String		telefon;
	private String		vorname;

	/**
	 * Default-Konstruktor.
	 */
	public Person() {
		setGeschlecht(Geschlecht.M);
	}

	/**
	 * Kopier-Konstruktor.
	 */
	public Person(Person p) {
		setVorname(p.getVorname());
		setNachname(p.getNachname());
		setStrasse(p.getStrasse());
		setPlz(p.getPlz());
		setOrt(p.getOrt());
		setTelefon(p.getTelefon());
		setHandy(p.getHandy());
		setGeschlecht(p.getGeschlecht());
	}

	@Override
	public Person clone() {
		Person p = null;
		try {
			p = (Person)super.clone();
		} catch(CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return p;
	}

	public Geschlecht getGeschlecht() {
		return geschlecht;
	}

	public String getHandy() {
		return handy;
	}

	public String getNachname() {
		return nachname;
	}

	public String getOrt() {
		return ort;
	}

	public String getPlz() {
		return plz;
	}

	public String getStrasse() {
		return strasse;
	}

	public String getTelefon() {
		return telefon;
	}

	public String getVorname() {
		return vorname;
	}

	public void setGeschlecht(Geschlecht geschlecht) {
		this.geschlecht = geschlecht;
	}

	public void setHandy(String handy) {
		this.handy = handy;
	}

	public void setNachname(String nachname) {
		this.nachname = nachname;
	}

	public void setOrt(String ort) {
		this.ort = ort;
	}

	public void setPlz(String plz) {
		this.plz = plz;
	}

	public void setStrasse(String strasse) {
		this.strasse = strasse;
	}

	public void setTelefon(String telefon) {
		this.telefon = telefon;
	}

	public void setVorname(String vorname) {
		this.vorname = vorname;
	}

	@Override
	public String toString() {
		return String.format("%s[%s,%s,%s,%s,%s,%s,%s,%s]",
				getClass().getName(), getVorname(), getNachname(),
				getStrasse(), getPlz(), getOrt(), getTelefon(), getHandy(),
				getGeschlecht());
	}
}
Java:
package de.tutorials.sakizzo.kopierkonstruktor;

import de.tutorials.sakizzo.kopierkonstruktor.Person.Geschlecht;

public class KopierkonstruktorBeispiel {
	public static void main(String[] args) {
		// Eine Person erzeugen
		Person p1 = new Person();
		p1.setVorname("Max");
		p1.setNachname("Mustermann");
		p1.setStrasse("Musterstrasse 1");
		p1.setPlz("01234");
		p1.setOrt("Musterhausen");
		p1.setTelefon("01234/56789");
		p1.setHandy("0800/999999");
		p1.setGeschlecht(Geschlecht.M);
		
		// Zweite Person auf Basis einer anderen Person erzeugen (clone())
		Person p2 = p1.clone();
		p2.setVorname("Tine");
		p2.setHandy("0900/666666");
		p2.setGeschlecht(Geschlecht.W);
		
		// Dritte Person auf Basis einer anderen Person erzeugen (Kopier-Konstruktor)
		Person p3 = new Person(p1);
		p3.setVorname("Tom");
		p3.setHandy("");
		
		// Alle drei Personen ausgeben
		System.out.println(p1);
		System.out.println(p2);
		System.out.println(p3);
	}
}

Ausgabe:
de.tutorials.sakizzo.kopierkonstruktor.Person[Max,Mustermann,Musterstrasse 1,01234,Musterhausen,01234/56789,0800/999999,M]
de.tutorials.sakizzo.kopierkonstruktor.Person[Tine,Mustermann,Musterstrasse 1,01234,Musterhausen,01234/56789,0900/666666,W]
de.tutorials.sakizzo.kopierkonstruktor.Person[Tom,Mustermann,Musterstrasse 1,01234,Musterhausen,01234/56789,,M]

Wie man sieht, kann man mit nur wenigen Schritten komplexe Objekte erzeugen ohne dass man alle tausend Eigenschaften von Hand eintippen muss. Gesagt sei noch, dass dieses Beispiel eher klein ist. Hierbei könnte man eventuell verkraften, dass man die Eigenschaften der Objekte immer neu eintippt, was nicht schön aussehen würde, aber das sei mal dahingestellt. Aber jetzt mal ohne zu übertreiben, es gibt Objekte, die einige Eigenschaften mehr haben, sagen wir mal bei einem Auto, ich denke da würde man mit 100 Eigenschaften gar nicht hinkommen. Dabei macht so ein Kopiervorgang durchaus Sinn, wobei ich sagen muss, dass das bei diesem Personenbeispiel auch schon sinnvoll war.
 
Zuletzt bearbeitet:
Danke für das aufwendige Beispiel....!also so wie ich das alles verstanden haben, ist ein vollst. Konstr. dazu da, eine Objekt zu erstellen mit genauen Werten, der Kopierkonstruktor ist dazu da eine Kopie eines Objektes zu erstellen und mittels Set ändert man bestimmte Eigenschaften, und der Standardkonstruktor erstellt ein Objekt ohne Eigenschaften!
Ist das so richtig?
 
Jap, haste richtig verstanden. Allerdings muss man keine Setter verwenden, ich versuche aber nach Möglichkeit anstatt direkt auf die Instanzvariablen zuzugreifen, die entsprechenden Methoden zu verwenden, da es sein kann, dass da noch anderen Abläufe stattfinden.
 
Zurück