OOP Ein Fahrrad - zwei Besitzer: Zwei Referenzen auf ein Objekt

JavaMeetsBlueJ

Bekanntes Mitglied
Hallo Java-Forum
Letztens habe ich ein kleines Konto-Übungsprogramm geschrieben und da ist mir die Idee gekommen, dass ein Konto schließlich von zwei Ehepartnern besitzt werden kann(Falls dem nicht so ist bitte berichtigen). Übertragen wollte ich die Idee auf ein Programm, bei dem ein Fahrrad gefahren wird und die Kilometer gezählt werden. Nun kann ja ein Fahrrad von beliebig vielen Personen gefahren werden. Wie realisiert man das? Hilft da eine statische Methode oder ist das entgegen der Grundsätze der OOP?

MfG
 
Nein, eine statische Methode hilft dir da nicht.

Du musst beiden Personen einfach die Referenz aufs selbe Fahrrad übergeben:

Java:
Fahrrad mountainBike = new Fahrrad();

Person peter = new Person(mountainBike);
Person lucy = new Person(mountainBike);

peter.fahre();
lucy.fahre();
 
In dem Beispiel wird ja dem Konstruktor von den Personen im Konstruktor die Referenz aufs Objekt mountainbike übergeben. Muss ich an dem Konstruktor dann nichts ändern oder versteht das Java so?
MfG
 
Aber ein statischer ansatz wäre doch garnicht so verkehrt oder?
Wenn man in der Klasse Fahrrad eine statische variable für Laufzeit anlegt würde doch egal welche Instanz diese erhöhen können oder nicht?!

grüße
Javalui
 
Das würde aber auch bedeuten dass sich alle Personen immer genau ein Fahrrad teilen. Das lässt sich dann später auch ohne größeren Aufwand nichtmehr ändern.
Das schränkt dann ganz schön ein, ob man das will...
 
Dachte ich auch erst, nur kommt es dann zum Problem, wenn man mehrere Räder und mehrere Fahrer hat. Dann wird ja von jedem Fahrrad die Laufleistung erhöht auch wenn es nicht gefahren wird.

MfG
 
Evtl. müsst die Methode fahre() dann auch noch thread-sicher gemacht werden, wenn mehrere Personen gleichzeitig fahren können
 
Das braucht man nur wenns auch mehrere Threads gibt. Kann ich mir bei diesem Beispiel nicht vorstellen.
 
Wenn man es aus diesem Blickwinkel ansieht stimmt das. Dann ist es wohl doch besser auf das selbe Objekt zu referenzieren. Danke 😉
 
Alles Schritt für Schritt hehe, ich habe zwar das Grundprinzip der OOP verstanden aber mit Threads fang ich lieber erst später an.Erstmal kommen noch Interfaces. Trotzdem Danke für die Ergänzung.

MfG
 
Alles Schritt für Schritt hehe, ich habe zwar das Grundprinzip der OOP verstanden aber mit Threads fang ich lieber erst später an.Erstmal kommen noch Interfaces. Trotzdem Danke für die Ergänzung.

MfG

Also besser wärs eigentlich noch, jedem Fahrrad (also "Fahrrad-Objekt") genau einen Besitzer zuzuweisen, oder?

Java:
Person peter = new Person();
Person lucy = new Person();

Fahrrad mountainBike = new Fahrrad(lucy);

mountainBike.fahre(1000000);

mountainBike.setDriver(peter);
mountainBike.fahre(999999);

All right?? 😀 😀
 
Gepäckträger und so.

Java:
public boolean gepaeckTraegerIsFreeForGirlfriend(){
    return true; // aber immer doch
}
 
Also besser wärs eigentlich noch, jedem Fahrrad (also "Fahrrad-Objekt") genau einen Besitzer zuzuweisen, oder?

Java:
Person peter = new Person();
Person lucy = new Person();

Fahrrad mountainBike = new Fahrrad(lucy);

mountainBike.fahre(1000000);

mountainBike.setDriver(peter);
mountainBike.fahre(999999);

All right?? 😀 😀

Nein, so einen Mist würde man ganz sicher NICHT machen.
Zwar kann man bei "Fahrzeugen" schon den "Fahrer" setzen, hier geht es aber um den "Eigentümer" (@TO : Besitz und Eigentum sind zwei verschiedene Paar Schuhe).
Also anstatt "setDriver" eher "setBesitzer", und sowas würde man in der Realität auch nicht machen.
Da ist es schon sinnvoller zwei Personen ein Fahrrad zuzuteilen.
 
Gibt es eigentlich irgendwelche Richtlinien woran man entscheidet ob man der Person ein Fahrrad zuordnet oder dem Fahrrad eine Person?

Letzteres wäre mein intuitiver Lösungsansatz gewesen, ersteres funktioniert natürlich auch.

Was ist schöner und wie entscheidet man das, oder ist das egal?

Die Argumentation, dass nicht jede Person ein Fahrrad hat zieht ja leider nicht, ein Fahrradverleih hat ja normalerweise auch nicht immer jedes Fahrrad einem Mieter zugeordnet.
 
Es geht hier eigentlich eher weniger um das reale Problem "Person <-> Fahrrad" sondern um Grundlagen der OOP. Und JA : es gibt in OOP "conventions" wie man solche Fälle "am besten" löst. GooGLe wird dir helfen.
 
Grundgerüst steht, wer motzen will darf gerne 😉, bin ja noch Anfänger.

Klasse Fahhrad:
Java:
public class Fahrrad
{
    int laufleistung = 0;

    public void fahre(int strecke)
    {
      laufleistung += strecke;
System.out.println("Mein Fahrrad wurde gerade: " + strecke + "Kilometer gefahren. Die Gesamtlaufleistung beträgt " + laufleistung + "Kilometer.");
    } 
}
Klasse Radfahrer:
Java:
public class Radfahrer
{
    public void fahren(Fahrrad fahrrad, int strecke)
    {
      fahrrad.fahre(strecke);
    }
}

Klasse Test:
Java:
public class Test
{
  
    public static void main(String[] args)
    {
      Fahrrad mountainbike = new Fahrrad();
    
      Radfahrer alex = new Radfahrer();
      Radfahrer luisa = new Radfahrer();

      alex.fahren(mountainbike, 500);
      luisa.fahren(mountainbike, 300);
    }
}

Und ja...ich fahre gerne lange Strecken😉

MfG
 
Zuletzt bearbeitet:
Es geht hier eigentlich eher weniger um das reale Problem "Person <-> Fahrrad" sondern um Grundlagen der OOP. Und JA : es gibt in OOP "conventions" wie man solche Fälle "am besten" löst. GooGLe wird dir helfen.

Du bist ja voll Aggro drauf... Vor ein paar Minuten war hier noch voll die Stimmung, dann so ein Miesmacher...

Fakt ist doch, dass ein und dasselbe Fahrrad mehrere Personen fahren können. Und wie man es dann implementiert ist Jacke Wie Hose. Ohne Gründe, warum das eine richtig und das andere falsch sein soll, ist so eine Aussage einfach nur unqualifiziert. :lol:
 
Was müsste im Konstruktor stehen, wenn ich das so löse:

Java:
public class Radfahrer
{
  public Radfahrer(Fahrrad fahrrad)
{
 ????  irgendwas = fahrrad???  // irgendwie so?
}
.
.
.
.

}
MfG
 
Was müsste im Konstruktor stehen, wenn ich das so löse:

Ein Radfahrer hätte dann ein Fahrrad (Kennt-Beziehung). Also muss Radfahrer dein eine Objektvariable/Attribut haben, der das Fahrrad-Objekt zugewiesen wird.

Wenn der Radfahrer fährt, muss eine Methode von Fahrrad aufgerufen werden
 
Zuletzt bearbeitet von einem Moderator:
Ein Radfahrer hätte dann ein Fahrrad (Kennt-Beziehung). Also muss es dann in Radfahrer eine Objektvariable/Attribut geben, der das Fahrrad-Objekt zugewiesen wird.

Wenn der Radfahrer dann fährt, muss eine entsprechende Methode von Fahrrad aufgerufen werden

Also sowas wie
HTML:
 Radfahrer = mountainbike;
oder stehe ich gerade voll aufm Schlauch?(wahrscheinlich ja 😉)
MfG
 
Daraus schließe ich: JavaMeetsBlueJ, du weißt, was du machen musst, und jetzt probier endlich WIE du es machen musst, denn Java ist learning by doing😉 Ist jetzt nicht böse gemeint.
MfG
 
Sprichst du von dier jetzt in der zweiten Person?

Hier mein Ansatz;

Java:
public class Fahrrad {

    private int strecke = 0;
    private String fahrer = "";

    public void fahre(String fahrer, int strecke) {
        this.strecke += strecke;
        this.fahrer += fahrer + " (" + strecke + " km, insgesamt " + this.strecke + " km), ";
    }

    public String toString() {
        return fahrer;
    }

    public static void main(String[] args) {
        Fahrrad f1 = new Fahrrad();
        Fahrrad f2 = new Fahrrad();

        f1.fahre("Peter", 10);
        f2.fahre("Lucy", 20);
        f1.fahre("Alex", 5);
        f2.fahre("Luisa", 30);

        System.out.println(f1);
        System.out.println(f2);
    }
}
 
Oder alles in eine Zeile 😉 :
Code:
this.fahrer += fahrer + " (" + strecke + " km, insgesamt " + (this.strecke += strecke) + " km), ";

Aber kp was jetzt eigentlich gemeint ist. EikeB trifft fast immer zu weiß bescheid.😀
 
Die toString() Methode gibt dir eine Stringrepräsentation des Objekts zurück. Beim Fahrrad könnte das bspw. so aussehen:

Java:
public String toString() {
  return "Ich bin ein Fahrrad, dass bisher " + strecke + " km gefahren ist";
}
(Das Beispiel mit dem Fahrertext finde ich nicht so gelungen)
 
Hab ich auf die schnelle geschrieben. Kann natürlich auch etwas anderes als String sein. Weil die Beiträge von EikeB bisher immer richtig waren

So bis dann, MfG
 
So ich hab jetzt mal ein bischen weiter gemacht und dabei rausgekommen ist folgendes:

Klass Fahrrad:
Java:
package Fahrradverleih;

public class Fahrrad {
	
	int laufleistung;
	String seriennummer;
	double preis = 0.2; //Preis pro kilometer: 20 cent

	public Fahrrad(String seriennummer)
	{
		this.seriennummer = seriennummer;
	}
	
	
	public void fahre(int strecke)
	{
		laufleistung += strecke;
	}

	public int getLaufleistung()
	{
		return laufleistung;
	}
	
	public double getPreis(int strecke)
	{
		return strecke*preis;
	}
	
	public void showStatistik()
	{
		System.out.println("-------------------------------" + "\n" + "Sereiennummer: " + seriennummer + "\n" + "Gesamtlaufleistung: " + laufleistung + "\n" );
	}
}

Klasse Kunde:
Java:
package Fahrradverleih;

public class Kunde {
	String name;
	String nachname;
	String alter;
	String wohnort;
	
	
	public Kunde(String name, String nachname,String alter, String wohnort)
	{
		this.name = name;
		this.nachname = nachname;
		this.alter = alter;
		this.wohnort = wohnort;
		
		System.out.println("Kunde anlegen erfolgreich!" + "\n" + "-------------------------------------");
		
	}
	
	public void fahre(Fahrrad fahrrad,int strecke)
	{
		fahrrad.fahre(strecke);
		
	}
}

Klasse Fahrradverleih:
Java:
package Fahrradverleih;

public class Fahrradverleih {

	
	public static void main(String[] args) {
		
		Kunde egon = new Kunde("Egon","Meyer","45","Hannover");
		Kunde eva = new Kunde("Eva", "Peter", "24", "Leipzig");
		Fahrrad f1234 = new Fahrrad("f1234");
		egon.fahre(f1234, 40);
		System.out.println("Gesamtlaufleistung: " + f1234.getLaufleistung());
		eva.fahre(f1234,150);
		System.out.println("Gesamtlaufleistung: " + f1234.getLaufleistung());
		f1234.showStatistik();
		
	
		
	}

}

Meine Frage ist: Wie kann ich in der Methode showStatistik() der Klasse Fahrrad den letzten Benutzer hinzufügen? Das Problem ist ja, dass das Fahrrad seinen letzten Benutzer "kennen" muss. Wie erreicht man das ohne viel codeaufwand. Eine Lösung wäre ja manuell eine Kunde-Referenz an das Fahrrad zu liefern aber das ist iwi nicht so OOP.like hab ich das Gefühl... . Kann mir da jemand helfen?

MfG
 
Zuletzt bearbeitet:
Sogar rein realistisch gedacht, wäre das die sinnvollste Variante: Eine Person geht zu einem Fahrrad (das Fahrrad bekommt also kurzzeitig eine Instanz der Person zugeteilt) und fährt damit.

Java:
Person bikeOwner = new Person("Hans Egon", "Schmidt", 43); //alter ist übrigens im int schöner
Fahrrad f = new Fahrrad("Fahrradmarke", "SERIENNUMMER", ...); //was auch immer
bikeOwner.addBike(f);
Person driver = new Person("Harald Herrmann", "Meier", 21);
Fahrrad rented = bikeOwner.rentBike(0, driver); //da wäre dann 0 die fahrradnummer (kann ja wohl sein, dass er mehrere fahhräder besitzt? und halt der driver leiht sich das rad
// jetzt müsste gelten f.equals(rented)
rented.drive(200); //oder so ähnlich, beim ausleihen könnte ja im Fahrrad ne methode wie setDriver(Person p) aufgerufen werden...
rented.bringBackToOwner();

In dem Fall hat das Fahrrad die Variable
Code:
Person driver
, wenn
Code:
!driver.equals(owner)
kann das fahrrad halt nicht geliehen werden. Wenn dann
Code:
bringBackToOwner(Person p)
aufgerufen wird, muss halt
Code:
driver = owner;
gesetzt werden.
 
Zuletzt bearbeitet:
Gibt es eigentlich irgendwelche Richtlinien woran man entscheidet ob man der Person ein Fahrrad zuordnet oder dem Fahrrad eine Person?

Letzteres wäre mein intuitiver Lösungsansatz gewesen, ersteres funktioniert natürlich auch.

Was ist schöner und wie entscheidet man das, oder ist das egal?

Die Argumentation, dass nicht jede Person ein Fahrrad hat zieht ja leider nicht, ein Fahrradverleih hat ja normalerweise auch nicht immer jedes Fahrrad einem Mieter zugeordnet.

Genau an dieser Frage erkennst du dein Problematik (Auch von oberen Fragen), und ergibt sich daraus der Lösungsansatz.

Code:
Fahrräder
und
Code:
Personen
sind unabhängige Objekte.
Die werden irgendwie miteinander verknüpft.

Jedes kann ohe Partner leben, aber keines dieser Objekte fährt ohne ein Gegenstück als Partner.
Wenn dich das nur für Stundenverleih interessiert, dann wirst du selten einen Mieter haben, der mehrere Fahrräder braucht. Also ist es am einfachsten bei den Fahrräder einen einzigen Mieter einzutragen. Wenn du aber einen Sportverein verwaltest, dann werden eher die Besitzer im Mittelpunkt stehen, und dort 'ihre' Fahrräder eingetragen. Und wenn du ein Hotel verwaltest, dann ist evtl. beides gleichrangig, und beides nicht mit einem Eintrag erledigt, weil manche für den Morgensport ein Moutainbike miten, und nachmittags mit den Kindern den Fluss entlang radeln.

Da brauchst du dann nicht nur 1 Eintrag beim Fahrer oder 1 Eintrag bei Fahrrad, sondern wirs evtl Listen brauchen die in beiben Objekten gegenseitig verweisen.

Dasselbe auch zu deinem obigen Problem:
Prinzipiell interessieren dich die Laufleistung eines Fahrrades.
Gleichermaßen interessant ist evtl die sportliche Leistung jeder Person.
Deshalb scheiden statische Veriablen aus, da diese für alle Fahrräder gemeinsam aufsummieren würden.
Bestenfalls wäre das bei den Personen interessant, wieviel die Bevölkerung für die Reichsgesundheit getan hat. Aber auch das wird besser aus Einzelsummen addiert.

ABER wichtig ist deshalb auch bei der Methode fahren dass sie Person UND Fahrzeug kennen muss.
Code:
karl.fährt()
ist also nicht ausreichend
sondern muss heißen karl.fährt(kettlerGoCart);

Weitere Schlussfolgerung:
Deshalb halte ich auch einen Kunstruktor Person(Fahrrad) für logisch ungünstig.
(Ist natürlich machbar, aber) besser einen reinen konstruktor
Java:
Person(Name)
und eine Methode
Java:
Person.kauft/mietet/besorgtSichAmFreineMarkt(Fahrrad)
.
und danach
Java:
Person.fährt(Fahrrad)
.

Resume:
Das Daten-Design ist weniger (nur) eine Frage der OOP-Konventionen, sondern ganz massiv vom Problem/Pflichtenheft geprägt.
 
Vielen Dank für die Erleuchtung AquaBall.
Jetzt, nachdem ich deinen Text gelesen habe, erinnere ich mich auch wieder düster an Begriffe wie Komposition und Aggregation.
Ich vermute das sind die Stichworte, mit denen ich mich diesbzeüglich nocheinmal beschäftigen sollte.

Ich habe es noch nicht zu 100% gelesen, wunder mich aber ehrlich gesagt doch gerade etwas, dass diese eigentlich recht grundlegenden Schlagworte in einem bekannten und auch recht beliebten Buch (das mir sonst auch echt gut gefällt!) aus dem o'really Verlag gar nicht auftauchen, oder habe ich es nur überlesen?!

Danke auch für deine Mühe Radfahrer, google war mir gänzlich unbekannt.
 
Bis jetzt gibt es Klassen Fahrrad, Fahrradverleih, Kunde usw. Bis nicht genau festgelegt ist, was überhaupt die Anforderungsdefinition ist, macht ein Entwurf keinen Sinn... Dann kann man sich immer noch über Komposition oder Aggregation Gedanken machen imho...
 
Vergesst bitte nicht, dass ich nicht der TE bin. Ich habe mich nur "eingemischt", weil sich mir Fragen aufgedrängt haben 😉
(Kommt mir so vor, als wäre bei ein oder zwei Leuten der Eindruck entstanden)

Lasse euch jetzt auch wieder in Ruhe *g*
 
Ich find das garnicht schlecht, dass aus diesem erst kleinen Prloblem neue Lösungsansätze entstehen, was mich gut im Lernprozess unterstützt. Der Post von pausch ist nicht schlecht und so weit hätte ich garnicht gedacht.

MfG
 
Komposition? Aggregation? Das hat meiner Ansicht nach nichts mit dieser Aufgabenstellung zu tun. Die Begriffe die ihr sucht, müssten Aquire and (Auto)Release heissen. Wie dem auch sei. Hier mal mein Ansatz:
Java:
class KannNichtException extends Exception {
	private static final long serialVersionUID = 1L;
}

class ZuVielVolkException extends Exception {
	private static final long serialVersionUID = 1L;
}

interface Person {
	void fahre(Fahrzeug fahrzeug) throws KannNichtException;
}

interface Fahrzeug {
	void benutze(long time) throws ZuVielVolkException;
}

class Fahhrad implements Fahrzeug {
	private static final int MAX_PERSONS = 1;

	private int user = 0;

	@Override
	public synchronized void benutze(final long time) throws ZuVielVolkException {
		if(user == MAX_PERSONS) {
			throw new ZuVielVolkException();
		}
		user++;
		new Thread() {

			@Override
			public void run()
			{
				try {
					Thread.sleep(time);
				} catch(InterruptedException ie) {
					interrupt();
				}
				user--;
			}
		}.start();
	}
}

class Tandem implements Fahrzeug {
	private static final int MAX_PERSONS = 2;

	private int user = 0;

	@Override
	public synchronized void benutze(final long time) throws ZuVielVolkException {
		if(user == MAX_PERSONS) {
			throw new ZuVielVolkException();
		}
		user++;
		new Thread() {

			@Override
			public void run()
			{
				try {
					Thread.sleep(time);
				} catch(InterruptedException ie) {
					interrupt();
				}
				user--;
			}
		}.start();
	}
}

class Peter implements Person {
	@Override
	public void fahre(Fahrzeug fahrzeug) throws KannNichtException {
		try {
			fahrzeug.benutze(10000L);
		} catch(ZuVielVolkException zvve) {
			throw new KannNichtException();
		}
	}
}

class Lucy implements Person {
	@Override
	public void fahre(Fahrzeug fahrzeug) throws KannNichtException {
		try {
			fahrzeug.benutze(10000L);
		} catch(ZuVielVolkException zvve) {
			throw new KannNichtException();
		}
	}
}
 
Zuletzt bearbeitet von einem Moderator:

Zurück
Oben