JAVA - Was ist die Lösung?
Hallo Leute.
Ich versuche mir im Selbststudium Java programmieren beizubringen und habe ein Problem mit einer Aufgabe. Seit Tagen versuche ich dahinterzukommen und ich will einfach nicht mehr. Wenn ich die Lösung sehen würde, dann könnte ich mir vielleicht selbst einen Reim darauf machen was ich falsch mache. Was muss in der Klasse Terminal stehen? Wie kann ich alle Attribute auf einmal ausgeben? Brauche ich dafür vlt. ein Array oder so?
public void hackRobot(TestRobot){
System.out.println(TestRobot.id);
/// Das hab ich versucht um nur mal ein Attribut auszugeben, selbst das funktioniert nicht - Bitte helft mir.
}
Folgende Situation:
Die Klasse TestRobot enthält 4 Attribute, die durch unterschiedliche Sichtbarkeiten geschützt sind.
Implementiere in der Klasse Terminal eine public Methode hackRobot(). Dies soll einen TestRobot als Parameter annehmen, und alle Attribute der Klasse TestRobot ausgeben, auf die man von der Klasse Terminal aus Zugriff hat.
1 Antwort
Was muss in der Klasse Terminal stehen?
Zunächst einmal die geforderte Methode mit einem Parameter in der Parameterliste.
Ein Beispiel für eine Methode mit Parametern:
public void printSum(int numberOne, int numberTwo) {
int result = numberOne + numberTwo;
System.out.println(result);
}
Wie kann ich alle Attribute auf einmal ausgeben?
Das sollst du gar nicht. Du sollst nur die Felder ausgeben, auf die von außen Zugriff besteht. Auf sichtbare Felder kann separat zugegriffen werden.
Beispiel:
class Car {
public String color = "red";
}
class Main {
public static void main(String[] args) {
Car car = new Car();
System.out.println(car.color);
}
}
Belies dich also noch einmal zu Zugriffsmodifikatoren. Sie werden beispielsweise hier erklärt.
Ein Parameter für eine Funktionsdefinition besteht immer aus Datentyp und Parametername. Das siehst du auch bei meinen Beispielen (printSum, main). Bei dir fehlt die Typangabe.
Auch bei loesung lässt du bei der Initialisierung die Typangabe weg.
Ich würde des Weiteren empfehlen, Parameternamen genauso wie alle anderen Variablen stets mit einem Kleinbuchstaben zu beginnen (testRobot). Das hilft beim Code lesen ungemein, um schnell zwischen Klassennamen und Variablen unterscheiden zu können.
Sorry aber ich kapier es immer noch nicht.
Kannst du mir nicht einfach mal den Code, welchen ich brauche hier anführen?
Dann werde ich vermutlich dahintersteigen wenn ich das Schritt für Schritt durchprobiere.
Ich bekomm nur Fehlermeldungen, auch wenn ich den Typ angebe.
Ich streng mich wirklich an und würds gern kapieren... (btw Vielen Dank, dass du dir hier für mich Zeit nimmst)
class Terminal {
public void hackRobot(String TestRobot){
System.out.println(TestRobot.id);
}
}
Story.java:6: error: incompatible types: TestRobot cannot be converted to String terminal.hackRobot(tr); ^ ./Terminal.java:4: error: cannot find symbol System.out.println(TestRobot.id); ^ symbol: variable id location: variable TestRobot of type String Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 2 errors make: *** [Makefile:2: run] Error 1 Die letzte Code-Ausführung wurde mit einem Fehler beendet (Statuscode 2).
Du gibst nun zwar einen Typ an, aber einen falschen. Du möchtest doch ein TestRobot-Objekt an die Methode übergeben, keine Zeichenkette (String). Also muss der Datentyp auch TestRobot entsprechen.
Grundsätzlich noch einmal zu Parametern und Argumenten: Beide müssen denselben Datentyp haben. Wenn eine Methode einen Parameter des Typs XY definiert, muss bei Aufruf auch ein Objekt des Typs XY übergeben werden. Und andersherum: Wenn einer Methode ein Argument des Typs XY übergeben wird, muss es auch eine Methode geben, die einen Parameter des Typs XY definiert.
Das Beispiel zeigt Anwendungsfälle:
class Car {
private String brand;
public Car(String brand) {
this.brand = brand;
}
public String getBrand() {
return this.brand;
}
}
class Horse {
private String name;
public Horse(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
class Buyer {
void buy(Car someCar) {
System.out.println("Bought a " + someCar.getBrand());
}
public void buy(Horse someHorse) {
System.out.println("Bought " + someHorse.getName());
}
}
class Dog {
}
public class Main {
public static void main(String[] args) {
Buyer thomas = new Buyer();
Car mercedes = new Car("Mercedes");
Horse jollyJumper = new Horse("Jolly Jumper");
thomas.buy(mercedes);
thomas.buy(jollyJumper);
Dog odie = new Dog();
thomas.buy(odie); // error!
}
}
Thomas kann sich ein Auto und ein Pferd kaufen, denn es gibt für beide Fälle jeweils eine Methode mit entsprechendem Parameter. Einen Hund kann er sich nicht kaufen, dafür müsste es eine buy-Methode geben, die den Typ Dog als Parameter definiert.
Der gezeigte Fehlerfall spiegelt genau den Fehler wieder, den dir dein Compiler als Erstes zurückgibt. Der Compiler versucht noch, das übergebene Objekt zu konvertieren (bei dir: TestRobot zu String), scheitert aber logischerweise.
Da in der ersten buy-Methode der Parameter someCar vom Typ Car ist, welcher (in seiner Klassendefinition) eine öffentliche Methode getBrand definiert, kann über den Parameter die getBrand-Methode aufgerufen werden. Auf Methoden, die der Datentyp nicht definiert (oder die er nicht von anderen Basistypen erbt), besteht über den Parameter kein Zugriff. So würde dieser Aufruf:
someCar.getName();
scheitern. Das Gleiche gilt für Felder. Konkret in deinem Fall scheitert der Aufruf von
TestRobot.id
da du in deinem Code angegeben hast, der Parameter TestRobot sei vom Typ String. Ein String kennt aber kein id-Feld. Dieses Problem wird in der zweiten Fehlermeldung formuliert. Der Compiler schaut in die Typdefinition von String und sucht nach dem Symbol id, was er letztendlich nicht finden kann.
Ich habs nun endlich geschnallt...Vielen Dank, dein letzter Kommentar hat mich nun auf die richtige Spur gebracht!
Muss meine grauen Zellen immer wieder mal fordern um Lösungen zu finden.
Hier meine Lösung: (Typendefinition jetzt mal vernachlässigen... ;-)
class Terminal extends TestRobot{
public void hackRobot(TestRobot test){
System.out.println(numberOfProcessorCores);
System.out.println(test.hasFirewall);
System.out.println(test.id);
}
}
Deine Lösung ist dennoch nicht richtig. In der Aufgabe steht nirgendwo, dass Terminal von TestRobot erben sollte. Es wäre auch unlogisch. Ein Terminal ist kein Roboter.
Da bei meinem Lernportal die Lösung automatisiert überprüft wird und diese für korrekt erklärt wurde, muss diese auch richtig sein. Wenn ich ohne Vererbung prüfe, dann kommt die Rückmeldung, dass das Beispiel falsch ist. Die Aufgabenstellung lautet ja "alle Attribute ausgeben, auf welche man von der Klasse Terminal aus Zugriff hat" - Wenn ich nun in Terminal eine Vererbung reinschreibe, dann hab ich ja Zugriff auf Attribute des Typs "protected".
Im vorigen Kapitel war der Lerninhalt Vererbung. Die Beispiele sind immer mit einer interaktiven Geschichte verbunden und im Lauf dieser Geschichte hat der Bösewicht unseren Roboter gehackt, da der Stoff hier noch nicht den Schutz der Attribute miteinbezogen hatte (public, protected etc. - Es geht darum, spielerisch diese Funktionalitäten zu lernen und bereits gelerntes anzuwenden - z.b. Vererbung). Ich bin eben ein Anfänger und versuch mich so gut es geht dahinterzuklemmen. Ich bedanke mich jedenfalls für deine Mühen, ich glaube ohne deine Beispiele und Anmerkungen hätte ich wahrscheinlich demnächst das Handtuch geworfen.
Bei dir ist das Terminal zum Roboter geworden, dabei ist es doch eher nur ein Teil eines Computers oder Roboters. Es ist also eine unlogische Beziehung (so wie ein Reifen kein Auto ist oder ein Bein kein Tisch), die zudem die konkrete Aufgabenstellung umgeht.
Der explizite Zusatz: (...) auf welche man von der Klasse Terminal aus Zugriff hat deutet daraufhin, dass das Verständnis von Zugriffsmodifikatoren geschult werden soll. Das du aktiv dafür sorgen sollst, auf jedes Attribut Zugriff zu haben, steht dort wiederum nicht.
Sollte das Ziel bei dieser Aufgabe tatsächlich das Finden so einer Lösung sein, wäre der Kurs keineswegs zu empfehlen, da hierbei eine völlig falsche Vorstellung entsteht, wozu Vererbung dient (zwischen korrekter Programmlogik und korrekter Programmsyntax besteht ein Unterschied). Ich denke eher, dass die technische Überprüfung nicht zu genau ist.
Danke erstmal für deine Unterstützung dabei. Ich habs jetzt eine Weile versucht, und die o.g. Beispiele sind mir eigentlich soweit klar dachte ich.
Heute hab ich leider keine Zeit mehr, jedoch werde ich mich in den kommenden Tagen nochmal dazusetzen und es weiter versuchen. Ich gebe dazu gerne noch Rückmeldung. Da ich aber berufsbedingt wenig Zeit habe, brauche ich immer ein paar Tage um zu reagieren.
Ich glaube es hapert bei der Anwendung des Parameters. (tr)
Ein Zwischenstand wie weit ich heute gekommen bin (falls es noch was hilfreiches gibt, freue ich mich über jeden Kommentar):