6. Luyện Tập Polymorphism, Abstract Classes and Interfaces
6.1 Ex: Abstract Superclass Shape and Its Concrete Subclasses
Rewrite the superclass Shape and its subclasses Circle, Rectangle and Square, as shown in the class diagram.
Trong bài tập này, Shapesẽ được định nghĩa là một abstractlớp, bao gồm:
- Hai
protectedbiến đối tượng color( String) và filled( boolean). Các protectedbiến có thể được truy cập bởi các lớp con và các lớp trong cùng một gói. Chúng được ký hiệu bằng một '#'dấu hiệu trong sơ đồ lớp.
- Getter và setter cho tất cả các biến thể hiện và
toString().
- Hai
abstractphương thức getArea()và getPerimeter()(thể hiện bằng chữ in nghiêng trong sơ đồ lớp).
Các lớp con Circlevà Rectanglesẽ ghi đè lên các abstractphương pháp getArea()và getPerimeter()và cung cấp việc thực hiện đúng. Họ cũng ghi đè lên các toString().
Viết một lớp kiểm tra để kiểm tra các câu lệnh liên quan đến đa hình và giải thích các đầu ra. Một số báo cáo có thể kích hoạt lỗi biên dịch. Giải thích các lỗi, nếu có.
Shape s1 = new Circle(5.5, "RED", false);
System.out.println(s1);
System.out.println(s1.getArea());
System.out.println(s1.getPerimeter());
System.out.println(s1.getColor());
System.out.println(s1.isFilled());
System.out.println(s1.getRadius());
Circle c1 = (Circle)s1;
System.out.println(c1);
System.out.println(c1.getArea());
System.out.println(c1.getPerimeter());
System.out.println(c1.getColor());
System.out.println(c1.isFilled());
System.out.println(c1.getRadius());
Shape s2 = new Shape();
Shape s3 = new Rectangle(1.0, 2.0, "RED", false);
System.out.println(s3);
System.out.println(s3.getArea());
System.out.println(s3.getPerimeter());
System.out.println(s3.getColor());
System.out.println(s3.getLength());
Rectangle r1 = (Rectangle)s3;
System.out.println(r1);
System.out.println(r1.getArea());
System.out.println(r1.getColor());
System.out.println(r1.getLength());
Shape s4 = new Square(6.6);
System.out.println(s4);
System.out.println(s4.getArea());
System.out.println(s4.getColor());
System.out.println(s4.getSide());
Rectangle r2 = (Rectangle)s4;
System.out.println(r2);
System.out.println(r2.getArea());
System.out.println(r2.getColor());
System.out.println(r2.getSide());
System.out.println(r2.getLength());
Square sq1 = (Square)r2;
System.out.println(sq1);
System.out.println(sq1.getArea());
System.out.println(sq1.getColor());
System.out.println(sq1.getSide());
System.out.println(sq1.getLength());
Việc sử dụng abstractphương thức và abstractlớp là gì?
6.2 Ex: Polymorphism
Kiểm tra các mã sau đây và vẽ sơ đồ lớp.
abstract public class Animal {
abstract public void greeting();
}
public class Cat extends Animal {
@Override
public void greeting() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void greeting() {
System.out.println("Woof!");
}
public void greeting(Dog another) {
System.out.println("Woooooooooof!");
}
}
public class BigDog extends Dog {
@Override
public void greeting() {
System.out.println("Woow!");
}
@Override
public void greeting(Dog another) {
System.out.println("Woooooowwwww!");
}
}
Giải thích các đầu ra (hoặc lỗi) cho chương trình thử nghiệm sau.
public class TestAnimal {
public static void main(String[] args) {
Cat cat1 = new Cat();
cat1.greeting();
Dog dog1 = new Dog();
dog1.greeting();
BigDog bigDog1 = new BigDog();
bigDog1.greeting();
Animal animal1 = new Cat();
animal1.greeting();
Animal animal2 = new Dog();
animal2.greeting();
Animal animal3 = new BigDog();
animal3.greeting();
Animal animal4 = new Animal();
Dog dog2 = (Dog)animal2;
BigDog bigDog2 = (BigDog)animal3;
Dog dog3 = (Dog)animal3;
Cat cat2 = (Cat)animal2;
dog2.greeting(dog3);
dog3.greeting(dog2);
dog2.greeting(bigDog2);
bigDog2.greeting(dog2);
bigDog2.greeting(bigDog1);
}
}
6.3 Ex: Interface Movable and its implementations MovablePoint and MovableCircle
Giả sử rằng chúng ta có một tập hợp các đối tượng với một số hành vi phổ biến: chúng có thể di chuyển lên, xuống, sang trái hoặc phải. Các hành vi chính xác (như cách di chuyển và di chuyển bao xa) phụ thuộc vào chính các đối tượng. Một cách phổ biến để mô hình hóa những hành vi phổ biến là xác định một giao diện được gọi là Movable, với abstractphương pháp moveUp(), moveDown(), moveLeft()và moveRight(). Các lớp thực hiện Movablegiao diện sẽ cung cấp thực hiện thực tế cho các abstractphương thức này .
Chúng ta hãy viết hai lớp cụ thể - MovablePointvà MovableCircle- thực hiện giao diện Movable.
The code for the interface Movable
public interface Movable {
public void moveUp();
......
}
Đối với các MovablePointlớp, khai báo các biến Ví dụ x, y, xSpeedvà ySpeedvới truy cập gói như hình với '~'trong sơ đồ lớp (ví dụ, lớp trong cùng một gói có thể truy cập các biến trực tiếp). Đối với các MovableCirclelớp, sử dụng một MovablePointđại diện cho trung tâm của nó (mà chứa bốn biến x, y, xSpeedvà ySpeed). Nói cách khác, các thành phần MovableCirclea MovablePoint, và của nó radius.
public class MovablePoint implements Movable {
int x, y, xSpeed, ySpeed;
public MovablePoint(int x, int y, int xSpeed, int ySpeed) {
this.x = x;
......
}
......
@Override
public void moveUp() {
y -= ySpeed;
}
......
}
public class MovableCircle implements Movable {
private MovablePoint center;
private int radius;
public MovableCircle(int x, int y, int xSpeed, int ySpeed, int radius) {
center = new MovablePoint(x, y, xSpeed, ySpeed);
......
}
......
@Override
public void moveUp() {
center.y -= center.ySpeed;
}
......
}
Write a test program and try out these statements:
Movable m1 = new MovablePoint(5, 6, 10, 15);
System.out.println(m1);
m1.moveLeft();
System.out.println(m1);
Movable m2 = new MovableCircle(1, 2, 3, 4, 20);
System.out.println(m2);
m2.moveRight();
System.out.println(m2);
Viết một lớp mới được gọi MovableRectangle, bao gồm hai MovablePoints(đại diện cho các góc trên cùng bên trái và dưới cùng bên phải) và thực hiện MovableGiao diện. Hãy chắc chắn rằng hai điểm có cùng tốc độ.
Sự khác biệt giữa một interface và một lớp trừu tượng là gì?
6.4 Ex: Interfaces GeometricObject and Resizable
- Viết lệnh được gọi , trong đó khai báo hai phương thức: và , như được chỉ định trong sơ đồ lớp. Gợi ý:
interface được gọi là lệnhGeometricObject , khai báo hai abstractphương thức: getParameter()và getArea(), như được chỉ định trong sơ đồ lớp.
Gợi ý:
public interface GeometricObject {
public double getPerimeter();
......
}
- Viết lớp thực hiện
Circle, với một biến được bảo vệ radius, thực hiện giao diện GeometricObject.
Gợi ý:
public class Circle implements GeometricObject {
......
......
@Override
public double getPerimeter() { ...... }
......
}
- Viết chương trình kiểm tra được gọi
TestCircleđể kiểm tra các phương thức được định nghĩa trong Circle.
- Lớp
ResizableCircleđược định nghĩa là một lớp con của lớp Circle, nó cũng thực hiện một giao diện được gọi Resizable, như được hiển thị trong sơ đồ lớp. Giao diện Resizablekhai báo một abstractphương thức resize(), điều chỉnh kích thước (chẳng hạn như radius) theo tỷ lệ phần trăm nhất định. Viết giao diện Resizablevà lớp ResizableCircle.
Gợi ý:
public interface Resizable {
public double resize(...);
}
public class ResizableCircle extends Circle implements Resizeable {
public ResizableCircle(double radius) {
super(...);
}
@Override
public double resize(int percent) { ...... }
}
- Viết chương trình kiểm tra được gọi
TestResizableCircleđể kiểm tra các phương thức được định nghĩa trong ResizableCircle.
Đăng nhận xét