我正在尝试了解Interface和Abstract类及其用法。
让我们说,我有Interface IPlan
。有三个实现它的类,schoolPlan, highSchoolPlan, collegePlan
。如果我想编写一个createPlan()
服务方法来接受这三个计划类型对象中的任何一个,我该怎么做?
在我的服务类中,如果我这样做,
public String createPlan(IPlan plan) {}
由于传递的对象将被实例化为IPlan,我将无法访问我想要创建的对象的变量。 那么,我应该引入Abstract类,比如
public String createPlan(AbstractPlan plan) {}
或者这个模型完全错了?
答案 0 :(得分:2)
如果每个IPlan
中都存在实例变量,无论它是什么类型IPlan
,那么定义变量的abstract
类是合适的。实际上,您可能会考虑仅定义抽象类,而不是接口。如果接口的唯一用途是拥有一个实现它的抽象类,而其他所有东西都是抽象类的子类,那么该接口就没有多大用处。
如果不同类型IPlan
的变量不同,则createPlan
不应尝试访问变量。编写像
public String createPlan(AbstractPlan plan) {
...
if (plan instanceof SchoolPlan) {
return doSomethingWith(((SchoolPlan)plan).schoolType, ...)
} else if (plan instanceof HighSchoolPlan) {
return doSomethingElseWith(((HighSchoolPlan)plan).schedule, ...)
...
}
这违背了多态性的目的。相反,您可能想问:createPlan
的哪些部分在所有类之间是共同的,以及不同子类之间的不同之处是什么?不同的东西可以变成你在abstract
类中定义的方法(理想情况下,如果你的“服务类”在同一个包中,你可以使它们成为protected
方法createPlan
可以使用它们,但在其他任何地方都无法使用它们。例如,如果createPlan
返回的字符串包含一个包含计划描述的标题,但描述取决于每个计划类型唯一的不同变量,则可以定义一个getDescription()
抽象方法。在每个班级实施。
[我不是说instanceof
总是坏的;但是真正需要它的情况相对较少,通常你应该寻找替代方案。]
P.S。使用I
来表示接口是一种C#约定,Java程序员倾向于把握起来。
答案 1 :(得分:0)
在界面中,您无法在那里实现您的方法,只需定义它们即可。 根据您的示例,让我们尝试执行以下操作:
interface IPlan {
String createPlan();
}
public abstract class APlan implements IPlan {
@Override
String createPlan() {
//do something in general for schoolplan, collegeplan, highschoolplan.
}
}
public class SchoolPlan extends APlan {
@Override
String createPlan() {
super();
//do something unique for school plan here.
}
}
如果使用接口方法,也不能使用多态数组 - 但前提是你继承了类。