Mã sau đây biên dịch và hoạt động tốt. Tôi định nghĩa một giao diện Builder, sau đó lớp CarBuilder được sử dụng để xử lý bất cứ điều gì liên quan đến một chiếc xe, và lớp BusBuilder được sử dụng để xử lý bất cứ điều gì liên quan đến một chiếc xe buýt. Xe hơi và xe buýt chia sẻ một lớp trừu tượng có tên là Xe. Mã này rất đơn giản. Mã chí đầu ra:Chúng ta có thể tự động gọi một phương thức giao diện Java với một tham số chung không?
do something to CREATE the Car
do something to UPDATE the Car
do something to CREATE the Bus
do something to UPDATE the Bus
Đây là mã ban đầu mà biên dịch:
public abstract class Vehicle { }
public class Car extends Vehicle { }
public class Bus extends Vehicle { }
public interface Builder<V extends Vehicle> {
public V createVehicle(String spec);
public void updateVehicle(String spec, Vehicle vehicle);
}
public class CarBuilder implements Builder<Car> {
public Car createVehicle(String spec) {
Car car = new Car();
System.out.println("do something to CREATE the Car");
return car;
}
public void updateVehicle(String spec, Vehicle vehicle) {
Car car = (Car) vehicle;
System.out.println("do something to UPDATE the Car");
return;
}
}
public class BusBuilder implements Builder<Bus> {
public Bus createVehicle(String spec) {
Bus bus = new Bus();
System.out.println("do something to CREATE the Bus");
return bus;
}
public void updateVehicle(String spec, Vehicle vehicle) {
Bus bus = (Bus) vehicle;
System.out.println("do something to UPDATE the Bus");
return;
}
}
@Test
public void main() {
Builder<? extends Vehicle> builder = null;
Vehicle vehicle = null;
builder = new CarBuilder();
vehicle = builder.createVehicle("my original Car spec");
builder.updateVehicle("my modified Car spec", vehicle);
builder = new BusBuilder();
vehicle = builder.createVehicle("my original Bus spec");
builder.updateVehicle("my modified Bus spec", vehicle);
}
Nhưng, tôi muốn làm cho mã của tôi mạnh mẽ hơn nữa, đánh máy. Tôi muốn thay đổi phương thức giao diện,
từ
public void updateVehicle(String spec, Vehicle vehicle);
để
public void updateVehicle(String spec, V vehicle);
Nói cách khác, tôi cố gắng sử dụng generic V
thay vì lớp cơ sở Vehicle
trong chữ ký của giao diện của tôi. Điều này buộc người triển khai của Builder
phải "đóng" trên loại sản phẩm cụ thể (ví dụ: Car
hoặc Bus
, nhưng không phải là loại cơ sở Vehicle
). CarBuilder
chỉ được xử lý Car
; BusBuilder
chỉ nên xử lý Bus
.
Mã này trở thành như sau:
public interface Builder<V extends Vehicle> {
public V createVehicle(String spec);
public void updateVehicle(String spec, V vehicle);
}
public class CarBuilder implements Builder<Car> {
public Car createVehicle(String spec) {
Car car = new Car();
System.out.println("do something to CREATE the Car");
return car;
}
public void updateVehicle(String spec, Car car) {
System.out.println("do something to UPDATE the Car");
return;
}
}
public class BusBuilder implements Builder<Bus> {
public Bus createVehicle(String spec) {
Bus bus = new Bus();
System.out.println("do something to CREATE the Bus");
return bus;
}
public void updateVehicle(String spec, Bus bus) {
System.out.println("do something to UPDATE the Bus");
return;
}
}
@Test
public void main() {
Builder<? extends Vehicle> builder = null;
Vehicle vehicle = null;
builder = new CarBuilder();
vehicle = builder.createVehicle("my original Car spec");
builder.updateVehicle("my modified Car spec", vehicle); <== compilation error
builder = new BusBuilder();
vehicle = builder.createVehicle("my original Bus spec");
builder.updateVehicle("my modified Bus spec", vehicle); <== compilation error
}
Hai lỗi biên dịch - biên dịch Java sẽ không cho phép điều này vì "Phương pháp updateVehicle (String, chụp # 3-of kéo dài xe?) Trong các loại Builder không áp dụng cho các đối số (String, Vehicle) ".
Trong Java có cách nào để làm những gì tôi muốn thực hiện không? Trong C#, tôi có thể chỉ cần nhập biến của mình với var từ khóa, như var vehicle
thay vì Vehicle vehicle
. Tôi nghe nói rằng Java generics invocation là một quyết định thời gian biên dịch. Có một kỹ thuật để vượt qua điều này?
Tại sao phương pháp cập nhật nội dung nào đó về xe buýt hoặc xe hơi không thuộc loại tương ứng? – thatidiotguy
Làm cho cảm giác có. Một Builder được sử dụng phổ biến nhất để tạo một cá thể, chứ không phải để cập nhật nó. – vptheron