在我的背后使用可靠的C ++,一些Java概念并非100%清晰。
List<SomeInterface> list = new ArrayList<SomeImplementation>;
这是100%明确无需解释 - 但它有后果......
interface Drivable {...}
class Car implements Drivable {...}
class Bike implements Drivable {...}
class Skateboard implements Drivable {...}
class MyGarage{
List<Driveable> myRides;
public void addRides( List<Driveable> rideList ){...}
List<Car>
无法调用。但是我可以通过以下方式将汽车添加到myRides:
public void addCars( List<Car> carList ){
myRides.addAll( new List<Driveable>( carList ) );
Q1:这是个好主意吗?
我真的想要像第一个功能一样工作。通过执行与C ++ const&
相对应的内容并将的副本添加到myRides中,我认为carList将受到保护,以防止非法访问。我希望将final
作为一个函数参数添加起来。
Q2:有没有办法让完全可调用的addRides(List<Driveable> rideList)
工作?
超载(List<Car> List<Bike> etc
)也不合法。
是的,我可以通过添加单独的函数addBikes() addCars etc
来完成这项工作,或者我可以在每个调用点执行new List<Drivable>
。但我希望能有更时尚的东西。
问题3:有任何建议吗?
非常感谢! 亚当
答案 0 :(得分:4)
您的 addRides 方法应如下所示:
public void addRides(Collection<? extends Drivable> c)
如果对泛型使用有疑问,请在 java.util 中查找集合接口,它们有很多示例,您想要做的与 {{3}相同确实。
答案 1 :(得分:0)
A1。为了获得更好的保护,您可以使用Collections.unmodifiableList()
包装列表。
A2。您需要public void addRides( List<? extends Driveable> rideList ){...}
,因为rideList
可以包含任何扩展可驱动的内容。
A3。不客气!
答案 2 :(得分:0)
对通用参数使用通配符类型。宣言将是
addRides(List<? extends Driveable> list);
这会接受Car,Skateboard,Bike或任何其他Driveable的列表,并且会正确编译。
答案 3 :(得分:0)
您可以通过对方法进行参数化来实现此目的:
public class MyGarage{
public static void main(String[] args) {
MyGarage garage = new MyGarage();
garage.addRides(new ArrayList<Car>(4));
garage.addRides(new ArrayList<Bike>(4));
}
List<Driveable> myRides;
public <T extends Driveable> void addRides( List<T> rideList ){
// ...
}
}
这基本上声明您的方法将接受任何对象列表T,使得T从Driveable扩展。我建议从生产者和消费者的角度阅读描述Java Generics的this excellent SO post。
答案 4 :(得分:0)
你没有问过的问题应该是第一行代码
List<SomeInterface> list = new ArrayList<SomeImplementation>;
为什么不编译?
原因不一样是您需要public void addRides( List<? extends Driveable> rideList )