Trong bài viết này, Codegym sẽ hướng dẫn các bạn thực hành việc áp dụng abstract class & implicit casting (ép kiểu ngầm định) để tối ưu hóa các bài toán.
Bắt đầu nhé!
Ta có bài toán: Tính diện tích của toàn bộ các hình học cho trước: hình tròn, hình chữ nhật, hình tam giác.
Với cách thông thường ta sẽ thực hiện như code bên dưới:
class Geometric { } class Circle extends Geometric { double radius; } class Rectangle extends Geometric { double width; double height; } class Triangle extends Geometric { double firstSide; double secondSide; double thirdSide; } public class AreaGeometricDisplay { public void showArea(List<Geometric> geometricList) { for (Geometric geometric : geometricList) { if (geometric instanceof Circle) { Circle circle = (Circle) geometric; double area = Math.PI * circle.radius * circle.radius; System.out.println(area); } if (geometric instanceof Rectangle) { Rectangle rectangle = (Rectangle) geometric; double area = rectangle.width * rectangle.height; System.out.println(area); } if (geometric instanceof Triangle) { Triangle triangle = (Triangle) geometric; double halfOfPerimeter = triangle.firstSide + triangle.secondSide + triangle.thirdSide; double area = Math.sqrt( halfOfPerimeter * (halfOfPerimeter - triangle.firstSide) * (halfOfPerimeter - triangle.secondSide) * (halfOfPerimeter - triangle.thirdSide) ); System.out.println(area); } // Nếu yêu cầu bao gồm thêm việc tính diện tích cho một geometric mới thì ta phải sửa lại method này } } }
Nếu yêu cầu bài toàn thay đổi, tức là sẽ thêm việc tính diện tích cho một hình học mới thì ta phải chỉnh sửa lại phương thức AreaGeometricDisplay#showArea() và viết thêm các câu lệnh if để phục vụ cho việc tính diện tích hình học mới đó.
Có thể thấy, cách làm trên rất dài dòng và dễ phát sinh lỗi.
Vì vậy, ta sẽ áp dụng abstract class và override lại phương thức getArea() như code dưới đây:
abstract class Geometric { abstract double getArea(); } class Circle extends Geometric { double radius; @Override double getArea() { return Math.PI * this.radius * this.radius; } } class Rectangle extends Geometric { double width; double height; @Override double getArea() { return this.width * this.height; } } class Triangle extends Geometric { double firstSide; double secondSide; double thirdSide; @Override double getArea() { double halfOfPerimeter = this.firstSide + this.secondSide + this.thirdSide; return Math.sqrt( halfOfPerimeter * (halfOfPerimeter - this.firstSide) * (halfOfPerimeter - this.secondSide) * (halfOfPerimeter - this.thirdSide) ); } } public class AreaGeometricDisplay { public void showArea(List<Geometric> geometricList) { for (Geometric geometric : geometricList) { System.out.println(geometric.getArea()); } } }
Dễ thấy, nếu yêu cầu bài toán cũng thay đổi như trên, thì ta chỉ việc định nghĩa một class mới và kế thừa class Geometric, sau đó override lại phương thức getArea(). Và việc tính toán diện tích của một hình học mới sẽ không cần phải chỉnh sửa phương thức AreaGeometricDisplay#showArea() phải không nào.
Vì vậy, trong tương lại để tối ưu các bài toán như trên, ta nên áp dụng abstract class, khái niệm Override và khởi tạo các đối tượng thông qua cách ép kiểu ngầm định (implicit casting) để bài toán dễ bảo trì và giảm chỉnh sửa ít nhất có thể.
Chúc các bạn thành công!
Author: Nguyễn Vũ Thành Tiến
0 Lời bình