abstracte klassen methoden

Nico1999

Aktives Mitglied
hallo ich habe hier eine abstracte Klasse Figur und eine klasse pferd die diese implementiert
Java:
public class Pferd extends Figur{
    private int graphik=3;
@Override
public boolean gehe(Eingabe a, Figur[][] b) {
        if(((a.getJetztx()-a.getDannx()==-2||a.getJetztx()-a.getDannx()==2)&&(a.getJetzty()-a.getDanny()==1||a.getJetzty()-a.getDanny()==-1)||(a.getJetztx()-a.getDannx()==-1||a.getJetztx()-a.getDannx()==1)&&(a.getJetzty()-a.getDanny()==2||a.getJetzty()-a.getDanny()==-2))) {
            if(b[a.getDannx()][a.getDanny()]==null&&a.getJetztx()==this.getKoordinaten().getX()&&a.getJetzty()==this.getKoordinaten().getY()) {
                this.setKoordinaten(a.getDannx(),a.getDanny());
                return true;  
            }else {
                return false;
            }
        }return false;
       
       
    }}
public abstract class Figur{
    private Koordinaten koordinaten;
    private int graphik;
    public abstract boolean gehe();

 
}public class Koordinanten {
    private int x;
    private int y;
}public class eingabe
    private int jetztx;
    private int jetzty;
    private int dannx;
    private int danny;
    //methoden zur nutzer abfrage der jeweiligen attribute


ich hatte gedacht wenn ich eine abstracte methode habe muss ich sie in alle Klassen einfügen die ich von der abstracten klasse extende, aber ich habe ja jetzt die abstracte methode gehe() von Figur in Pferd implementiert also warum zeigt es mir eine Fehler an
"the methode gehe(Eingabe,Figur[][])of type Pferd must override or implement a supertype methode"
ich meine ich habe doch die methode schon da?
 
Dann zeige die Methode in der Klasse Figut auch einmal. Die Fehlermeldung besagt, dass die Methode gehe mit diesen Parametern nicht in der Klasse Figur vorhanden ist.
 
Java:
public abstract boolean gehe();
du willst diese methode überschreiben

aber zu einer signatur gehören parameter und rückgabetyp, nur wenn diese exakt gleich sind bei der überschreibung kannst du es überschreiben

deine überschreibung hat aber diese signatur
public boolean gehe(Eingabe a, Figur[][] b)
( das abstract fällt natürlich weg bei der Überschreibung )
 
Außerdem hast du noch @Override dh diese methode sollte zwangsmäßig eine Methode der über klasse überschreiben, zumindest löst es die IDE so auf , was java damit macht ka...

da es in der ober klasse keine solche methode gibt, wirfts einen fehler weil du das signaturen problem hast
 
Java:
public abstract boolean gehe();
du willst diese methode überschreiben

aber zu einer signatur gehören parameter und rückgabetyp, nur wenn diese exakt gleich sind bei der überschreibung kannst du es überschreiben

deine überschreibung hat aber diese signatur

( das abstract fällt natürlich weg bei der Überschreibung )
ah ich dachte bei einer abstracten methode kann man keine parameter übergeben danke für die Info
Danke
 
eine abstrakte klasse darf aber auch schon implementationen drin haben ansonsten hast ansich ein interface
Hier bitte immer genau bleiben. Eine Abstrakte Klasse ist und bleibt eine Klasse. Selbst wenn da keine Methode implementiert wurde.
Ebenso bleibt ein Interface halt ein Interface - auch wenn es default Methoden enthält.

Das sind und bleiben aus Java Sicht zwei unterschiedliche Dinge.

Man kann sich maximal über den Sinn / Unsinn unterhalten, aber das würde dann deutlich über so ein knappen Satz hinaus gehen müssen.

Und die Klasse hat ja auf jeden Fall bereits einen internen Status durch zwei Instanzvariablen:
private Koordinaten koordinaten;
private int graphik;

Da diese bei Child Klassen nicht sichtbar sind, ist also davon auszugehen, dass es hier weitere Implementationsdetails gibt, die nur eben weggekürzt wurden, da diese mit dem eigentlichen Problem nichts zu tun haben.
 
Da diese bei Child Klassen nicht sichtbar sind, ist also davon auszugehen, dass es hier weitere Implementationsdetails gibt, die nur eben weggekürzt wurden, da diese mit dem eigentlichen Problem nichts zu tun haben.
hab ich übersehen dass das private klassen felder sind, hatte aus irgednwelchen gürnden gedacht dass das methoden sind.. bruh

und die sind doch sichtbar
Java:
public class Koordinanten {
    private int x;
    private int y;
}
 
Also da dann einfach die Frage: Wer oder was sieht private Elemente?

Man hat also z.B. ausschließlich:
Java:
public abstract class Figur{
    private Koordinaten koordinaten;
    private int graphik;
    public abstract boolean gehe();
}

Welcher Code kann wie auf koordinaten und graphik zuzugreifen?
 
getter setter und so sind natürlich vorhanden
allerdings habe ich probleme mit dem setter von Koordinaten
Java:
public void setKoordinaten(int a, int b) {
        this.koordinaten.setX(a);
        this.koordinaten.setY(b);
    }
so sieht er aus und er wirft eine nullpointer exception allerdings habe ich keine ahnung weshalb und wie ichs beheben könnte
 
Frage wo ist denn die Methode setX( ) und setY( ) ?

x und y sind doch Instanzvariablen da kannst du doch direkt darauf zugreifen.
 
Java:
public void setX(int x) {
        this.x = x;
public void setY(int y) {
    this.y = y;
}
diese zwei methoden befinden sich in der klasse Koordinaten
 
Java:
public void setKoordinaten(int a, int b) {
        x = a;
        y = b;
    }
sollte doch reichen

wo in welcher Klasse bist du ?
 
"wo in welcher Klasse bist du"
den setter der art wie ich ihn dahingeschrieben habe ist in der klasse Pferd
und den setter für x und y der ist in der klasse Koordinaten
Pferd ist ja eine Figur und hat daher Koordinaten als attribut
 
Java:
public class Koordinanten {
    private int x;
    private int y;
    
    public void setKoordinaten(int a, int b) {
        x = a;
        y = b;
    }
    .....
 
Java:
public class Pfred {
...


public void setKoordinaten(Koordinaten koor, int a, int b) {
        koor.setX(a);
        koor.setY(b);
    }
 
getter setter und so sind natürlich vorhanden
allerdings habe ich probleme mit dem setter von Koordinaten
Java:
public void setKoordinaten(int a, int b) {
        this.koordinaten.setX(a);
        this.koordinaten.setY(b);
    }
so sieht er aus und er wirft eine nullpointer exception allerdings habe ich keine ahnung weshalb und wie ichs beheben könnte
Dann ist vermutlich koordinaten null.

Generell würde ich dazu raten, dass Du Kooridnaten als unveränderliche Klasse machst. Und dann wäre der Setter bei Dir immer nur ein:
Java:
public void setKoordinaten(Koordinaten koordinaten) {
        this.koordinaten = koordinaten;
    }

Und die Klasse Koordinaten hat kein setX / setY sondern nur Getter. Und dann wird da halt beim Ändern der Koodinate eine neue Koordinate erzeugt und gesetzt.

Das wäre so eine Möglichkeit, die mir hier durch den Kopf gehen würde, denn eine Koordinate ist eine Koordinate und die verändert sich ja nicht. Das Feld E1 ist und bleibt das Feld E1. Das Feld selbst wird nicht plötzlich zu D1. Eine Figur wechselt von E1 zu D1 also von einer Koordinate zu einer anderen Koordinate....
 
Java:
public class Pfred {
...
public void setKoordinaten(Koordinaten koor, int a, int b) {
        koor.setX(a);
        koor.setY(b);
    }
ich habe den code mal kopiert und eingesetzt und es wirft immer noch das
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Koordinaten.setX(int)" because "koor" is null
ich versuche halt das ich in den Konstrukor von Pferd Koordinaten in x und y aufspalten kann und nicht für jedes Objekt Pferd oder andere Figuren
eine Klasse Koordinaten erstellen muss, aber wenn das nicht funktiert muss ich wohl jedes mal eine klasse erstellen
 
ich habe den code mal kopiert und eingesetzt und es wirft immer noch das
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Koordinaten.setX(int)" because "koor" is null
ich versuche halt das ich in den Konstrukor von Pferd Koordinaten in x und y aufspalten kann und nicht für jedes Objekt Pferd oder andere Figuren
eine Klasse Koordinaten erstellen muss, aber wenn das nicht funktiert muss ich wohl jedes mal eine klasse erstellen
Naja, die Fehlermeldung ist doch eindeutig.
Du hast ein null-Objekt an die Methode übergeben, deshalb können dessen Koordinaten auch nicht gesetzt werden. (null ist halt null und bleibt null). Du musst sicherstellen, dass das Objekt, das an die Methode übergeben ist, nicht null ist.
Zeig mal den Codeblock, wo die Methode aufgerufen wurde.
 
Java:
Figur(int x, int y, boolean existiere){
        this.setKoordinaten(this.koordinaten,x, y);
        this.existiere=existiere;
    }
wenn das jetzt so nicht funktiert kann ich irgentwie einen konstruktor machen bei dem ich anstatt eine Klasse Koordinaten einfach nur zwei int übergeben die ich dann zu den Koordinaten der Figur machen oder ist das nicht möglich
 
Kann es sein, dass Du gerade den Überblick verloren hast und es Sinn machen könnte, dass Du evtl. erst einmal etwas anderes machst?

Also erst einmal ist dieser Code so ohne wirklichen Sinn:
Java:
public void setKoordinaten(Koordinaten koor, int a, int b) {
        koor.setX(a);  // koor ist der Parameter!
        koor.setY(b);
    }

Du bekommst eine Koordinaten Instanz übergeben und setzt auf dieser X und Y aber sonst machst Du nichts? Also koordinaten in der Instanz selbst bleibt unverändert.


setKoordinaten soll koordinaten in der Instanz setzen. Also wäre das dann - wie schon geschrieben - so eine Methode:
Java:
public void setKoordinaten(Koordinaten koordinaten) {
        this.koordinaten = koordinaten;
    }

Das wäre dann etwas, das Du z.B. so aufrufen kannst:
Java:
setKoordinaten(new Koordinaten(x,y));

Wenn Du ein setKoordinaten mit x und y Parameter haben willst, dann kannst Du natürlich auch so eine Methode bauen:
Java:
public void setKoordinaten(int x, int y) {
        this.koordinaten = new Koordinaten(x,y);
    }

Das ist aber eher unüblich, denn damit hat Deine Klasse eine stärkere Abhängigkeit zu der Implementation von Koordinaten. Was wäre, wenn Koordinaten auch noch eine z Komponente bekommt? Wenn Du da einfach mit Koordinaten arbeitest, dann ist dir das relativ egal (an dieser Stelle).

Wird das so etwas deutlich?
 
Wenn du in Pferd die Koordinaten Instanz hast kannst du auch gleich selber die dort die setter benutzen.

Hast du die Instanz überhaupt?
 
[CODE lang="java" title="Aufruf"]this.setKoordinaten(this.koordinaten,x, y);[/CODE]
1. hat this.koordinaten noch keinen Wert, also kannst du's auch nicht verwenden
2. brauchst du's gar nicht verwenden.
2.1 Bei der Deklaration solltest du der Variable sofort einen Wert zuweisen, dieser wird schon zugewiesen, bevor der Konstruktor aufgerufen wird
Java:
private final Koordinaten koordinaten = new Koordinaten(); //eventuell mit 0,0 initialisieren, falls notwendig.
Anm: Du kannst den Wert natürlich auch im Konstruktor zuweisen, das macht keinen Unterschied. Wichtig is, dass das passiert, bevor die Variable anderweitig verwendet wird.
2.2 Beim Aufruf sollte this.koordinaten kein Parameter sein, die Methode akzeptiert nur x und y und weist diese dann an this.koordinaten zu.
 
Wenn Du ein setKoordinaten mit x und y Parameter haben willst, dann kannst Du natürlich auch so eine Methode bauen:
Java:
public void setKoordinaten(int x, int y) {
        this.koordinaten = new Koordinaten(x,y);
    }

Das ist aber eher unüblich, denn damit hat Deine Klasse eine stärkere Abhängigkeit zu der Implementation von Koordinaten. Was wäre, wenn Koordinaten auch noch eine z Komponente bekommt? Wenn Du da einfach mit Koordinaten arbeitest, dann ist dir das relativ egal (an dieser Stelle).

Wird das so etwas deutlich?
danke das hat geholfen ich dachte es reicht wenn ich einer Klasse einfach nur ein Attribut gebe ich wusste nicht das man dann falls dieses Attribut eine Klasse ist es erst neu instanzieren muss.
meinst du mit normalerweise(also) das man ein attribut so deklariert
Java:
public setKoordinaten(koordinaten){
    this.koordinaten=koordinaten;
}
[CODE lang="java" title="Aufruf"]this.setKoordinaten(this.koordinaten,x, y);[/CODE]
1. hat this.koordinaten noch keinen Wert, also kannst du's auch nicht verwenden
2. brauchst du's gar nicht verwenden.
2.1 Bei der Deklaration solltest du der Variable sofort einen Wert zuweisen, dieser wird schon zugewiesen, bevor der Konstruktor aufgerufen wird
Java:
private final Koordinaten koordinaten = new Koordinaten(); //eventuell mit 0,0 initialisieren, falls notwendig.
Anm: Du kannst den Wert natürlich auch im Konstruktor zuweisen, das macht keinen Unterschied. Wichtig is, dass das passiert, bevor die Variable anderweitig verwendet wird.
2.2 Beim Aufruf sollte this.koordinaten kein Parameter sein, die Methode akzeptiert nur x und y und weist diese dann an this.koordinaten zu.
ist das so üblich das man attributen vorher einen Wert zu weißt
den wenn ja sollte dann ja wieder meine eigentliche methode funktieren oder
Java:
setKoordinaten(int x, int y){
    this.koordinaten.setX=x
    this.koordinaten.setY=y
}
also des nur als overload zum einfacheren handhaben
 
meinst du mit normalerweise(also) das man ein attribut so deklariert
Das Attribut wird so nicht deklariert. Die Deklaration des Attributs ist das
private Koordinaten koordinaten;

Und der typische Setter seiner Attributs hat als Parameter ein Element vom Typ des Attributs.

Deine Methode fuktioniert technisch. Aber die Kernfrage ist und bleibt: Sind die Koordinaten veränderlich? Kann ein Feld D1 zu einem Feld E1 werden? Oder ist es nicht eher so wie auch die Zahlen? Eine 5 ist ud bleibt eine 5. Da wo eine Zahl gespeichert wird, kannst Du nur eben eine andere Zahl speichern. Du kannst die 5 also z.B. durch eine 6 ersetzen. Aber du kannst die 5 nicht zu einer 6 machen. (Bei der Klasse Integer z.B.)
Das würde sich immutable nennen. Das ist aber schlicht etwas, das ich hier jetzt meine zu sehen. Dein Verständnis kann durchaus anders sein.

Ein
Java:
setKoordinaten(int x, int y){
    this.koordinaten.setX=x
    this.koordinaten.setY=y
}
kann technisch natürlich auch funktionieren. Vom Design her ist dies aber schon etwas, das aufmerken lässt: Du gibt damit Attribute eines Attributs nach außen. Das ist zumindest unüblich. Du hast die Klasse Koordinaten eingeführt - dann nutze diese auch konsequent. Wenn Du nicht mit Koordianten arbeiten willst, dann musst Du es auch nicht in einer Klasse kapseln. Dann kannst Du wieder x und y in der Figur speichern:
Java:
private int x;
private int y;
public void setKoordinaten(int x, int y) {
    this.x = x;
    this.y = y;
}

Also bei einem Objektmodell wirklich überlegen, mit was für Objekten Du arbeiten willst, was diese darstellen und wie Du diese nutzen willst.

Und dann sind das keine Koordinaten sondern die Klasse gibt doch ein Spielfeld an. Dann würde ich das ggf. auch so nennen.
Dann kann die Klasse Intern x / y Werte haben. Die gehen aber niemanden etwas außerhalb an. Also ob das 0 basiert ist oder it 1 anfängt oder oder oder ...
toString kann daraus dann evtl "d1" und so aus den Werten machen. Du hast Evtl. ein parseSpielfeld, dass aus einem "d1" ein Spielfeld machen kann. Du kannst vergleichen. Du hast evtl. eine Methode, die alle Felder auf einem Weg angibt, also sowas wie: getAllFieldsTo(Spielfeld) und das gibt dann bei geraden bewegungen alle Felder bis hin zum Zielfeld. Bei Bewegungen des Springers kommt nur das Zielfeld raus. Dann wäre das auch nicht mehr ein reines Zusammen fügen von x/y sondern bekommt auch noch ein Verhalten.
Evtl. hast Du ein Spiebrett, das alle Spielfelder enthält. Dann wäre das "immutable" sehr wichtig - die Spielfelder selbst dürfen sich nicht ändern ...
 
... falls dieses Attribut eine Klasse ist es erst neu instanzieren muss...
Das wäre auch falsch (das Wort "neu" gehört nicht in diesen Satz).

Jedes Objekt eines nicht primitiven Datentyps muss erst mal initialisiert werden, sonst ist es null
Java:
class Demo {
    Demo {
        setPoint(1,2); //Nullpointerexception, p ist null
    }
    public setP(int x, int y) {
        this.p.setLocation(x,y); //funktioniert nur, falls p != null
    }
    private String string; //ist null
    private Point p; //auch null
}
//also:
class Demo {
    Demo {
        setPoint(1,2);
    }
    public setP(int x, int y) {
        this.p.setLocation(x,y); //funktioniert nur, falls p != null
    }
    private String string; //ist null
    private Point p = new Point(); //nicht mehr null, Juhuu
}
//oder
class Demo {
    Demo {
        this.p = new Point();
        setPoint(1,2);
    }
    public setP(int x, int y) {
        this.p.setLocation(x,y); //funktioniert nur, falls p != null
    }
    private String string; //ist null
    private Point p; //null, wird aber im Konstruktor gesetzt
}
Btw, Objekte, die nur ein einziges Mal entweder im Konstruktor oder direkt bei der Deklaration initialisiert werden, sollten final sein. Sinnvoll wäre
Java:
private final Point p = new Point();
 
meinst du mit normalerweise(also) das man ein attribut so deklariert
Ein Attribut ist ja nur eine Variable, die den Wert eines bestimmten Typen aufnehmen kann.

In Java wird zwischen primitven Typen, wie int oder double, und Referenztypen, wie String, unterschieden. Ein Referenztyp enthält nicht direkt den Wert, sondern eine Referenz, die auf die Stelle verweist, die den eigentlichen Wert enthält (einfach erklärt).

Deklarierst du also ein Attribut mit einem primitiven Typen, wie private int value;, dann hat dieser direkt den Wert 0 und du kannst einfach einen anderen Wert zuweisen.

Deklarierst du dagegen ein Attribut mit einem Referenztypen, wie private Koordinate koordinate;, dann sagst du damit zwar, dass die Variable "koordinate" einen Verweis auf eine tatsächliche Koordinate aufnehmen soll, aber diesen Verweis kann es noch nicht geben, weil ja noch keine Instanz einer Koordinate existiert. Dieses Attribut hat also zunächst den Wert "null" - also nix. Aus dem Grund erhältst du auch deine Fehlermeldung, weil du versuchst, Methoden auf eine Instanz aufzurufen, die es noch gar nicht gibt.

Du kannst also bei der Deklaration direkt einen (Standard-)Wert zuweisen mit private Koordinate koordinate = new Koordinate(0,0);. Du kannst das auch in einem Konstruktor machen, oder an ganz anderer Stelle, aber, wenn du das Attribut benutzen möchtest, dann musst du das vorher getan haben.
 

Zurück
Oben