简体   繁体   English

是否可以使用扩展抽象类的空子类?

[英]Is it ok to have an empty subclass that extends an abstract class?

Consider the following: 考虑以下:

  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 represents an item that is available for sale whereas CartItem represents an item that is added to the cart so it has additional properties such as quantity and tax. InventoryItem表示可供销售的项目,而CartItem表示添加到购物车的项目,因此它具有其他属性,如数量和税金。 Is it alright to have an empty subclass of the abstract class Item in this scenario? 在这种情况下,是否可以使用抽象类Item的空子类?

Option 2 : We could have an empty Item interface. 选项2:我们可以有一个空的Item接口。 InventoryItem will implement Item and define name and description properties and have getters and setters. InventoryItem将实现Item并定义名称和描述属性,并具有getter和setter。 CartItem will extend from InventoryItem and will define quantity and tax as properties and have getters and setters. CartItem将从InventoryItem扩展,并将数量和税收定义为属性,并具有getter和setter。

Option 3 : Would it be better to have an Item interface. 选项3:拥有Item接口会更好吗? InventoryItem would implement Item. InventoryItem将实现Item。 We could then have a CartItem class that 'has-an' Item and two properties namely tax and quantity 然后我们可以有一个CartItem类,它有'一个'项和两个属性,即税和数量

I think there is nothing wrong with this design: it clearly designates Item as a base, and InventoryItem / CartItem as instantiable classes. 我认为这个设计没有任何问题:它明确地将Item指定为基础,而InventoryItem / CartItem为可实例化的类。 I would rename Item to AbstractItem (Java class libraries do this) to underscore the fact that the intended use for the class is to be used as a base for other classes. 我将Item重命名为AbstractItem (Java类库执行此操作)以强调该类的预期用途将用作其他类的基础。

There are C++ - specific issues, such as assignment through the base pointer , that make it very desirable to make all "non-leaf" classes abstract. 存在C ++特定的问题,例如通过基指针的赋值 ,这使得非常希望使所有“非叶子”类抽象化。 Although the rule does not translate to Java literally, I think it is still a good idea to make non-leaf classes abstract, even when the class is self-sufficient. 虽然规则并没有按字面意思转换为Java,但我认为将非叶类抽象化仍然是一个好主意,即使该类是自给自足的。 This helps you make explicit separation between classes intended for direct instantiation and classes intended for extending, which is good for maintenance by people who are not familiar with your code base. 这有助于您在用于直接实例化的类和用于扩展的类之间进行明确分离,这有助于不熟悉您的代码库的人员进行维护。

Taking the rule a step further, it is a common practice in Java to make all leaf classes final . 进一步采用该规则,Java中的常见做法是使所有叶类final This is a good defensive rule, especially when your classes are immutable. 这是一个很好的防御规则,特别是当你的类是不可变的时候。

EDIT : As far as modeling items in the cart goes, inheriting is not the best option. 编辑:对于购物车中的建模项目,继承不是最好的选择。 In fact, I think it is a wrong thing to do. 事实上,我认为做错了。 I would make my CartItem own an Item , rather than extending it, because the item does not become another kind of entity by being placed in a cart. 我会让我的CartItem拥有一个Item ,而不是扩展它,因为该项目不会通过放置在购物车中而成为另一种实体。 Here is how I think it should be modeled: 以下是我认为它应该如何建模:

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

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

Let me offer a slightly longer suggestion, or an opinion, which might provide some guidance. 让我提供一个稍长的建议或意见,这可能会提供一些指导。

When designing is-a hierarchy I tend to make distinctions only in behaviors through polymorphism. 当设计是一个层次结构时,我倾向于仅通过多态来区分行为。 In general, I tend to avoid distinction between objects by data only. 一般来说,我倾向于避免仅通过数据区分对象。 Over the years, I even stopped created inheritance hierarchies for struct-like "data objects" on the sole basis of what variables they hold. 多年来,我甚至根据它们所拥有的变量来停止为类似结构的“数据对象”创建的继承层次结构。

Where I spend most time is in defining the common interface for the abstraction class represents in terms of methods and then having subclasses that are all amenable to the same interface, but with different behaviors. 我花费大部分时间的地方在于定义抽象类的公共接口表示方法,然后具有所有适用于相同接口但具有不同行为的子类。 (Liskov Substitution Principle) (利斯科夫替代原则)

In this case, I would consider a common interface/abstract Item class with hierarchy of Item implementations that differ in how they stock, calculate their taxes, etc. I could have a method .isInCatalog() that would tell me where is item or what is its nature if I have to handle it differently, but I would still try to encapsulate most of the item-type specific logic into the implementations of its polymorphic methods. 在这种情况下,我会考虑一个公共接口/抽象Item类,其中Item实现的层次结构在库存方式,计算税收等方面有所不同。我可以使用方法.isInCatalog()来告诉我项目在哪里或者什么如果我必须以不同的方式处理它是它的本质,但我仍然会尝试将大多数项类型特定逻辑封装到其多态方法的实现中。

Although these types of calculations are usually in practice done in a batch/aggregate operations on a database and not in a single object, I would have on abstract level .getTax(), .getQuantity() and then have sub-classes with different behaviors. 虽然这些类型的计算通常在数据库的批处理/聚合操作中实现,而不是在单个对象中完成,但我会在抽象级别.getTax(),. getQuantity()上进行,然后具有不同行为的子类。 ( Consider NullObject refactoring for do nothings to avoid handling nulls) (考虑NullObject重构,以避免处理空值)

Few principles that aid this design are outlined here in this solid blog post: 这篇坚实的博客文章中概述了很少有助于这种设计的原则:

http://codebork.com/2009/02/18/solid-principles-ood.html http://codebork.com/2009/02/18/solid-principles-ood.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 有一个扩展另一个类的“空”类是否可以? - Is it OK to have an 'empty' class that extends another class? 初始化扩展抽象类的子类 - Initialising a Subclass that extends an Abstract class Java PaintComponent的大小和在扩展Jpanel的抽象类的子类中的位置 - Java PaintComponent size and position in a subclass of an abstract class that extends Jpanel 如果子类扩展了抽象类,则克隆方法的语法是什么? - what the syntax for clone method if the subclass extends abstract class? Java类扩展了抽象类,但必须具有静态方法 - Java Class extends Abstract class but must have static method 如果子类没有构造函数,如何通过第三类(不扩展抽象类)管理抽象类的子类? - How to manage a subclass of an abstract class via a third class(not extending the abstract class) if the subclass doesn't have a constructor? 在Android AppCompatActivity中,每个扩展BaseActivity的子类都可以实现一种抽象方法吗? - In Android AppCompatActivity, can I have an abstract method being implemented by each subclass that extends BaseActivity? 为什么通过创建扩展抽象类“Figure”的子类“Square”来获得 NullPointerException? - Why do I get a NullPointerException by creating a subclass "Square" which extends an abstract class "Figure"? 抽象类及其子类 - Abstract Class and Its Subclass 实例化抽象类的子类 - Instantiate subclass of abstract class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM