Java 从方法返回接口对象而不实例化(未知)具体类型
我肯定有一些解决方案或模式,但我很难清楚地回答这个问题以找到正确的答案 我有一个界面,ICar:Java 从方法返回接口对象而不实例化(未知)具体类型,java,design-patterns,interface,polymorphism,Java,Design Patterns,Interface,Polymorphism,我肯定有一些解决方案或模式,但我很难清楚地回答这个问题以找到正确的答案 我有一个界面,ICar: public interface ICar { void SetMake(String make); String GetMake(); } 我有一门课,一辆车: public class Car implements ICar { private String make; public void SetMake(String make) { this.make = make; } publi
public interface ICar {
void SetMake(String make);
String GetMake();
}
我有一门课,一辆车:
public class Car implements ICar {
private String make;
public void SetMake(String make) { this.make = make; }
public String GetMake() { return make; }
我在另一个类中有一个方法,它不知道汽车。本着多态性的精神,我希望此方法返回一个ICar,以便有人可以创建自己的ICar实现,并将此方法用于他们的汽车:
...//class preamble
public ICar myMethod() {
ICar myCar = new ICar();
myCar.SetMake("Ferrari");
return myCar;
}
我不知道为什么像这样的东西不起作用。由于ICar包含方法SetMake,因此每个实现也必须包含此方法。当然jvm可以以某种方式将方法调用排队,然后在方法的具体化可用时运行它们
另一个想法是将新创建的ICar实现作为参数传递给myMethod并调用其方法,但我觉得这可能不是一个干净的实现,因为每次我都需要创建一个Car实例。另外,如果没有无参数构造函数,我将不得不用伪数据(也不是干净的)实例化它
我觉得我对如何实现这样的东西缺乏一些理解,我想知道是否有人能提供帮助
谢谢。您需要执行以下操作:
public ICar myMethod() {
ICar myCar = new Car();
myCar.SetMake("Ferrari");
return myCar;
}
而不是
public ICar myMethod() {
ICar myCar = new ICar();
myCar.SetMake("Ferrari");
myCar.return;
}
此语句:
myCar.return代码>在这里几乎没有意义。。。由于ICar是一个接口,您不能执行ICar myCar=new ICar()
您不能实例化接口,因此new ICar()
不是一个选项。例如,setMake应该设置一个实例变量,但接口没有实例变量
但是,您可以执行以下操作:
return new ICar() {
String m;
@Override
public void setMake(String make)
{
m = make;
}
@Override
public String getMake()
{
return m;
}
};
这样,您就可以创建一个实现接口的对象
虽然这个答案给出了一个特定的例子来回答这个问题(就像简单地实例化一个Car对象一样),但是关于接口的更大的问题是,可以返回接口中实现的任何对象。有任意数量的设计模式可用于委托对象的创建。例如,你可以考虑,你不能创建一个新的界面,但是你可以返回一个。
public ICar myMethod() {
ICar myCar = new Car();
myCar.SetMake("Ferrari");
return myCar;
}
接口意味着一个契约,它基本上是说“这是一个ICar
它可以是Car
,RedCar
和一千种不同的实现,但你不知道是哪种”。
这就是多态性的含义无论谁使用myMethod
都不知道他得到的是哪辆车,他只能知道契约,而不能知道它们是如何实现的。我不太确定我是否确切理解你的目的,但我想你真正想做的是从一个抽象基类继承你的车,以便其他人可以实施其他类型的车辆
大概是这样的:
public abstract class Vehicle {
public abstract void SetMake(String make);
public abstract String GetMake();
}
public class Car extends Vehicle {
private String make;
public void SetMake(String make) { this.make = make; }
public String GetMake() { return make; }
}
public class Truck extends Vehicle {
private String make;
public void SetMake(String make) { this.make = make; }
public String GetMake() { return make; }
}
public Vehicle myMethod() {
Vehicle myCar = new Truck();
myCar.SetMake("Ferrari");
return myCar;
}
Car car = myMethod(Car.class);
对于您已声明的方法myMethod()
本着多态性的精神,我希望此方法返回一个ICar,以便有人可以创建自己的ICar实现,并将此方法用于他们的汽车:
我从中了解到,您希望使myMethod()
与不同具体类型的ICar
一起工作
使用新操作符时会创建对象。现有代码无法编译,因为无法实例化接口的对象。要修复编译错误,我不希望您创建具体的汽车对象:
ICar car = new Car(); // this will solve compile error but avoid doing this in your code
避免使用new
操作符,让代码的用户使用new并注入具体的实现(您甚至可能不知道具体的实现,因为它们依赖于用户,即代码的用户)
改变方法如下
...//class preamble
public ICar myMethod(ICar myCar, String make) {
myCar.SetMake(make);
return myCar;
}
我建议您学习:DIP原则
和依赖项注入
,代码到接口
,一种方法是提供类类型作为参数,并使其通用:
public <T extends ICar> T myMethod(Class<T> type) {
try {
T myCar = type.newInstance(); // T needs a visible no-args constructor
myCar.SetMake("Ferrari");
return myCar;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
更灵活的方法是引入工厂接口,并将工厂实例传递给myMethod
,后者使用它创建具体的ICar
。工厂仍然可以是通用的:
public interface ICarFactory<T extends ICar> {
T createCar();
}
...
public <T extends ICar> T myMethod(ICarFactory<T> factory) {
T myCar = factory.createCar();
myCar.SetMake("Ferrari");
return myCar;
}
...
Car car = myMethod(carFactory);
公共接口ICarFactory{
T createCar();
}
...
公共MYT方法(ICarFactory工厂){
T myCar=factory.createCar();
myCar.SetMake(“法拉利”);
归还我的车;
}
...
汽车=我的方法(汽车工厂);
新ICar()代码>将不会编译,因为它是一个接口。很抱歉,我在myCar.return中出错。但这并不能解决问题,因为myMethod无法知道车辆类型。返回后是否可以将其“转换”为车辆类型?所以我可以调用myMethod,比如:carnewcar=myMethod()
?@RicketyRick否,该方法返回的是接口
,而不是特定的类。因此,调用将是ICar newCar=myMethod()
。通常最好使用接口方法,而不是特定的类实现代码>myMethod不知道具体车型?(除了将新车作为参数传递)@Ricketrick,否,因为Car
是一个特定的类。更好的方法是使用接口ICar
,而不是使用特定的类Car
。然而,我对你使用“类型”这个词的方式做了一些假设,这可能是不正确的。我认为,最好的方法是为myMethod使用工厂模式,返回ICar
,并允许工厂返回ICar
的特定/具体实例。的确,可以使用此层次结构,但我仍然会创建接口IVehile,并让myMethod()返回该接口。本例还重复了两个子类中的字符串make
,可以在基本类中处理。这里的方法仍然将一个编程留给一个特定的实现。这是我唯一能做的