Klassen/Objekte Verständnis

chrisddj

Neues Mitglied
Hi

Vor kurzem habe ich angefangen mich mit Java zu beschäftigen. Um mir das alles anzueignen benutze ich "Java ist auch eine Insel".
Da mich Klassen/Objekte irgendwie ein bisschen verwirrt haben, habe ich versucht mir das mal an einem Beispiel klarzumachen.
Dazu hab ich ein paar Fragen:
1. Ist meine herangehensweise, den Code auf mehrere *.java Dateien zu verteilen, so in Ordnung? Ich bin mir nicht sicher ob ich verstanden habe wie man seinen Code aufteilen sollte.
2. Wenn ich Methoden oder Variablen aus den Klassen Konto oder Menu in meiner main() benutzen möchte, muss ich dann immer soetwas wie
Java:
Menu startMenu = new Menu();
Konto Peter = new Konto();
in meiner main() schreiben?
3. Bei meiner Menüauswahl, bei der ich zwischen 1,2 oder 3 entscheiden kann, möchte ich auf die Methoden in meiner Klasse Konto zugreifen. Das funktioniert aber nicht ohne
Java:
	Konto Peter = new Konto();
	Peter.ID = 1337;
	Peter.inhaber = "Peter";
	Peter.kapital = 256;
nochmal in der Methode schreibe, obwohl ich das ja eigentlich schon in meiner main() (also Bank.java) getan habe. Lässt sich darauf irgendwie zugreifen?

Verzeiht mir die gemischten Namen mancher Methoden, mir ist in dem Moment nichts besseres eingefallen.

Vielen Dank im Voraus wenn sich jemand die Mühe macht das alles durchzulesen 🙂

Hier mein Beispielprogramm:

Bank.java
Java:
package klassenuebung;

import static java.lang.System.out;

import java.util.Scanner;

public class Bank {

	public static void main(String[] args) {
		Menu startMenu = new Menu();
		Konto Peter = new Konto();
		
		Peter.ID = 123;
		Peter.inhaber = "Peter";
		Peter.kapital = 256;
		
		
		out.println("Kontonummer: ");
		Scanner kontoNummerInput = new Scanner(System.in);
		double idInput = kontoNummerInput.nextInt();
		if(idInput == Peter.ID){
			out.println("Willkommen " + Peter.inhaber + "!");
			startMenu.showMenu();
		} else {
			out.println("Falsche Kontonummer!");
		}
		
		
	}
}

Konto.java
Java:
package klassenuebung;
import static java.lang.System.out;
import java.util.Scanner;

public class Konto {
	double ID;
	double kapital;
	String inhaber;
	
	
	public void zeigeInhaber(){
		out.println("Inhaber des Kontos: " + inhaber);
	}
	
	public void showKapital(){
		out.println("Ihr Kontostand beträgt: " + kapital + " €");
	}
	
	public void einzahlung(){
		out.println("Wieviel € möchten Sie einzahlen? ");
		Scanner userInput = new Scanner(System.in);
		double betrag = userInput.nextDouble();
		kapital += betrag;
		out.println("Ihr Kontostand beträgt nun " + kapital + " €");
	}
	
	public void auszahlung(){
		out.println("Wieviel € möchten Sie auszahlen? ");
		Scanner userInput = new Scanner(System.in);
		double betrag = userInput.nextDouble();
		kapital -= betrag;
		out.println("Ihr Kontostand beträgt nun " + kapital + " €");
	}
	
}

Menu.java
Java:
package klassenuebung;

import static java.lang.System.out;

import java.util.Scanner;

public class Menu {
	
	public void showMenu(){
		out.println("Was möchten Sie tun?");
		out.println("1: Kontostand prüfen, 2: Einzahlung, 3: Auszahlung");
		Scanner userInput = new Scanner(System.in);
		String menuAuswahl = userInput.next();
				
		Konto Peter = new Konto();
		Peter.ID = 123;
		Peter.inhaber = "Peter";
		Peter.kapital = 256;

		switch(menuAuswahl){
			case "1":
				out.println("--Kontostand--");
				Peter.showKapital();
				break;
			case "2":
				out.println("--Einzahlung--");
				Peter.einzahlung();
				break;
			case "3":
				out.println("--Auszahlung--");
				Peter.auszahlung();
				break;
			default:
				out.println("Wählen Sie zwischen 1,2 oder 3!");
				break;
		}
		
	}
}
 
Hi chrisddj,
deine Nutzung von Objekten ist richtig (auf dem ersten Blick),
jedoch werden eigentlich Objektvariablen als private deklariert, da sonst auch andere Klassen von außen auf jene Zugreifen können --> das ganze wird unsicher und ist nicht erwünscht,
Also ändere besser die Variablen der Klasse Konto in private:
private double ID;
private double kapital;
private String inhaber;

und gib ihnen jeweils eine get- und set-Methode:

[Java]//set-Methode für einen int:
public void setNameDerVariable(int x){
NameDerVariable=x;
}
//get-Methode für einen int:
public int getNameDerVariable(){
return NameDerVariable
}[/Java]

3. Bei meiner Menüauswahl, bei der ich zwischen 1,2 oder 3 entscheiden kann, möchte ich auf die Methoden in meiner Klasse Konto zugreifen. Das funktioniert aber nicht ohne
Java Code:

Konto Peter = new Konto();
Peter.ID = 1337;
Peter.inhaber = "Peter";
Peter.kapital = 256;


nochmal in der Methode schreibe, obwohl ich das ja eigentlich schon in meiner main() (also Bank.java) getan habe. Lässt sich darauf irgendwie zugreifen?
In deinem Programm greift die Klasse Bank ja nicht direkt auf das Konto von Peter zu sondern erstellt nur ein Menu, welches wiederum ein Konto erstellt / erstellen muss da Objekte (ganz grob) an die Klasse in der Sie erstellt wurden gebunden sind.

(Dies stimmt aber nicht ganz denn man kann Objekte auch als public deklarieren und sie damit für jeder Klasse "sichtbar" machen oder mit dem Konstruktor an andere Objekt übergeben)

Also ist das Objekt Konto in der main überflüssig oder du übergibst es an die Klasse Menu oder lässt alle Methoden der Klasse Menu (showMenu()) als Parameter ein Objekt von der Klasse Konto erwarten mit welchem dann die Methode weiterarbeiten. (Die 3. Variante ist die beste, weil dann nicht für jedes neue Konto ein neues Menu gebraucht wird.):
[Java]public void showMenu(Konto myKonto){
//Code..
//in der switch dann:
switch(menuAuswahl){
case "1":
out.println("--Kontostand--");
myKonto.showKapital();
break;
case "2":
out.println("--Einzahlung--");
myKonto.einzahlung();
break;
case "3":
out.println("--Auszahlung--");
myKonto.auszahlung();
break;
default:
out.println("Wählen Sie zwischen 1,2 oder 3!");
break;
}[/Java]
 
Hi,

danke für deine Antwort. Dass das nicht sicher war dachte ich mir schon. Hab alles so umgesetzt wie du es vorgeschlagen hast und es funktioniert. 🙂
Werde mir morgen noch ein zweites Beispiel ausdenken und daran ausprobieren.

Vielen Dank soweit für die Hilfe.
 
Hi chrisddj,
deine Nutzung von Objekten ist richtig (auf dem ersten Blick),
jedoch werden eigentlich Objektvariablen als private deklariert, da sonst auch andere Klassen von außen auf jene Zugreifen können --> das ganze wird unsicher und ist nicht erwünscht,
Also ändere besser die Variablen der Klasse Konto in private:
private double ID;
private double kapital;
private String inhaber;

und gib ihnen jeweils eine get- und set-Methode:

[Java]//set-Methode für einen int:
public void setNameDerVariable(int x){
NameDerVariable=x;
}
//get-Methode für einen int:
public int getNameDerVariable(){
return NameDerVariable
}[/Java]

Wobei als fragende Anmerkung: Die Setter und Getter in dieser Form sind genauso unsicher wie der direkte Zugriff auf die Objektvariablen, da ja keine Einschränkung erfolgt. Denn so kann ich die Objektvariablen genauso "platt" machen - nur eben über den Setter. So ist also - abgesehen vom Stil - gar nichts gewonnen?
 
Wobei als fragende Anmerkung: Die Setter und Getter in dieser Form sind genauso unsicher wie der direkte Zugriff auf die Objektvariablen, da ja keine Einschränkung erfolgt. Denn so kann ich die Objektvariablen genauso "platt" machen - nur eben über den Setter. So ist also - abgesehen vom Stil - gar nichts gewonnen?

Prinzipiell ist es schöner Programmierstil, diese Variablen mit private zu deklarieren. Weiters kannst du ja selber entscheiden ob du willst, dass diese Variablen von außerhalb modifiziert werden dürfen. Dementsprechend implementierst du Setter/Getter-Methoden. Sobald du deine Methoden implementiert hast, willst du doch eigentlich explizit, dass Sie geändert werden dürfen.

Implementierst du die Getter/Setter nicht, dann willst du auch nicht dass sie modifiziert werden können.

Ich denke hier ist es auch noch wunderschön beschrieben: Quelle: Zugriffsfunktion – Wikipedia
Änderungsmethoden (Setter)

Eine Zugriffsmethode, die ein Objektattribut ändert, heißt auch Änderungsmethode oder Setter (von englisch to set – etwas einstellen, setzen). Ein Vorteil der Änderungsmethode besteht darin, dass sie vor der Änderung den Wert auf Gültigkeit prüfen kann. So könnte beispielsweise in einem Objekt, das eine Person darstellt, die Funktion zum Setzen des Namens sicherstellen, dass als Name kein leerer Text übergeben wird. Falls ein ungültiger Wert übergeben wird, besteht eine mögliche Reaktion im Auslösen einer Ausnahmeroutine, wodurch der normale Programmablauf unterbrochen und ein Fehler signalisiert wird.

Ein weiterer Vorteil der Änderungsmethode besteht darin, dass sie eventuelle Beobachter (im Sinne des gleichnamigen Entwurfsmusters) über die Änderung des Objektzustands informieren kann. Dies wird beispielsweise in Model View Controller-Architekturen benutzt, um eine Sicht (View, z. B. ein Bildschirmformular) zu aktualisieren, wenn der Inhalt des zugrundeliegenden Modells (Model, z. B. ein Datensatz in einer Datenbanktabelle) geändert wurde.

In einigen Programmiersprachen ist es üblich, die Namen aller Änderungsmethoden mit set beginnen zu lassen. So könnte z. B. eine Methode, die den Namen einer Person ändert, setName heißen. In anderen Programmiersprachen ist dieser Präfix unüblich und die Methode hieße einfach name, da bereits der parametrisierte Funktions/Prozeduraufruf als solcher eine setzende Methode impliziert.
 
Zuletzt bearbeitet:
Hallo,

das ist tatsächlich ein Problem.

Vom Stil her mag es besser sein mit Settern & Gettern zu arbeiten.

Es mag aber auch oft an den einfachen Beispielen liegen wo es keine weiteren logischen Einschränkungen der Werte gibt. In der Realität hat man oft entweder sowieso keinen Zugriff auf Attribute (also auch keine Getter & Setter) und wenn, dann gibt es ja oft Prüfungen innerhalb der Setter, die dann das ganze sowieso sinnhafter machen?

Mehr Sinn machen würde es wenn man (AFAIK in C# geht das?) eine Variable getrennt auf lesbar/ schreibbar setzen könnte.

Viele Grüßle 🙂
 
Zuletzt bearbeitet:
Allerdings kann so jederzeit später eine Prüfung implementiert oder intern Variablentypen geändert werden, ohne dass ein Benutzer der Klasse etwas ändern müsste, da er ja nur die Setter benutzt und nicht direkt auf Variablen zugreift.
 

Zurück
Oben