Schnittstellen

JavaIsTheBest

Bekanntes Mitglied
Hallo,
ich soll bei dieser Aufgabe Java Schnittstellen definieren. Dazu hätte ich ein paar Fragen.

1. Wozu werden die Interfaces Ellipse und Square benötigt?
2. Wäre es falsch, wenn man diese beiden Interfaces weggelassen hätte?
 

Anhänge

  • 02.png
    02.png
    63,6 KB · Aufrufe: 124

JStein52

Top Contributor
Zu 1.) würde ich sagen um den Dingen einen Namen zu geben.
zu 2.) es wäre nicht falsch gewesen aber vielleicht nicht das was der Aufgabensteller sehen wollte ;);)

Edit: siehe ersten Satz der Aufgabenstellung
 

JavaIsTheBest

Bekanntes Mitglied
1. Warum ist die Klasse AbstractFigure abstrakt, obwohl es keine einzige abstrakte Methode gibt? Kann man das "abstract" auch weglassen? Wenn nein, warum nicht?
2. Kann man von einer abstrakten Klasse, einen Konstruktor definieren. Wenn ja, wozu?
3. Warum kann man von abstrakten Klassen Konstruktoren definieren? Man macht doch eine abstrakte Klasse, wenn man kein Objekt dieser Klasse erstellen möchte.
4. In der Klasse "AbstractIrregularFigure" steht vor dem Konstruktor, der Modifikator protected. Wozu das?(Ich weiß, protected wird verwendet, damit die Unterklasse darauf zugreifen kann)
 

Anhänge

  • 07.png
    07.png
    437,1 KB · Aufrufe: 113

InfectedBytes

Top Contributor
1. Da es keine abstrakten Methoden gibt, könntest du das abstract vor der Klasse weglassen, allerdings macht es schon Sinn es stehen zu lassen. Denn dadurch das die Klasse abstrakt ist, kann man kein Objekt daraus erzeugen. Und genau das ist ja das gewünschte Verhalten, denn du willst ja nicht das jemand einfach folgendes macht: AbstractFigure fig = new AbstractFigure();
2. Ja. Eine Unterklasse muss immer einen Konstruktor der Oberklasse aufrufen, implizit wird dabei immer der parameterlose Konstruktor (falls vorhanden) aufgerufen. Wenn du nun also einen Konstruktor in deiner abstrakten Klasse definierst, dann zwingst du die Unterklasse dazu, dass sie diesen Konstruktor aufruft.
3. sieht 2.
4. Im Grunde wieder das Prinzip: Sichtbarkeit so gering wie möglich, aber so groß wie nötig.
 

JavaIsTheBest

Bekanntes Mitglied
2. Ja. Eine Unterklasse muss immer einen Konstruktor der Oberklasse aufrufen, implizit wird dabei immer der parameterlose Konstruktor (falls vorhanden) aufgerufen. Wenn du nun also einen Konstruktor in deiner abstrakten Klasse definierst, dann zwingst du die Unterklasse dazu, dass sie diesen Konstruktor aufruft.

1. Ich verstehe immer noch nicht, warum man einen Konstruktor in einer abstrakten Klasse definiert, wenn man von der Klasse kein Objekt erzeugen will. Das ist doch unnötig?

Und genau das ist ja das gewünschte Verhalten, denn du willst ja nicht das jemand einfach folgendes macht: AbstractFigure fig = new AbstractFigure();

2. Warum sollte ich das nicht wollen? :)
Ich sehe keinen Grund, der dagegen spricht, ein neues Objekt vom Typ Figure zu erstellen, wenn die Klasse nicht abstrakt ist.

3. Und woher weiß ich, dass es sinnvoll ist, wenn die Klassen AbstractRegularFigure, AbstractIrregularFigure, AbstractFigure abstrakt sind?
Was spricht dafür, diese Klassen abstrakt zu machen?
 
Zuletzt bearbeitet:

@SupressWarnings()

Aktives Mitglied
@JavaIsTheBest
Zu 1: Wenn du zum Beispiel eine Klasse Auto hast, dann möchtest du vielleicht nicht, dass es direkt Autos gibt, aber du möchtest, dass jedes Auto einen Namen, eine Höchstgeschwindigkeit und ein Herstellungsjahr hat. Also schreibst du in der abstrakten Oberklasse diesen festen Konstruktor, der später aufgerufen werden MUSS.

Zu 3: Man kann Klassen abstrakt machen, wenn es nur Unterklassen geben soll. Du könntest natürlich darauf vertrauen, dass der Anwender kein Objekt der Oberklasse erstellt, es ist aber sicherer sie abstrakt zu machen. Die Funktion von Oberklassen ist dann, für viele Unterklassen Variablen und Methoden zu definieren, damit du nicht zehn mal dasselbe in die Klassen schreiben musst.

Ich hoffe das hilft.
@SupressWarnings()
 

JavaIsTheBest

Bekanntes Mitglied
Stimmt, nur die Klassen Kreis, Ellipse, Rechteck und Quadrat sollen laut Aufgabenstellung konkret sein.
Der Rest der klassen sollte abstrakt sein.

Brauche ich den Konstruktor laut Aufgabenstellung in den abstrakten Klassen unbedingt? Steht das irgendwo?
Ich hätte es so gemacht, dass ich nur in den Klassen Kreis, Ellipse, Rechteck und Quadrat Konstruktoren definiert hätte. Wäre das falsch gewesen? Welchen Nachteil hätte ich dabei?
 

Joose

Top Contributor
Ich hätte es so gemacht, dass ich nur in den Klassen Kreis, Ellipse, Rechteck und Quadrat Konstruktoren definiert hätte. Wäre das falsch gewesen? Welchen Nachteil hätte ich dabei?

Solanges es funktioniert und nicht verlangt wurde ist es nicht falsch ;)

Nachteil: Du musst in jeder deiner Klassen (Kreis, Ellipse, Reckteck und Quadrat) dafür sorgen das die Koordinaten (x und y) gesetzt werden. Vergisst du es kann es zu Problemen kommen. Sprich du hast 4 Klassen wo du 4x die gleichen Anweisungen schreibst (Duplicate Code sollte vermieden werden).
Würdest die abstrakte Basisklasse nun einen Konstruktor mit 2 Parametern (für x und y) bereitstellen, so musst du diesen Konstruktor verpflichtend aufrufen im Konstruktor der Subklassen.
 

JavaIsTheBest

Bekanntes Mitglied
1. Warum wird in der Musterlösung dieses "implements XY" in den abstrakten Klassen kommentiert?
Warum wird das an dieser Stelle nicht benötigt?

2. Ich habe das so gemacht, dass in der Klasse AbstractIrregularFigure, der Konstruktor aus der Oberklasse aufgerufen wird. In der Musterlösung wird das nicht so gemacht. Meine Lösung ist trotzdem auch richtig?

Java:
abstract class AbstractIrregularFigure extends AbstractFigure {
    private double breite;
    private double hoehe;
   
    protected AbstractIrregularFigure(double mx, double my, double breite,double hoehe){
        super(mx,my);
        this.breite=breite;
        this.hoehe=hoehe;
    }
    public double getBreite(){
        return breite;
    }
    public double getHoehe(){
        return hoehe;
    }
    public void skaliere(double f){
        breite*=f;
        hoehe*=f;
    }
   
}


3. Ich fand das ganze Programm zu programmieren sehr unübersichtlich. Habt ihr Tipps, wie ich den Überblick behalte? So, dass ich nicht vergesse, welche Methoden ich zu implementieren habe?
 
Zuletzt bearbeitet:

mrBrown

Super-Moderator
Mitarbeiter
1. Warum wird in der Musterlösung dieses "implements XY" in den abstrakten Klassen kommentiert?
Warum wird das an dieser Stelle nicht benötigt?

Benötigt wird es nicht, man muss dann die Methoden halt doppelt deklarieren.
Ich hätte die Abstrakten Klassen auch das Interface implementieren lassen.

2. Ich habe das so gemacht, dass in der Klasse AbstractIrregularFigure, der Konstruktor aus der Oberklasse aufgerufen wird. In der Musterlösung wird das nicht so gemacht. Meine Lösung ist trotzdem auch richtig?

Man sollte immer den Oberkonstruktor aufrufen, wenn das aber nur der Defaultkonstruktor, wird der implizite aufgerufen, in der Musterlösung braucht man das also nicht. Schöner ist's allerdings, einen Konstruktor zu haben, der die privaten Werte setzt, in der MusterLösung müsste man erst #move aufrufen.

3. Ich fand das ganze Programm zu programmieren sehr unübersichtlich. Habt ihr Tipps, wie ich den Überblick behalte? So, dass ich nicht vergesse, welche Methoden ich zu implementieren habe?

Naja, die Interfaces geben dir vor, welche Methoden implementiert sein. Also als erstes die nötigen Interfaces angeben, dann implementieren. Sollte was fehlen, sagt dir spätestens der Compiler bescheid.
Ansonsten, vorher vernünftig planen, zb UML-Diagramme erstellen ;)
 

JavaIsTheBest

Bekanntes Mitglied
Und in der Klasse AbstractFigure werden nicht alle Methoden, der Schnittstelle Figure implementiert. Z.B ist die Methode scale/skaliere in der abstrakten Klasse nicht dabei.
Woher weiss ich, welche Methoden ich in dieser Klasse benötige und welche nicht?
 

mrBrown

Super-Moderator
Mitarbeiter
Zu 1)
Kannst du mir ein Beispiel nennen, welche Methode dann doppelt implementiert werden muss?

implementiert wird jede nur einmal, nur deklariert werden sie doppelt.

Zu 1)
Zu 2) Also wäre meine Lösung auch richtig?

Ja

Und in der Klasse AbstractFigure werden nicht alle Methoden, der Schnittstelle Figure implementiert. Z.B ist die Methode scale/skaliere in der abstrakten Klasse nicht dabei.
Woher weiss ich, welche Methoden ich in dieser Klasse benötige und welche nicht?

AbstractFigure implementiert Figure auch nicht zumindest nicht in der Musterlösung.
In abstracten Klassen immer das implementieren, was für alle möglichen Unterklassen gleich wäre
 

mrBrown

Super-Moderator
Mitarbeiter
Jein, wenn man es so macht, wie in der Musterlösung, dann muss man die Deklaration aus dem Interface in die Abstrakte Klasse kopieren, und erst in der Klasse, die dann das Interface implementiert, merkt man zB Tippfehler (das Interface muss nicht mal implementiert werden, dann gäbe es abstrakte Figuren, die keine Figuren gibt).

Implementiert man das Interface stattdessen schon in der abstrakten Klasse, muss da zwingend die korrekte Methode implementiert werden (wenn man @Override benutzt). Außerdem ist dann auch zwingen jeder abstrakte Figur eine Figur.
 

JavaIsTheBest

Bekanntes Mitglied
Wenn ich die Fläche eines Kreises berechnen will, dann erhalte ich immer den Wert 0.
Das liegt am Konstruktor.
Wäre es schlechter Programmierstil, wenn ich zuerst super(0,0,r); aufrufe und dann erst this.radius=r; zuweise?
Weil, so würde es funktionieren.

Java:
abstract class AbstractRegularFigure extends AbstractFigure{
    private double groesse;
   
    protected AbstractRegularFigure(double mx, double my, double groesse){
        super(mx,my);
        this.groesse=groesse;
    }
    public double size(){
        return groesse;
    }
    public double getBreite(){
        return groesse;
    }
    public double getHoehe(){
        return groesse;
    }
    public void skaliere(double f){
        groesse*=f;
    }

}

Java:
public class KreisImpl extends AbstractRegularFigure implements Kreis{
    private double radius;
    public KreisImpl(double r){
        super(0,0,r);
    }
    public double radius(){
        return radius;
    }
    public double getFlaeche(){
        double f=Math.PI*radius*radius;
        return f;
    }

}

Java:
public class FigureTest {

    public static void main(String[] args) {
        KreisImpl k=new KreisImpl(3);
       
        System.out.println(k.getBreite());
        System.out.println(k.getFlaeche());
        k.skaliere(2);
        System.out.println(k.getBreite());
        System.out.println(k.getHoehe());

    }

}
 

mrBrown

Super-Moderator
Mitarbeiter
Wenn ich die Fläche eines Kreises berechnen will, dann erhalte ich immer den Wert 0.
Das liegt am Konstruktor.
Wäre es schlechter Programmierstil, wenn ich zuerst super(0,0,r); aufrufe und dann erst this.radius=r; zuweise?
Weil, so würde es funktionieren.

Du musst immer erst super(...) aufrufen, bevor du irgendwas anderes machen kannst, also der richtige Weg. Macht es denn sinn, Radius und Größe zu speichern, wenn beides das gleiche ausdrückt?
 

JavaIsTheBest

Bekanntes Mitglied
Macht es denn sinn, Radius und Größe zu speichern, wenn beides das gleiche ausdrückt?

Nein, macht es nicht. :)


Was mir noch auffällt. Der Konstruktor wird in der Klasse AbstractFigure (Musterlösung) ohne die Mittelspunktskoordinaten erstellt. Obwohl das doch laut Aufgabenstellung so sein soll?

Meine Lösung:

Java:
abstract class AbstractFigure {
    private double mx;
    private double my;
   
    protected AbstractFigure(double mx, double my){
        this.mx=mx;
        this.my=my;
    }
    public double getX(){
        return mx;
    }
    public double getY(){
        return my;
    }
    public void move(double x, double y){
        this.mx+=x;
        this.my+=my;
    }

}
 

mrBrown

Super-Moderator
Mitarbeiter
Das auch AbstractFigure die Mittelpunktskoordinaten übergeben werden müssen, steht da so mEn nicht, implizite werden sie auf 0 gesetzt, und lassen sich ja dann mit #move verändern
 

mrBrown

Super-Moderator
Mitarbeiter
primitive Typen sind immer mit 0 (bzw false) vorbelegt.
Der Abschnitt liest sich aber jetzt doch so, das der Konstruktor keine Position annehmen soll, sondern diese immer auf 0,0 gesetzt werden soll.
 

Neue Themen


Oben