1

在我进入问题的实质之前,让我注意这是一个纯粹的理论问题。出于实际原因,我对此不感兴趣,我对如何处理这种情况的底层 OOP 理论感兴趣。

在我正在进行的一个项目中,我有两个密切相关的类。一种是通用的“用户”类。另一个是子类,并添加了某些用户使用的附加功能——对于一个通用示例,可​​以考虑一个“主持人”类。

如何处理用户类上可用的公共方法,这些方法对孩子调用没有意义?

例如,调用 User::getUserWithId(id) 非常有意义(此方法从数据库中检索数据并使用该数据初始化并返回用户类);在主持人类中使用该方法没有多大意义(如果有的话)。

我是否应该忽略它——如果用户调用 moderator::getUserWithId(id),他们仍然会得到一个用户,这正是他们所要求的。尽管有方法名称,我是否应该覆盖它以返回主持人?还是在我不熟悉的 OOP 领域有什么东西可以让我“阻止”通话?

4

2 回答 2

1

如果您的基类中有在子类中没有意义的方法,那么我认为您需要重新评估是否应该通过继承关系对这些类进行建模。需要在子类中隐藏基类的成员是一个危险信号,表明通过继承关系对此进行建模是有问题的。

继承关系应指示“是”关系。对于您的示例,主持人对象“是”用户对象,因此应该具有与用户对象相同的方法和属性。如果没有,那么它似乎与它的基用户类没有真正的继承关系。

在这种情况下,您可能需要考虑使用接口而不是继承。您可以将 User 和 Moderator 类之间的通用功能分解到一个界面中。如果它们可以共享公共代码,那么您可以使用组合来实现这一点,方法是创建接口的公共实现,然后将其传递给需要重用此代码的类。有关详细信息,请参阅此处此处

正如上面第二个链接中的作者所说:

  • TypeB 是否想公开 TypeA 的完整接口(所有公共方法不少于),以便 TypeB 可以在预期 TypeA 的地方使用?表示继承。

  • TypeB 是否只需要 TypeA 暴露的部分/部分行为?表示需要组合。

从您需要隐藏基类的成员来看,您似乎属于第二类,可能想探索使用组合和接口。

于 2013-01-22T01:44:18.643 回答
1

昨天我留下了一个回复,不知何故迷路了。我认为,@Joe Alfano 有一个很好的解释,可以解决您的“理论”和特定问题。除此之外,在我看来,问题的一个根源可能是您正在域对象中进行数据库访问。一般来说,除非有令人信服的理由,否则这不是一个好的做法。如果您将该数据库访问权限移除到单独的层,例如数据访问层 (DAL),则此问题就会消失。你的类中不会有 User::getUserWithId(id) 东西,它们将在 DAL 中处理。喜欢

class UserDao {
     User getById(id)

}

Class ModeratorDao {

     Moderator getById(id)
}

如果您采用类似 DAL 的方法,那么您还将找到重构代码的方法,这是另一回事。

于 2013-01-22T15:30:17.027 回答