使用Interface和Abstract类

时间:2017-05-30 02:29:52

标签: java interface abstract-class

我正在尝试了解Interface和Abstract类及其用法。

让我们说,我有Interface IPlan。有三个实现它的类,schoolPlan, highSchoolPlan, collegePlan。如果我想编写一个createPlan()服务方法来接受这三个计划类型对象中的任何一个,我该怎么做? 在我的服务类中,如果我这样做,

public String createPlan(IPlan plan) {}

由于传递的对象将被实例化为IPlan,我将无法访问我想要创建的对象的变量。 那么,我应该引入Abstract类,比如

public String createPlan(AbstractPlan plan) {}

或者这个模型完全错了?

2 个答案:

答案 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.
   }
}

如果使用接口方法,也不能使用多态数组 - 但前提是你继承了类。