C# Getter & Setter? Konstruktoren?

Socnrd

Lt. Junior Grade
Registriert
März 2007
Beiträge
464
Hallo,

ich habe eine Frage zu den Themen "Getter und Setter" und zu "Konstruktoren".
Ich habe eine lange Zeit herumgegooglet, aber so wirklich verstanden habe ich beides nicht...

Getter und Setter braucht man anscheinend, damit nicht jede Klasse sieht, was in einer Klasse passiert - stimmt das?
Kann mir jemand ein Beispiel für einen Getter und Setter-Ablauf posten? Am besten mit Hilfe des Codes unten.

Und dann die Frage: Weshalb gibt es 2 verschiedene Konstruktoren? Standardkonstruktor und Parameterisierterkonstruktor???

Code:
    class Schueler
    {   //**** Attribute:  (zusammengenommen als Daten bezeichnet)  
        public string name;
        public string vName;
        public string ort;
        public int plz;
        public int gebJahr;
        public double entf_WS;
        public double entf_WB;

        //***************************** Methoden:
        //***** 1.) Standardkonstruktor:
        public Schueler()
        {
            name = "";
            vName = "";
            ort = "";
            plz = 0;
            gebJahr = 0;
            entf_WS = 0.0;
            entf_WB = 0.0;
        }
        //***** 2.) Parametrisierter Konstruktor:
        public Schueler(string n, string vN, string o, int pz, int gJ,
                        double eWS, double eWB)
        {
            name = n;
            vName = vN;
            ort = o;
            plz = pz;
            gebJahr = gJ;
            entf_WS = eWS;
            entf_WB = eWB;
        }



    }
}

Gruß
 
Öffentliche Datenfelder sind schlecht, weil sich so starke Abhängigkeiten zwischen einzelnen Klasse ergeben, also der Klasse mit den Datenfeldern und der verwendenden Klasse. Entfernst du beispielsweise ein Datenfeld , musst du dies in allen verwendenden Klassen anpassen.
Verwendest du allerdings einen Getter, also eine Methode, die den Wert eines Datenfelds zurückgibt, muss das Entfernen des Datenfelds nicht auch das Entfernen der Getter-Methode bedeuten. So hat dies keine Auswirkungen auf verwendende Klassen. Die Begriffe, die hier wichtig sind, sind Kopplung, Kohäsion und Kapselung.

Was den Konstruktur angeht, du kannst beliebig viele davon erstellen mit einer beliebigen Parameterliste, genau wie bei Methoden. Die übergebenen Werte dienen dem Konstruktor dann zum Initialisieren der Datenfelder. So viele Parameter sind allerdings eindeutig zuviel meiner Meinung nach.
 
Na ja, bei dir sind die Variablen als "public" bezeichnet, somit hättest du Getter & Setter nicht mehr gebraucht.

Dies ist jedoch nicht erwünscht, da so eine Manipulation von außen möglich wäre, und unter Umständen bestimmte Abläufe bei dir falsch laufen würden.

Also schön "private" deklarieren, und für jede Variable, die von außen abgerufen oder geändert werden soll, eine Getter- und Setter-Methode.

Wenn du zB die PLZ individuell festlegen willst, dann sähe der Setter so aus:

Code:
public int SetPLZ(int p)
{
 plz = p
}

und der Getter:

Code:
public int GetPLZ
{
 return plz
}

Hoffe, das hilft dir weiter.

Der Standardkonstruktor dient dazu einen Schüler mit Default-Werten anzulegen und bedarf daher keine Parameter (Leere Klammern), im Gegensatz zum anderen wo die Parameter unbedingt in der Reihenfolge eingegeben werden MÜSSEN.
Ein Standardkonstruktor ist eigentlich nicht üblich. Ist nur eine Komfort-Sache.
 
Zuletzt bearbeitet:
In deinem Codebeispiel brauchst du eigentlich keine Getter- und Set-Methoden, da die Attribute (Daten) alle public sind und du außerhalb der Klasse auf diese zugreifen kannst. Das ist aber nicht der Sinn von Klassen, denn die Attribute einer Klasse sollten nicht von außen veränderbar sein (protected oder private). Nur die Klasse selber darf diese verändern, damit alles schön gekapselt ist. Wenn du die Attribute nun ändern oder auslesen willst, geht das nur über den Umweg mit den Getter- und Set-Methoden. Diese Methoden müssen public sein, damit man von außen auf die Methoden zugreifen kann. Ist zwar alles C++, das soltle sich aber nicht stark von C# unterscheiden.

Die verschiedenen Konstruktoren dienen dazu verschiedene Kostruktoraufrufe zu ermöglichen. Der Konstruktoraufruf ohne Parameter soll ein definiertes Objekt erzeugen, darum müssen die Attribute auf einen bestimmten Wert gestellt werden, sonst würde sich "Datenmüll" in den Attributen befinden bzw. das was gerade an der Speicherplatz befindet.
 
Hallo

Soldier89 schrieb:
Getter und Setter braucht man anscheinend, damit nicht jede Klasse sieht, was in einer Klasse passiert - stimmt das?

Nicht direkt. Getter und Setter sind dafür da, damit andere Klassen die Attribute deiner Klasse nicht direkt manipulieren können. Attribute sollten immer durch getter und setter gelesen und geändert werden. Vorteil ist: Beim Setter kannst du noch Plausi-Prüfungen einbauen und bei fehlerhaften Werten eine Fehlermeldung o.Ä. bringen.

Soldier89 schrieb:
Kann mir jemand ein Beispiel für einen Getter und Setter-Ablauf posten? Am besten mit Hilfe des Codes unten.

Code:
private String myString;

public String getMyString() {
  return myString;
}

public void setMyString(String value) {
  myString = value;
}

Hoffe, dass das valider C# code ist, normalerweise programmiere ich in Java und C ;)

Soldier89 schrieb:
Und dann die Frage: Weshalb gibt es 2 verschiedene Konstruktoren? Standardkonstruktor und Parameterisierterkonstruktor???

Du kannst auch mehr als zwei verschiedene Kontruktoren nehmen. Das ist einfach dafür da, dass du eine Objekt mit verschiedenen Parametern erstellen kannst. In deinem Beispiel kannst du das Objekt mit Default-Attributen erstellen, dafür ist der Konstruktor ohne Parameter da. Wenn du diese Attribute aber bei der Erstellung des Objekts schon ändern willst, kannst du sie bei dem anderen Konstruktor direkt mitgeben.

Das klappt auch nicht nur bei Konstruktoren, du kannst alle Funktionen mehrfach mit verschiedenen Parametern überschrieben ;)

Gruß Asfaloth
 
In C# macht man keine Getter- und Setter-Methoden, sondern Properties, die aber vom Compiler zu Methoden umgewandelt werden:

public int Test
{
get{ return 0; }
set{ this.test = value; }
}

Sind dann zu verwenden wie Variablen selbst. Angenommen die Property ist von der Klasse XY und das Objekt der Klasse XY heißt z, dann wäre die Property so zu verwenden:

XY z = new XY();
z.Test = z.Test + 1;
 
kinglouy schrieb:
Was den Konstruktur angeht, du kannst beliebig viele davon erstellen mit einer beliebigen Parameterliste, genau wie bei Methoden. Die übergebenen Werte dienen dem Konstruktor dann zum Initialisieren der Datenfelder. So viele Parameter sind allerdings eindeutig zuviel meiner Meinung nach.

Die Parameter wurden von meinem C# Lehrer so vorgegeben...
Ich verstehe nur nicht, wofür man diese braucht.

sparvar schrieb:
http://openbook.galileocomputing.de/visual_csharp_2010/

hier werden sie geholfen ;) (ist ein gutes buch, habe ich selber)

Ist aber nicht gerade günstig :O

Jongar schrieb:
Na ja, bei dir sind die Variablen als "public" bezeichnet, somit hättest du Getter & Setter nicht mehr gebraucht.

Dies ist jedoch nicht erwünscht, da so eine Manipulation von außen möglich wäre, und unter Umständen bestimmte Abläufe bei dir falsch laufen würden.

Also schön "private" deklarieren, und für jede Variable, die von außen abgerufen oder geändert werden soll, eine Getter- und Setter-Methode.

Wenn du zB die PLZ individuell festlegen willst, dann sähe der Setter so aus:

Code:
public int SetPLZ(int p)
{
 plz = p
}

und der Getter:

Code:
public int GetPLZ
{
 return plz
}

Hoffe, das hilft dir weiter.

Der Standardkonstruktor dient dazu einen Schüler mit Default-Werten anzulegen und bedarf daher keine Parameter (Leere Klammern), im Gegensatz zum anderen wo die Parameter unbedingt in der Reihenfolge eingegeben werden MÜSSEN.
Ein Standardkonstruktor ist eigentlich nicht üblich. Ist nur eine Komfort-Sache.

Müsste ich dann für alles in meinem Code (Alter, Name,...) einen Getter und Setter erstellen?
Und was passiert, wenn ich den Standardkonstruktor weg lasse?

And.! schrieb:
In deinem Codebeispiel brauchst du eigentlich keine Getter- und Set-Methoden, da die Attribute (Daten) alle public sind und du außerhalb der Klasse auf diese zugreifen kannst. Das ist aber nicht der Sinn von Klassen, denn die Attribute einer Klasse sollten nicht von außen veränderbar sein (protected oder private). Nur die Klasse selber darf diese verändern, damit alles schön gekapselt ist. Wenn du die Attribute nun ändern oder auslesen willst, geht das nur über den Umweg mit den Getter- und Set-Methoden. Diese Methoden müssen public sein, damit man von außen auf die Methoden zugreifen kann. Ist zwar alles C++, das soltle sich aber nicht stark von C# unterscheiden.

Die verschiedenen Konstruktoren dienen dazu verschiedene Kostruktoraufrufe zu ermöglichen. Der Konstruktoraufruf ohne Parameter soll ein definiertes Objekt erzeugen, darum müssen die Attribute auf einen bestimmten Wert gestellt werden, sonst würde sich "Datenmüll" in den Attributen befinden bzw. das was gerade an der Speicherplatz befindet.

Es ist alles public, weil ich keinen schimmer habe, wie ich das auf private setzen kann (und zwar so, dass der Programm dann auch funktioniert).



Könnte mir jemand den Code bitte so umschreiben, dass die Klasse private ist und die getter und setter Methoden vorhanden sind? Zur Zeit habe ich nämlich nur ein großes ? vor den Augen.

Trotzdem danke an die bisherigen Beiträge!
 
Code:
public class abc
{
	protected int _def;
	public int def // normaler  getter & setter
	{
		get { return _def; }
		set { _def = value; }
	}
	
	public int ghi { get; set; } // Kurzform von oben
	
	protected int _jkl;
	public int jkl // getter only
	{
		get { return _jkl; }
		private set {}
	}
	
	protected int _mno;
	public int mno // mit Prüfung
	{
		get { return _mno; }
		set
		{
			if( value >= 0 && value <= 10 )
				_mno = value;
			else
				throw new Exception( "Nur von 0 bis 10." );
		}
	}
}
Soldier89 schrieb:
Könnte mir jemand den Code bitte so umschreiben, dass die Klasse private ist und die getter und setter Methoden vorhanden sind? Zur Zeit habe ich nämlich nur ein großes ? vor den Augen.
Lies dich ein und nimm es selbst vor, sonst würdest du es auch nicht verstehen.
 
@soldier - ja klar ist es nicht günstig, aber dieses geld ist gut investiert wenn du c# lernen willst/mußt.

außerdem ist es als openbook online umsonst. ich verwende z.b. online als nachschlagewerk. das buch ist jedenfalls sein geld wert.
 
Soldier89 schrieb:
Müsste ich dann für alles in meinem Code (Alter, Name,...) einen Getter und Setter erstellen?
Und was passiert, wenn ich den Standardkonstruktor weg lasse?
Wenn du die Felder nach außen hin sicht- und änderbar machen willst, ja.
Wenn du den Standardkonstruktor weg lässt, musst du immer den 2. Konstruktor benutzen.

Soldier89 schrieb:
Es ist alles public, weil ich keinen schimmer habe, wie ich das auf private setzen kann (und zwar so, dass der Programm dann auch funktioniert).
Du setzt die Felder auf private indem du "public" gegen "private" austauschst ;)
Dann musst du natürlich auch die öffentlichen Getter/Setter benutzen.
"Das Programm funktioniert nicht" ist übrigens eine sehr ungenaue Beschreibung. Fehlermeldungen wäre hier sehr hilfreich.

Soldier89 schrieb:
Könnte mir jemand den Code bitte so umschreiben, dass die Klasse private ist und die getter und setter Methoden vorhanden sind? Zur Zeit habe ich nämlich nur ein großes ? vor den Augen.
Nein, da dies kein Hausaufgabenforum ist und du dabei auch nichts lernen würdest.
 
Moin,

einen Konstruktor sollte man nutzen, wenn die Instanz einer Klasse Initialwerte benötigt, damit dieses Objekt überhaupt "leben" kann bzw. man verhindern möchte, dass diese Werte dann nochmals verändert werden können. Werte, die per Konstruktor übergeben werden, haben in der Regel dann nur noch lesbare Properties (private set) oder eben Methoden, die dann die Werte zurückgeben. (Stichpunkt wäre hier vielleicht Domain Driven Design).

Des Weiteren werden häufig Abhängigkeiten / abhängige Implementierungen per Konstruktor übergeben. (Stichpunkt(e) hier: IoC / Dependency Injection bzw. Single Responsibility Prinzip)

EDIT:Der parameterisierte Konstruktor aus dem Beispiel ist im Grunde genommen sinnlos, da die Werte von aussen manipuliert werden können. Daher sollte der Zugriff auf Klassenmember (Private Fields) immer gekapselt werden. Entweder furch entsprechende Methoden oder Properties. Vorteil, wie bereits erwähnt, wäre die Validierung der eingegebenen Daten.
 
Zuletzt bearbeitet:
lbm1305 schrieb:
Moin,

einen Konstruktor sollte man nutzen, wenn die Instanz einer Klasse Initialwerte benötigt, damit dieses Objekt überhaupt "leben" kann bzw. man verhindern möchte, dass diese Werte dann nochmals verändert werden können. Werte, die per Konstruktor übergeben werden, haben in der Regel dann nur noch lesbare Properties (private set) oder eben Methoden, die dann die Werte zurückgeben. (Stichpunkt wäre hier vielleicht Domain Driven Design).

Des Weiteren werden häufig Abhängigkeiten / abhängige Implementierungen per Konstruktor übergeben. (Stichpunkt(e) hier: IoC / Dependency Injection bzw. Single Responsibility Prinzip)

EDIT:Der parameterisierte Konstruktor aus dem Beispiel ist im Grunde genommen sinnlos, da die Werte von aussen manipuliert werden können. Daher sollte der Zugriff auf Klassenmember (Private Fields) immer gekapselt werden. Entweder furch entsprechende Methoden oder Properties. Vorteil, wie bereits erwähnt, wäre die Validierung der eingegebenen Daten.

Er kennt nichtmal den Unterschied zwischen public und private und du kommst mit ihm mit Entwurfsmustern ;) Köstlich ;)
 
Zurück
Oben