Allgemeine Fragen zur Programmierung

JimK

Bekanntes Mitglied
Hallo,

ich versuche mich gerade auf eine Klausur für Programmieren vorzubereiten und ich hoffe das ihr mir weiterhelfen könnt.

1.1. Definieren Sie die abstrakte Oberklasse GeoObj. In der Klasse sind das Bezugssystem als Text und ein
eindeutiger Schlüssel als Zahl zu berücksichtigen.

Das habe ich so geschrieben:

Java:
public abstract class GeoObj
{
	String bezug;
	int schluessel; 
}

Das dürfte ja richtig sein. Bei zweitens habe ich aber meine Probleme.

1.2. Erweitern Sie die Klasse GeoObj um einen Konstruktor. Im Konstruktor soll automatisch ein neuer
eindeutiger Schlüssel erzeugt werden.

Da habe ich bis jetzt nur folgendes:

Java:
public abstract class GeoObj
{
	String bezug;
	int schluessel;

		public GeoObj(int schluessel)
		{
		   schluessel = schluessel;
		}
}

Wie kann ich im Konstruktor einen neuen eindeutigen Schlüssel erzeugen???

LG
JimK
 
Hallo,
mit ein wenig google hab ich das hier gefunden: Java Practices -> Generating unique IDs

Ansonsten kannst du als ID, auch einen timestamp nehmen. Da kann es aber vllt. vorkommen, dass dei Eindeutigkeit verloren geht, wenn man an der Systemzeit rumspielt (Korrigiert mich, wenn ich da falsch liege).

Eine weitere Möglichkeit wäre sicherlich irgendeine Art von Factory, welche fortlaufend Nummern beim Erstellen vergibt.
 
als eindeutige id würde ich eher eine static int klassenvariable nehmen und diese bei jeder instanziierung inkrementieren
 
Hm... das mit den ID´s hatte wir gar nicht in der Vorlesung. Gibt es vielleicht noch eine andere Möglichkeit? Vielleicht, dass man einfach nur eine Zähler einbaut? So zusagen, dass bei jedem Aufruf der Schlüssel um 1 weiter zählt?
 
Zuletzt bearbeitet:
z.b.
Java:
public abstract class GeoObj
{
	static int idCounter = 0;
    String bezug;
    int id;
   
        public GeoObj()
        {
        	this.id = idCounter++;
        }

}
 
Vielen Dank nrg. Also funktioniert es doch im Konstruktor einen Zähler einzubauen. Ich war mir da nämlich nicht sicher.
Leider habe ich noch ein paar Fragen für euch. ^^ Will sie nur selber nochmal schnell probieren. 😉

LG JimK
 
1.3. Definieren Sie eine Klasse GeoPoint, welche die Lage eines Punktes in der Ebene beschreibt. GeoPoint soll von GeoObj erben und Attribute zur Verwaltung der Koordinate des Punktes besitzen.
Berücksichtigen Sie auch einen Konstruktor, der als Parameter die Koordinate des Punktes bekommt.

Stimmt meine Idee?

Java:
public class GeoPoint extends GeoObj
{
	double x, y;
        int counter;
	
	public GeoObj(double x, double y)
	{
		super(id);
		counter = id;
                x = x;
                y = y;
	}
}
 
Du kannst das auch ohne Konstruktor machen. Wenn du Zeile 7 löschst, funktioniert es noch immer. Dann handelt es sich nämlich um einen Instance Initializer.

Zu GeoPoint: Wie sieht GeoObj nun aus? Wofür steht counter in GeoPoint?
Code:
x = x;
und
Code:
y = y;
weist du den Parametern ihren eigenen Wert zu. Du musst [c]this[/c] benutzen, um auf die Variablen in der Klasse zuzugreifen: [c]this.x = x;[/c]
 
Zuletzt bearbeitet:
Meinst du das super(id)? GeoObj ist 1.2. Die bauen aufeinander auf und der counter soll die erzeugte ID aus GeoObj sein
 
Zuletzt bearbeitet:
ich will nicht alles vorweg nehmen, deshalb gebe ich jetzt nur ein paar tipps 🙂.

counter kannst du dir sparen. den erbt GeoPoint von GeoObj. Der Konstruktor von GeoPoint muss natürlich auch GeoPoint heissen. Der explizite Aufruf des superkonstruktors ist so auch falsch (zumindest nach meiner Lösung), weil es diesen so parametrisiert nicht gibt. Kannst du dir aber auch komplett sparen, weil dieser implizit aufgerufen wird. Die Variablenzuweißung macht so auch keinen Sinn. Da gehört noch ein this davor, weil dein x und y von der Konstruktorparametrisierung das x und y von der Klasse überdeckt.
 
Dein aktueller Code zu GeoObj …
Du rufst um Konstruktor von GeoPoint den Konstruktor von GeoObj mit einem Parameter auf. Wofür steht dieser?
 
Oh ja sorry, beim Konstruktor habe ich mich vertippt. =)
Hm... ich versteh die Frage irgendwie so, dass ein Konstruktor angelegt werden soll mit der generierten ID und den Koordinaten oder was denkt ihr?

Java:
public abstract class GeoObj
{
    static int idCounter = 0;
    String bezug;
    int id;
   
        public GeoObj()
        {
            this.id = idCounter++;
        }
 
}
 
Zuletzt bearbeitet:
das brauchst du aber in GeoPoint nicht mehr machen, weil du das doch schon in GeoObj tust

kuck dir mal den Code so an (Bezugsystem wurde weggelassen, weil das auch nur als Veranschaulichung dienen soll):

Java:
public abstract class GeoObj  {
	
	static int idCounter = 0;
	int id;

	public GeoObj() {
		System.out.println("super!");
		this.id = idCounter++;
	}

}

class GeoPoint extends GeoObj {
	
	double x, y;

	public GeoPoint(double x, double y) {
		System.out.println("sub");
		this.x = x;
		this.y = y;
	}
}

class Test {

	public static void main(String[] args) {
		System.out.println(new GeoPoint(0.0, 0.0).id);
		System.out.println(new GeoPoint(0.0, 0.0).id);
		System.out.println(new GeoPoint(0.0, 0.0).id);
		System.out.println(new GeoPoint(0.0, 0.0).id);
		System.out.println(new GeoPoint(0.0, 0.0).id);
	}
}

Ausgabe:
Code:
super!
sub
0
super!
sub
1
super!
sub
2
super!
sub
3
super!
sub
4

damit siehst du denke sehr schön, dass der parameterlose superkonstruktor immer und implizit vor dem subkonstruktor ausgeführt wird. auch dein counter in GeoObj wird von GeoPoint geerbt. D.h. in der Klasse GeoPoint brauchst du dich darum nicht mehr zu kümmern
 
Zuletzt bearbeitet:
Danke nrg. Hab deine Tipps befolgt und bin damit auch auf deinen Quellcode gekommen. Mit der Vererbung und den this muss ich mir nochmal anschauen. Bin darin noch total unsicher.
Auf zu nächsten Aufgabe... 😀
 
this brauchst du eigentlich nur, wenn ein "näherer Namespace" sich mit den Instanzvariablen überschneidet. Ansonsten kann man es schreiben, muss es aber nicht.

Stell dir vor du hast eine Schule mit einem Schüler MaxMustermann in der Klasse 1b

Jetzt befindest du dich aber grad in dem Klassenzimmer von der Klasse 2c, wo es zufällig auch einen MaxMustermann gibt

Um jetzt den MaxMustermann aus der Klasse 1b anzusprechen, reicht es nicht aus, einfach nur nach seinem Namen zu rufen. Dann wird sich ziemlich sicher der falsche Schüler angesprochen füllen und deshalb musst du halt rufen "MaxMustermann aus der Klasse 1b ..." 🙂

Mir ist jetzt kein besseres Beispiel eingefallen 😀. aber vllt macht es das etwas klarer
 
also im Beispiel würde das
Code:
this
dann für die Schule gelten, weil der MaxMustermann der Klasse ja den von der Schule verdeckt 🙂.

Aber "in Java" gilt
Code:
this
für die Instanzvariablen der aktuellen Instanz der Klasse, falls du das meintest
 
Hm... da hab ich wohl etwas falsches aufgeschnappt als mir das mal einer erklärt hat. ^^
Vielen danke für eure Hilfe.
Hänge jetzt aber irgendwie bei 1.5. fest.... 🙁

1.5. Definieren Sie nun eine Klasse Verkehrszeichen, welche von GeoPoint erbt. Zusätzlich soll sie Informationen zum Verkehrszeichen vorhalten. Die Nummer der Bildtafel (als Text, da mitunter auch mit
Unternummer) ist hier ausreichend. Der Konstruktor von GeoPoint soll die Lage des Verkehrsschildes und die Nummer der Bildtafel festlegen.

Der fett markierte Satz verwirrt mich. 🙁 Aber Moment... Das Problem haben wir ja schon in 1.3. gelöst. Eigentlich muss ich doch nur noch die Methode Verkehrsschild anlegen und von GeoPoint erben lassen oder?
 
Zuletzt bearbeitet:
Müsste es nicht heißen: Der Konstruktor von Vekehrsschild ... ?

Ansonsten wieder wie bei 1.3. Diesmal erbst du entsprechend von GeoPoint und zusätzlich initialisierst du eine String-variable.
 
Hm... hab hier eine Beispielaufgabe aus eine anderen Klausur die fast so ähnlich ist. Die haben wir mit dem Prof besprochen. Die Aufgabe lautete so :1.5. Es soll eine Klasse Lichtmast programmiert werden, die von der Klasse MeinPunkt erbt und folgende Informationen zusätzlich verwaltet:
- Nummer des Mastes
- Typ
- Leuchtleistung
- Baujahr

und seine Lösung war so:
Java:
public class Lichtmast extends MeinPunkt
{
 String nr, typ;
 double leistung;
 int baujahr;

 public Lichtmast(double x, double y)
 {
   super(x,y);
   …
 }
}

Könnte ich das anwenden auf meine Aufgabe?
 
Hab es jetzt so gemacht:

Java:
public class Verkehrszeichen extends GeoPoint
{
	String verzeichennr;
	
	public Verkehrzeichen(double x, double y)
	{
		this.x = x;
		this.y = y;
	}
}
 
Das ist so leider sehr unschön.
So ist die Musterlösung:
Java:
 public Lichtmast(double x, double y)
 {
   super(x,y);
   …
 }

D.h. hier leitest du die Punkt-Angaben x und y einfach an den super-Konstruktor (d.h. an den Konstruktor der nächsten "höheren" Klasse weiter.

Das sollst du auch so machen und nur eine Verkehrsschild-Nummer, welche vom Typ String ist, in dem Konstruktor der Klasse Vekehrrschild selbst setzen. Deine Lösung dürfte auch funktionieren, ist aber unsauber programmiert. Mit der Verkehrschildnummer machst du jedoch rein gar nichts.

//
So am Rande finde ich die Aufgabenstellung schon unschön. Meiner Meinung wäre es besser, wenn ein Verkehrsschild an einem Punkt steht und nicht selbst sozusagen ein Punkt ist. Entsprechend würde die Klasse eine Variable GeoPoint besitzen und nicht abgeleitet werden von GeoPoint.
 
Zuletzt bearbeitet:
Ok, danke Blakh... 😉

Nun zu meiner vorletzten Frage.... 😀

1.7. Ist der folgende Ausdruck erlaubt? Wenn ja, erklären Sie, den Vorteil solcher Anweisungen. Wenn nein, erklären Sie, warum dies nicht erlaubt ist. Ihre_Parameter steht für die Parameter entsprechend des
Konstruktors aus Aufgabe 1.5. .

GeoVis g=new Verkehrszeichen (Ihre_Parameter);

GeoVis sieht so aus:
Java:
public interface GeoVis
{
public void paint(Graphics g);
}

Also ich würde jetzt pauschal nein sagen, da GeoVis ein Interface ist.
 
Genau. Und was hat das jetzt für Folgen? Wieso funktioniert das nicht? Wäre ich Lehrer, dann würdest du von mir vllt. 2 von 4 Punkten bekommen 😉.

p.S. ich vermute jetzt mal, dass da noch ein 1.6 war und deine Antwort wegen 1.6 falsch ist. Was war Aufgabe 1.6?
 
Zuletzt bearbeitet:
Ha ha... mit 2 Punkte hätte ich volle Punktzahl.... :lol: Find ich irgendwie witzig.

Hab das hier gefunden:"Implementiert eine Klasse ein Interface, so muss sie alle Methoden des Interface überschreiben, da diese implizit als abstrakt deklariert werden."
 
1.6. Gegeben ist die folgende Schnittstelle GeoVis, die die Visualisierung eines Objektes ermöglichen soll:
Java:
public interface GeoVis
{
public void paint(Graphics g);
}
Wie muss die Klasse GeoPoint erweitert werden, damit sie diese Schnittstelle erfüllt?

Meine Lösung:

Java:
public class GeoPoint extends GeoObj implements GeoVis
{
	double x, y;
	
	public GeoPoint(double x, double y)
	{
		super(x,y);
	}
	
	public void paint()
	{
		...
	}
}
 
AHA! Also ist die Antwort auf 1.7, ob das so geht: Ja! Und jetzt überleg mal was der Vorteil sein kann.

Und beachte den post unter mir 🙂
 
Zuletzt bearbeitet:
Da bekämst du jetzt aber einen Compile-Fehler, dass die Klasse GeoPoint nicht die Methode paint(Graphics) von GeoVis implementiert - du hast da nur eine Methode paint() ohne Parameter.
 
Hm... bei dieser Frage stehe ich echt auf dem Schlauch. Wenn ich das richtig sehen, dann werden die Parameter an g übergeben und g ist ein Graphics. Hm... bedeutet es, dass es das implements überflüssig macht?
 
Ja.

(Gut, dass es noch kein Zeichenminimum in Beiträgen gibt xD)

Edit: Du kannst auch noch ein @Override vor die Methodendeklaration in der implementierenden Klasse schreiben, damit kündigst du an, dass diese Methode eine andere überschreibt. Falls das nicht der Fall ist (z.B. weil wie in deinem Fall der Parameter fehlt), wirft der Compiler einen Fehler und man erkennt eher, was das Problem ist.
 
Zuletzt bearbeitet:
:lol:

Find es aber echt super von euch, dass ihr mir helft auch wenn ich mir voll doof vorkommen. Das muss auch mal gesagt werden so lange ich noch soviel schreiben.
 

Neue Themen


Zurück
Oben