[Thực hành] Hệ các đối tượng hình học

Kế thừa

Mục tiêu:

Luyện tập kỹ năng lập bản thiết kế và triển khai lớp đối tượng kế thừa.

Điều kiện:

Biết cách thiết kế và triển khai lớp đối tượng kế thừa.

Mô tả:

Thiết kế lớp đối tượng Shape và các lớp con của nó thành giản đồ UML theo mô tả dưới đây:

Lớp Shape

  • Có hai thuộc tính là color (String) và filled (boolean).
  • Có hai phương thức khởi tạo, một trong số đó không cần đối số đầu vào mà sử dụng giá trị mặc định: "green" cho color và truecho filled. Phương thức khởi tạo còn lại đặt giá trị cho thuộc tính của color và filled theo giá trị của đối số truyền vào.
  • Có các getter và setter cho tất cả các thuộc tính.
  • Được cài đè phương thức toString trả về chuỗi ký tự theo mẫu "A Shape with color of xxx and filled/not filled".
  • Có hai lớp con là Circle và Rectangle

Lớp Circle

  • Có thêm thuộc tính radius (double).
  • Có ba phương thức khởi tạo. Phương thức khởi tạo mà không cần đối số đầu vào sẽ đặt giá trị mặc định cho radius là 1.0.
  • Có các getter và setter cho cả ba phương thức.
  • Có phương thức getArea và getPerimeter trả về diện tích và chu vi của hình.
  • Được cài đè phương thức toString trả về chuỗi ký tự theo mẫu "A Circle with radius=xxx, which is a subclass of yyy". Trong đó yyy là kết quả thực thi từ phương thức toString của lớp Shape.

Lớp Rectangle

  • Có thêm hai thuộc tính là width và length (double).
  • Có ba phương thức khởi tạo. Phương thức khởi tạo mà không cần đối số đầu vào sẽ đặt giá trị mặc định cho width và length là 1.0.
  • Có các getter và setter cho tất cả các thuộc tính.
  • Có phương thức getArea và getPerimeter trả về diện tích và chu vi của hình.
  • Được cài đè phương thức toString trả về chuỗi ký tự theo mẫu "A Rectangle with width=xxx and length=zzz, which is a subclass of yyy".Trong đó yyy là kết quả thực thi từ phương thức toString của lớp Shape.
  • Có một lớp con là lớp Square.

Lớp Square

Chú ý: trong thực tế, một “square” không phải là một “rectangle”, do đó quan hệ “lớp square là lớp con của lớp rectangle” là không hợp lý. Tình huống ở đây được đưa ra chỉ với mục đích luyện tập hiện thực hóa mô tả thành giản đồ UML và triển khai mã theo bản vẽ.

Lớp Square:

  • Không có thêm thuộc tính nào so với lớp cha.
  • Không có phương thức khởi tạo nào sử dụng đối số dầu vào width và length, thay vào đó là đối số side.
  • Phương thức khởi tạo mà không cần đối số đầu vào sẽ đặt giá trị mặc định cho width và height (side) là 1.0.
  • Có getter và setter cho side.
  • Cài đè phương thức setWidth và getWidth để chúng thay đổi giá trị của cả width và height, để bảo toàn tính “vuông”.
  • Được cài đè phương thức toString trả về chuỗi ký tự theo mẫu "A Square with side=xxx, which is a subclass of yyy".Trong đó yyy là kết quả thực thi từ phương thức toString của lớp Rectangle.

Có cần phải cài đè phương thức getArea và getPerimeter không?

Hướng dẫn

Bước 1: Vẽ giản đồ UML

Tự phân tích và vẽ hoàn chỉnh giản đồ UML của hệ lớp đối tượng. Sau đó so sánh với giản đồ mẫu ở đây trước khi bắt đầu viết mã triển khai.

Bước 2: Viết mã triển khai và mã kiểm thử cho lớp Shape

Lớp Shape

public class Shape {
    private String color = "green";
    private boolean filled = true;

    public Shape() {
    }

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

    public String getColor() {
        return color;
    }

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

    public boolean isFilled() {
        return filled;
    }

    public void setFilled(boolean filled) {
        this.filled = filled;
    }

    @Override
    public String toString() {
        return "A Shape with color of "
                + getColor()
                + " and "
                + (isFilled() ? "filled" : "not filled");
    }
}

Chương trình để kiểm thử

public class ShapeTest {
    public static void main(String[] args) {
        Shape shape = new Shape();
        System.out.println(shape);

        shape = new Shape("red", false);
        System.out.println(shape);
    }
}

Bước 3: Lớp Circle và mã kiểm thử

Lớp Circle

public class Circle extends Shape {
    private double radius = 1.0;

    public Circle() {
    }

    public Circle(double radius) {
        this.radius = radius;
    }

    public Circle(double radius, String color, boolean filled) {
        super(color, filled);
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public double getArea() {
        return radius * radius * Math.PI;
    }

    public double getPerimeter() {
        return 2 * radius * Math.PI;
    }

    @Override
    public String toString() {
        return "A Circle with radius="
                + getRadius()
                + ", which is a subclass of "
                + super.toString();
    }
}

Chương trình để kiểm thử

public class CircleTest {
    public static void main(String[] args) {
        Circle circle = new Circle();
        System.out.println(circle);

        circle = new Circle(3.5);
        System.out.println(circle);

        circle = new Circle(3.5, "indigo", false);
        System.out.println(circle);
    }
}

Bước 4: Lớp Rectangle và mã kiểm thử

Lớp Rectangle

public class Rectangle extends Shape {
    private double width = 1.0;
    private double length = 1.0;

    public Rectangle() {
    }

    public Rectangle(double width, double length) {
        this.width = width;
        this.length = length;
    }

    public Rectangle(double width, double length, String color, boolean filled) {
        super(color, filled);
        this.width = width;
        this.length = length;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getLength() {
        return length;
    }

    public void setLength(double length) {
        this.length = length;
    }

    public double getArea() {
        return width * this.length;
    }

    public double getPerimeter() {
        return 2 * (width + this.length);
    }

    @Override
    public String toString() {
        return "A Rectangle with width="
                + getWidth()
                + " and length="
                + getLength()
                + ", which is a subclass of "
                + super.toString();
    }
}

Chương trình để kiểm thử

public class RectangleTest {
    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        System.out.println(rectangle);

        rectangle = new Rectangle(2.3, 5.8);
        System.out.println(rectangle);

        rectangle = new Rectangle(2.5, 3.8, "orange", true);
        System.out.println(rectangle);
    }
}

Bước 5: Lớp Square và mã kiểm thử

Lớp Square

public class Square extends Rectangle {
    public Square() {
    }

    public Square(double side) {
        super(side, side);
    }
    
    public Square(double side, String color, boolean filled) {
        super(side, side, color, filled);
    }

    public double getSide() {
        return getWidth();
    }

    public void setSide(double side) {
        setWidth(side);
        setLength(side);
    }

    @Override
    public void setWidth(double width) {
        setSide(width);
    }

    @Override
    public void setLength(double length) {
        setSide(length);
    }

    @Override
    public String toString() {
        return "A Square with side="
                + getSide()
                + ", which is a subclass of "
                + super.toString();
    }
}

Chương trình để kiểm thử

public class SquareTest {
    public static void main(String[] args) {
        Square square = new Square();
        System.out.println(square);

        square = new Square(2.3);
        System.out.println(square);

        square = new Square(5.8, "yellow", true);
        System.out.println(square);
    }
}

Mã hoàn chỉnh của bài hướng dẫn này được đặt tại đây.

Hướng dẫn nộp bài

Up bài lên github

Paste link github vào phần nộp bài và nhấn submit.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

Leave a Reply

Your email address will not be published. Required fields are marked *