2016-08-29 6 views
-1

Konnte keine relevante Erklärung online finden Ich habe Hausaufgaben zu tun, ich sollte eine Klasse namens Shapes und 2 weitere Klassen eine für Rechteck und die zweite ist für einen Kreis. Ich wollte wissen, was der beste Weg ist, Konstruktoren, Datenelemente und Methoden anzuordnen, weil zum Beispiel für ein Rechteck ich Höhe und Breite haben sollte und der Kreis einen Radius hat.Die effizienteste Art der Verwendung von Konstruktoren, Methoden, Datenelementen in anderen Klassen JAVA

public class Shapes { 

    //Should I use only common Data members, constructors and functions in the base class? 
    private int x; 
    private int y; 
    private int width; 
    private int height; 
    private String color; 
    private double radius; 

auch wie erstelle ich die relevanten Konstruktoren mit super()? Ich glaube, ich habe alles vermischt:

//Constructors: 
    public Shapes() { 

    } 

    //Common constructor 
    public Shapes(int x, int y, String color) { 
     setX(x); 
     setY(y); 
     setColor(color); 

    } 
    //Circle constructor: 
    public Shapes(int x, int y, String color, double radius) { 
     this(x, y, color); 
     setRadius(radius); 
    } 

    //Rectangle constructor: 
    public Shapes(int x, int y, int width, int height, String color) { 
     this(x, y, color); 
     setWidth(width); 
     setHeight(height); 
    } 

im Rechteck-Klasse sieht es wie folgt aus:

public Rectangle() { 
    super(); 
} 

public Rectangle(int x, int y, int width, int height, String color) { 
    super(x, y, width, height, color); 
} 

und in der Kreisklasse Ich habe es wie folgt aus:

public Circle() { 
    super(); 
} 

public Circle(int x, int y, String color, double radius) { 
    super(x, y, color, radius); 
} 

Ich brauche eine Druckmethode, um alle Informationen aus jeder Klasse, die für die Klasse relevant ist, zu drucken. Gibt es eine Möglichkeit, diese Druckmethode in der Basisklasse (Shapes) zu verwenden, um mehrere Druckmethoden zu vermeiden?

Es gibt verschiedene Parameter, die angezeigt werden sollen, aber es wurde uns gesagt, die Multiplikation des Codes zu vermeiden.

+1

Sie müssen nicht alles in "Shapes". Die Form-spezifischen Dinge sollten in ihren jeweiligen Klassen sein, d. H. "Radius" sollte in "Kreis" existieren, nicht in "Formen" oder "Rechteck". Ihr Konstruktor/Super Verwirrung ist das Ergebnis von Ihnen Missverständnis, wie Superklassen und Unterklassen zu bauen. – Kayaman

+1

'Shape' sollte eine abstrakte Klasse sein, die nur' x', 'y' und' color' handhabt. Die konkreten Klassen können "Breite", "Höhe" und "Radius" in den Klassen haben, zu denen sie gehören. – 4castle

Antwort

1

Eine Basisklasse sollte niemals Eigenschaften haben, die nicht allen Unterklassen gemeinsam sind. In der Tat sollte es nicht einmal über seine Unterklassen wissen. Für weitere Informationen lesen Sie bitte das Liskow-Substitutionsprinzip und das Offen/Geschlossen-Prinzip. Die Basisklasse sollte daher wahrscheinlich nur die Parameter x, y und color haben. So könnte der Shapes Konstruktor wie folgt sein:

public Shapes(int x, int y, String color) { 
    setX(x); 
    setY(y); 
    setColor(color); 
} 

und den Kreis Konstruktor wie folgt aus:

public Circle(int x, int y, String color, double radius) { 
    super(x, y, color); 
    this.radius = radius; 
} 

Die Art und Weise Sie die Basisklassenkonstruktoren überlastet für die verschiedenen abgeleiteten Klassen passend ist wirklich ein sehr schlechtes Design . Es widerspricht nicht nur den oben genannten Prinzipien. Es wird auch für jemanden, der den Code liest, sehr schwer zu verstehen sein.

+0

Zum Beispiel, siehe http: // stackoverflow.com/questions/56860/was-ist-das-liskov-ersatz-prinzip –

+0

es ist alles klar danke ich saß bis spät gestern studieren wahrscheinlich könnte nicht klar denken :) –

0

Setzen Sie nur Mitglieder in eine Superklasse, wenn sie für alle Unterklassen sinnvoll sind. Sie sollten auch eine abstrakte Klasse verwenden, um die Erstellung eines einfachen Shape-Objekts und das Schlüsselwort protected zu verhindern, um Mitglieder vor der Außenwelt zu verbergen, aber Unterklassen diese anzeigen zu lassen.

public abstract class Shape { 
    protected int x; 
    protected int y; 
    protected String color; 

    protected Shape() { this(0, 0, ""); } 
    protected Shape(int x, int y, String color) { 
     this.x = x; 
     this.y = y; 
     this.color = color; 
    } 
    // setter and getters for x, y, and color 
} 

public class Rectangle extends Shape { 
    private int width; 
    private int height; 

    public Rectangle() { this(0, 0, "", 0, 0); } 
    public Rectangle(int x, int y, String color, int width, int height) { 
     super(x, y, color); 
     this.width = width; 
     this.height = height; 
    } 
    // setters and getters for width and height 
} 

public class Circle extends Shape { 
    private double radius; 

    public Circle() { this(0, 0, "", 0.0); } 
    public Circle(int x, int y, String color, double radius) { 
     super(x, y, color); 
     this.radius = radius; 
    } 
    // setter and getter for radius 
} 
+0

Wir haben immer noch nicht die geschützten und abstrakten Themen abgedeckt aber ich danke Ihnen für die Informationen Ich werde es nachschlagen und versuchen es zu verwenden, nachdem Sie genau verstanden haben, wie es funktioniert. bin dankbar. –

0

Beginnen wir mit den Attributen. Sie sollten überlegen, ob ein Attribut für Unterklassen einer Klasse oder nur für einige von ihnen gilt. Ist es beispielsweise sinnvoll, in der Shapes-Klasse ein "radius" -Attribut zu setzen? Benötigen alle Unterklassen von Shape dieses Attribut? Denken Sie an Rechteck: Hat ein Rechteck (Instanz) einen Radius? Wenn Sie das Radiusattribut in Shapes deklarieren, was wäre der Wert für Rechteckinstanzen? Vermeiden Sie die Verwendung von Ersatzattributen in Klassen für die Leistung, aber hauptsächlich für die Lesbarkeit. Gleiches gilt für Breite und Höhe.

Nun, was ist mit Farbe?Wird jede Form eine Farbe haben? Also, es ist ein gemeinsames Attribut ?.

Die x- und y-Attribute sind hier eine Besonderheit: Das gleiche Attribut kann zwei völlig verschiedene Dinge bedeuten: Für einen Kreis sollte es das Zentrum sein, aber für Rechtecke könnte der obere linke (oder was auch immer) sein. Sollten sie das gleiche Attribut sein oder zwei verschiedene Attribute sein? Ich würde für die zweite gehen, aber es ist meine Meinung.

Schließlich, was die Konstruktoren betrifft: Würden Sie jemanden eine Form-Instanz erstellen lassen, ohne ein Kreis oder ein Rechteck zu sein? Benötigen Sie einen öffentlichen Konstruktor in der Shapes-Klasse? Hat eine Form Sinn, die nur eine Form und kein Kreis oder ein Rechteck (oder irgendeine andere Unterklasse von Shape) ist?

Übrigens: Ich denke, es wäre besser, Ihre Shapes-Klasse nur in Shape umzubenennen. Eine Klasse repräsentiert ein Konzept; dann können Sie Instanzen dieses Konzept erstellen, die Formen sind ...

=== === EDIT

vergaß ich den letzten Teil Ihrer Frage zu Druckmethoden: man Sie entscheiden, wo jedes Attribut setzen , finden und beantworten Sie selbst .. Kann eine Methode einer Klasse in einigen ihrer Unterklassen auf Attribute zugreifen?

Oh, noch etwas: die toString-Methode ist immer vorhanden, weil sie in der Object-Klasse definiert ist. Denken Sie über die Beziehung der toString-Methode und der Druckmethode nach, die Sie benötigen.

0

Machen der Form Klasse eine abstrakte Klasse mit einer abstrakten Methode, die alle anderen Klassen

public abstract class Shape { 
    protected int x; 
    protected int y; 
    protected String color; 

    public Shape(String color) { 
     this.color = color; 
    } 

    public Shape() { 
     this("0xfffffff"); 
    } 

    public Shape(int x, int y, String color) { 
     this(color); 
     this.x = x; 
     this.y = y; 
    } 

    public Shape(int x, int y) { 
     this(); 
     this.x = x; 
     this.y = y; 
    } 

    public int getX() { return x; } 
    public int getY() { return y; } 
    public String getColor() { return color; } 

    public void setX(int x) { this.x = x; } 
    public void setY(int y) { this.y = y; } 
    public void setColor(String color) { this.color = color; } 

    @Override 
    public abstract String toString(); 
} 

public class Rectangle extends Shape { 
    private int width; 
    private int height; 

    public Rectangle(int width, int height){ 
     super(); 
     this.width = width; 
     this.height = height; 
    } 

    public Rectangle(int width, int height, String color){ 
     super(color); 
     this.width = width; 
     this.height = height; 
    } 

    public int getWidth() { return width; } 
    public int getHeight() { return height; } 

    // Also include setters if you don't need immutability 

    @Override 
    public String toString() { 
     return String.format("Rectangle\nWidth: %d\nHeight: %d\nColor: %s", width, height, color); 
    } 
} 

Dies ist nur Meinung meiner definieren müssen. Es gibt viele andere Möglichkeiten, diese Klassen zu strukturieren, aber alles hängt davon ab, wie Sie sie verwenden möchten. Die Art, wie ich zur Verfügung gestellt haben macht es einfach, diese in 3D zu erweitern, so dass Sie wie folgt deklariert 3D-Shape-Klasse haben:

public abstract class Shape3D extends Shape { 
    protected int z; 

    public Shape3D() { 
     super(); 
    } 
} 

Nicht sagen Sie ein 3D-Objekt benötigt, aber es geht um nicht selbst einschließende mit Design, da das Projekt komplexer wird.


In Ihrem Haupt-Klasse können Sie eine Reihe von Shape s haben und Sie können sie leicht alle wissen, drucken, dass sie alle definiert die toString Methode haben würde.

public final class Main { 
    public static void main(String []args) { 
     List<Shape> shapes = new ArrayList<>(); 
     // fill the list with all kinds of shapes 

     for (Shape shape: shapes) { 
      System.out.println(shape); // Will default to System.out.println(shape.toString()); 
     } 
    } 
} 

Ein letzter zu notieren; Wenn Sie lange Konstruktoren für eine Klasse schreiben müssen, sollten Sie sich fragen, ob Sie von dem Builder-Muster profitieren können. Zum Beispiel die Rectangle-Klasse kann mit einem Builder wie erstellt werden:

public abstract class ShapeBuilder { 
    int x, y; 
    String color; 

    public ShapeBuilder setX(int x) { 
     this.x = x; 
     return this; 
    } 

    public ShapeBuilder setY(int y) { 
     this.y = y; 
     return this; 
    } 

    public ShapeBuilder setColor(String color) { 
     this.color = color; 
     return this; 
    } 

    public abstract <T extends Shape> T build(); 
} 

public class RectangleBuilder extends ShapeBuilder { 
    int width; 
    int height; 

    public RectangleBuilder setWidth(int width) { 
     this.width = width; 
     return this; 
    } 

    ... 

    @Override 
    public Rectangle build() { 
     Rectangle rect = new Rectangle(width, height, color); 
     rect.setX(x); 
     rect.setY(y); 
     return rect; 
    } 
} 
+0

Wie würden Sie damit ein farbiges 'Rectangle' erstellen? Sie benötigen mehr Parameter im Konstruktor. Außerdem ist es wahrscheinlich eine schlechte Idee, 'Shape3D' zu erlauben,' Shape' zu ​​erweitern, da der Polymorphismus es dem Benutzer eines Objekts ermöglichen soll, sich der konkreten konkreten Klasse, die verwendet wird, nicht bewusst zu sein. Es wäre nicht sinnvoll, ein 3D-Objekt in einer 2D-Umgebung zu verwenden, daher sollten sie separate Entitäten sein. – 4castle

Verwandte Themen