Ich glaube mit der 4. Frage war folgendes gemeint: Es können eh keine Objekte der abstrakten Klasse angelegt werden, also wäre die Wirkung die gleiche auch wenn der Konstruktor public wäere ? Er kann eh nur von einem Konstruktor eine konkreten Subklasse aufgerufen werdenSichtbarkeit so gering wie möglich, aber so groß wie nötig
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.
Und genau das ist ja das gewünschte Verhalten, denn du willst ja nicht das jemand einfach folgendes macht: AbstractFigure fig = new AbstractFigure();
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?
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;
}
}
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?
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?
Zu 1)
Kannst du mir ein Beispiel nennen, welche Methode dann doppelt implementiert werden muss?
Zu 1)
Zu 2) Also wäre meine Lösung auch richtig?
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?
implementiert wird jede nur einmal, nur deklariert werden sie doppelt.
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;
}
}
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;
}
}
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());
}
}
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.
Macht es denn sinn, Radius und Größe zu speichern, wenn beides das gleiche ausdrückt?
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;
}
}
Die Mittelpunktskoordinaten werden immer mit 0 initialisiert.