Java 有一个扩展抽象类的空子类可以吗?

Java 有一个扩展抽象类的空子类可以吗?,java,abstract-class,subclass,Java,Abstract Class,Subclass,考虑以下几点: public abstract class Item { String name; String description; //concrete getters and setters follow } public class InventoryItem extends Item { //empty subclass of Item } public class CartItem extends Item {

考虑以下几点:

  public abstract class Item {
     String name;
     String description;
     //concrete getters and setters follow
  }

   public class InventoryItem extends Item {
     //empty subclass of Item 
   }

  public class CartItem extends Item {
     int quantity;
     int tax;
     //getters and setters for quantity and tax follow
  }
InventoryItem表示可供销售的商品,而CartItem表示添加到购物车中的商品,因此它具有其他属性,如数量和税收。在这个场景中,抽象类项的子类为空可以吗

选项2:我们可以有一个空项接口。InventoryItem将实现项并定义名称和描述属性,并具有getter和setter。CartItem将从InventoryItem扩展,并将数量和税定义为属性,并具有getter和setter


选项3:是否最好有一个项目接口。InventoryItem将实现该项。然后我们可以有一个CartItem类,它“有一个”项和两个属性,即tax和quantity,我认为这种设计没有什么错:它明确指定
为基础,而
库存项
/
CartItem
为实例类。我将
Item
重命名为
AbstractItem
(Java类库会这样做),以强调这样一个事实,即该类的预期用途是用作其他类的基础

<> P>有C++特定的问题,例如,使所有“非叶”类抽象化是非常可取的。虽然规则并没有从字面上翻译成Java,但我认为将非叶类抽象化仍然是一个好主意,即使类是自给自足的。这有助于明确区分用于直接实例化的类和用于扩展的类,这有利于不熟悉代码库的人员进行维护

更进一步地说,在Java中,使所有叶类
成为final
是一种常见的做法。这是一个很好的防御规则,尤其是当您的类是不可变的时

编辑:就购物车中的项目建模而言,继承不是最佳选择。事实上,我认为这样做是错误的。我会让我的
CartItem
拥有一个
Item
,而不是扩展它,因为物品不会通过放置在购物车中而成为另一种实体。以下是我认为它应该如何建模:

public class Item {
    String name;
    String description;
    ...
}

public class CartItem {
   Item item;
   int quantity;
   int tax;
   ...
}

让我提出一个稍微长一点的建议或意见,或许可以提供一些指导

在设计is-a层次结构时,我倾向于通过多态性来区分行为。 一般来说,我倾向于避免仅通过数据来区分对象。 多年来,我甚至不再仅仅根据结构类“数据对象”所包含的变量来创建继承层次结构

我花的时间最多的地方是定义抽象类的公共接口,用方法表示,然后创建所有子类,这些子类都适用于相同的接口,但具有不同的行为。(利斯科夫替换原理)

在这种情况下,我会考虑一个通用的接口/抽象项类,它们具有不同的项目实现层次,它们在库存、计算税额等方面有所不同。我可以有一个方法。iSimultCub()可以告诉我哪里是项,或者它的性质是什么,如果我必须用不同的方式处理它。但我仍然会尝试将大多数特定于项类型的逻辑封装到其多态方法的实现中

虽然这些类型的计算实际上通常在数据库的批处理/聚合操作中完成,而不是在单个对象中完成,但我将在抽象级别上使用.getTax(),.getQuantity(),然后使用具有不同行为的子类。 (考虑NulLoBooDebug重构,以避免处理空值)

在这篇坚实的博文中概述了一些有助于此设计的原则:


从设计角度看,它在功能上没有问题,似乎有点挑剔。这正是我所担心的。从设计的角度来看,这是错误的吗?看我的编辑!你能从设计的角度解释为什么它是错误的吗?java有抽象基类的空实现吗?另外,为了安全起见,还是使用我帖子中的option2更好?还是你绝对确定我可以把它卖给一个架构师?@bot我对你的设计所做的唯一两个更改是将
Item
重命名为
AbstractItem
,并在类中添加一个受保护的构造函数。
InventoryItem
将不再为空,因为它需要呈现一个公共构造函数。我认为空界面实际上更糟糕,因为它不能向读者传达任何意义。用接口替换
Item
只是稍微好一点,因为您错过了重用检查和/或生成公共属性的逻辑的机会。这是有道理的。在AbstractItem、无参数保护的构造函数或初始化所有参数的构造函数中,什么更好。我认为无参数构造函数更有意义,因为这不会使getter和setter冗余。@bot答案取决于您是否希望
AbstractItem
是可变的还是不可变的。如果您的设计需要它是可变的,那么无参数构造函数更好;如果它需要是不可变的,最好是一个具有所有参数的构造函数。我正在开发这个应用程序,作为一个面试的任务。考虑到这一点,我认为一个无参数的构造函数现在就足够了!空课真的不好吗?构造函数是必需的吗?