Gute Übungen für das erste Studiensemester, das Zeug kommt 100% dran

Für paar chillige Wochen im Studium, lern folgendes denn es verrät einiges über Objektorientierung:
Static hat verschiedene Bedeutungen, je nachdem ob es für Klassen, Methoden oder Variablen benutzt wird.
Dein Fehler oben war static bei einer Methode. Mit static kann man Methoden direkt aufrufen, ohne ein Objekt einer Klasse. Deshalb ist die main immer static, da sie einfach direkt aufgerufen werden muss ohne irgendwelche vorangestellen Objekte. Man kann sagen: Static bei Methoden hebelt die Objektorientierung aus ! Die Methoden werden also zu Funktionen.
Bei deiner 2ten Aufgabe ist eine Sinnlosigkeit drin

Du hast getter/setter für Variablen gemacht die nicht private sind. D.h. du kannst in der main "new Seite15...." machen und über das Objekt auf objekt.alter zugreifen. Der Sinn von gettern und settern ist aber genau um dies zu verhindern.
Außerhalb der Klasse soll niemand diese Variablen direkt ansteuern können. Dazu macht man "private int alter". Die Getter/Setter Methoden selbst sind allerdings public (wenn keine Sichtbarkeit angegeben ist public standard). Danach kannst du in der main nur noch objekt.getAlter() machen aber nicht mehr objekt.alter. Stell dir Bankkonten vor, wo jemand etwas draufzahlen soll, aber nicht wissen muss wie viel drauf ist.
Normalerweise macht man die Felder (=Objektvariablen) fast immer private und baut Getter/Setter. Immer nur das Minimum nach außen sichtbar machen um Probleme und Sicherheit nicht zu gefährden.
-------------
Das equals ist auch noch mehrfach zu verbessern, da es so nicht dem Zweck dient und überschrieben hast so auch nix da die Parameter anders sind, du hast nur Methoden "Überladen" -> gleiche Methode, andere Parameter.
1.
Dein Parameter bei der Equals ist "Seite15 obj", soll aber sein "Object obj" ! Du musst generell vergleichen können, ohne zu wissen was das "obj" ist und woher es kommt. Object ist in Java praktisch alles, selbst ein String, Integer etc.
2.
Du hast kein @override benutzt, dies macht man immer wenn man von Oberklassen Methoden überschreibt.
Alles in Java erbt von der Oberklasse "Object" (automatisch!). Darin sind die toString() und equals() enthalten.
Und daher sind sie überall präsent, in jeder Klasse die du schreibst. Das merkst du daran, dass wenn du eine leere Klasse machst, du dennoch ein klasse.toString() etc. hast ! Überschreibst du diese Methoden nicht in deiner Klasse, werden bei Bedarf eben die aus der "Object" Klasse benutzt ! Die erbende Klasse kann also alles was die Oberklasse kann - und man fügt der erbenden nur noch mehr Zeug ein, bzw. überschreibt den Kram aus der Oberklasse wenn man eine andere Funktionalität will.
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
3.
Allerdings wissen die standard toSTring und Equals nicht wie sie mit deiner Klasse umgehen sollen, d.h. sie kennen die Struktur nicht. Deswegen muss man diese überschreiben. Gibst du nun per system.out ein Klassenobjekt aus, wird die toString() automatisch aufgerufen und du siehst nur Müll. Wenn du selbst eine toString() geschrieben hast, wird diese statt dem Standard Ding benutzt. Standard toString und Equals funktionieren nur bei einfachen Objekten, wie String x = "aaa".
4.
Da nun die Equals den Parameter Object hat, musst du folgendes machen:
- du prüfst mit "instanceof" erst mal ob der Parameter "obj" von deiner Klasse abstammt, also der in der du grade schreibst. Dazu machst "if (obj instanceof Seite15)". Damit hast du sichergestellt dass du korrekt vergleichen kannst, d.h. du hast auf jedem Fall 2 gleichartige Objekte - nun prüfst ob der Inhalt auch gleich ist ! Nun darfst du das "obj" casten, also "Seite test = (Seite15) obj" ohne das Fehler auftreten, instanceof ist nur true wenn es sich um zwei Seite15 Objekte handelt, oder um Klassen die davon erben. Das casten brauchst du da der Paramteter vom Typ "Object" ist, Java weiß zu dem Zeitpunkt nicht um welche Klasse es sich handelt - das musst du erst mal sagen und eben mit instanceof sicherstellen das alles rechtens ist. Danach darfst du deine Variablen normal vergleichen wie du es oben tust.
5.
Die toString() ist ok. Aber ! Wenn Dinge viele "+" Zeichen enthalten, benutze einen StringBuffer(). Das hat den Grund das "+" sehr viel aufwand betreibt. Für jedes + muss Java einen neuen (größeren) Speicherblock reservieren und die vorherigen Strings umkopieren. Das zieht extrem die Leistung eines Programmes runter. Große Texte verarbeiten wäre ohne Buffer zu nutzen ein PC-Killer, selbst die neuesten gehen in die Knie ! Falls du mal C lernst wirst du genauer verstehen was ich meine, bis dahin: Stringbuffer wenn es mal mehr Zeug wird
6.
Das return buffer.toString() ruft das toString() aus dem Objekt "buffer" auf, also den Standard Kram der darin steckt. Es ruft nicht deine toString() auf, denn deine gilt nur für das Objekt deiner Klasse (new Seite15....).
Hoffe das war halbwegs verständlich.
Code:
public class Seite15 {
private int alter;
@Override
public boolean equals(Object obj) {
if (obj instanceof Seite15) {
Seite15 test = (Seite15) obj;
if (this.alter == test.getAlter()) {
System.out.println("Alter gleich, Objekte gleich! -> true");
return true;
} else {
System.out.println("Alter verschieden! Objekte nicht gleich! -> false");
}
}
return false;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer("Hallo");
buffer.append(" Welt!");
return buffer.toString();
}
public int getAlter() {
return this.alter;
}
public static void main(String[] args) {
Seite15 aa = new Seite15();
// Ruft automatisch toString() aus der Klasse Seite15 auf.
// Wenn kein toString() überschrieben wurde Ausgabe wie "package.Seite15@35345d"
System.out.println(aa); // Ausgabe: Hallo Welt!
}
}