Hãy tha thứ cho tôi nếu câu hỏi này chủ yếu dựa trên ý kiến, nhưng tôi có cảm giác rằng nó không phải là và có một lý do chính đáng cho sự lựa chọn. Đây là một ví dụ. Xin lỗi, nó thực sự dài, nhưng siêu đơn giản:Giải thích biên dịch ghi đè và quá tải
Interface:
public interface Shape
{
double area();
}
Thực hiện lớp 1:
import static java.lang.Math.PI;
public class Circle implements Shape
{
private double radius;
public Circle(double radius)
{
this.radius = radius;
}
public double area()
{
return PI*radius*radius;
}
}
Thực hiện lớp 2:
public class Square implements Shape
{
private double size;
public Square(double sideLength)
{
size = sideLength;
}
public double area()
{
return size*size;
}
}
Driver:
Shape[] shapes = new Shape[]{new Circle (5.3), new Square (2.4)};
System.out.println(shapes[0].area()); //prints 88.247...
System.out.println(shapes[1].area()); //prints 5.76
Công trình này từ .area()
bị ghi đè bởi Circle
và Square
. Bây giờ, đây là câu hỏi của tôi thực sự bắt đầu. Hãy nói rằng người lái xe có những phương pháp:
public static void whatIs(Shape s)
{
System.out.println("Shape");
}
public static void whatIs(Circle s)
{
System.out.println("Circle");
}
public static void whatIs(Square s)
{
System.out.println("Square");
}
Nếu chúng ta gọi là:
whatIs(shapes[0]); //prints "Shape"
whatIs(shapes[1]); //prints "Shape"
Điều này xảy ra bởi vì Java giải thích các đối tượng như Shape
s và không Circle
và Square
. Dĩ nhiên chúng ta có thể có được kết quả mong muốn thông qua:
if (shapes[0] instanceof Circle)
{
whatIs((Circle) shapes[0]); //prints "Circle"
}
if (shapes[1] instanceof Square)
{
whatIs((Square) shapes[1]); //prints "Square"
}
Bây giờ chúng ta có một nền tảng câu hỏi của tôi là: "Shape"
gì lý do góp phần vào việc thiết kế trình biên dịch/ngôn ngữ mà whatIs(shapes[0]);
sẽ in Như trong, tại sao trình biên dịch Java có thể phân biệt chính xác giữa các phương thức ghi đè cho các đối tượng liên quan, nhưng không phải là các phương thức quá tải? Cụ thể hơn, nếu các phương pháp duy nhất mà tài xế phải truy cập là:
public static void whatIs(Circle s)
{
System.out.println("Circle");
}
public static void whatIs(Square s)
{
System.out.println("Square");
}
và chúng tôi cố gắng để gọi,
whatIs(shapes[0]);
whatIs(shapes[1]);
chúng tôi sẽ nhận được hai lỗi (một cho Square
và một cho Circle
) cho thấy rằng:
- phương pháp Driver.whatIs (Square) không áp dụng
- Shape tranh luận thực tế không thể được chuyển đổi sang Quảng trường bằng cách chuyển đổi phương pháp gọi
Vì vậy, một lần nữa, bây giờ mà chúng tôi đã nhận được đến nitty-gritty, tại sao có thể Java không xử lý một tình huống như thế điều này? Như trong, điều này được thực hiện do mối quan tâm hiệu quả, là nó chỉ là không thể do một số quyết định thiết kế, đây có phải là một thực hành xấu vì một lý do nào đó, vv?
Ngoài ra, nếu có ai có ý tưởng tốt hơn cho tiêu đề, vui lòng đưa ra đề xuất hoặc chỉnh sửa, tôi biết rằng đó có thể không phải là đề xuất hay nhất, nhưng không thể nghĩ ra điều gì tốt hơn. Cảm ơn tất cả những ai đã vượt qua bài đăng này! –
Tôi đề nghị bạn đi qua [Phần JLS 15.2.2] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2) (Quá tải) và [JLS Mục 8.4.8.1] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8.1) (Ghi đè) –
Câu hỏi thú vị và @ RohitJain cảm ơn vì lời bình luận, tôi cũng sẽ phải đọc những lời đó. –