【问题标题】:Understanding the concepts of OOP [closed]了解 OOP 的概念 [关闭]
【发布时间】:2019-01-27 18:50:23
【问题描述】:

为这个可能超级简单的问题道歉。我正在尝试理解 OOP。我已经阅读了教程,但其中许多教程都非常简化,并且通过给自己一个“真实”项目,我遇到了大多数教程似乎没有涵盖的障碍。这是一个我有点想理解的场景:

如果我正在制作一个非常基本的体育游戏(想想国际足联),我目前有 3 个对象:

  • 音高对象
  • 团队对象
  • 播放器对象

我遇到了我的第一道理解障碍,因为我不希望玩家只是团队​​的延伸。毕竟在现实生活中,我们都是人类的对象,具有一个属性,在我们成为团队的子对象之前,我们会告诉我们我们属于哪个团队。

这方面的最佳做法是什么?

我应该是:

  1. 创建玩家对象,然后将每个对象添加到存储在团队对象的数组中?这就是我在程序上的做法。
  2. 针对玩家存储球队。
  3. 将球员与球队对抗。
  4. 按团队扩展球员(我想避免这种情况,除非它真的完成了)

这只是现在的大脑练习,所以我并没有真正的代码,但是

$team1 = new teamObject('red');

$player1 = new players('John'); 
$team1->addToTeam($player1); 

这让我印象深刻,因为它不起作用,因为在 teamObject 类中我无法在传递的玩家函数上调用任何玩家类函数?

【问题讨论】:

  • 当然,如果他们在一个团队中,你可以调用他们的方法。如果您不能拥有包含其他对象的对象,那么 OOP 将毫无用处。事实上,这种事情——组合对象——应该比创建继承层次结构更受青睐。您(实际上,所有第一次学习 OOP 的程序员)都应该阅读这本书:smile.amazon.com/… 它通过多个示例教授了如何思考 OOP 的一般方法。

标签: php oop object object-oriented-analysis


【解决方案1】:

这对我来说通常是有意义的:

$team1 = new teamObject('red');
$player1 = new players('John'); 
$team1->addToTeam($player1); 

虽然通常它可能看起来更像这样(但实际上是一样的):

$team1 = new Team('red');
$player1 = new Player('John'); 
$team1->addPlayer($player1); 

这让我感到震惊,因为它不起作用,因为在 teamObject 类中我无法在传递的玩家函数上调用任何玩家类函数?

您当然可以调用 Player 函数,因为在将玩家添加到团队后,团队将拥有对玩家的引用。它可以通过该引用简单地调用播放器函数。团队中的某个功能可能会使用:

$this->players[0]->pretendToBeHurt();

您绝对不想在这种情况下扩展 Team。

【讨论】:

  • 您好,感谢您的帮助,您能指出我的任何文档/提供从另一个类调用对象函数的更深层次的示例吗?我似乎无法绕过它!
  • @SqlQuery123 这是一个例子:gist.github.com/evert/8e1d9b2d5a97c4e69712af802afba707
  • 另一种思考方式是,您不是在调用另一个类的函数,而是在调用 object 上的函数。团队必须具有对该对象的引用,通常在属性中。
  • Evert,这非常有用!非常感谢您整理了一个实际示例!这真的很清楚,有道理!很高兴知道我也可以以这种方式传递对象!在这个网站上表示感谢的最佳方式是什么?我赞成你的回答!
  • @SqlQuery123 您正在为非常基础的东西而苦苦挣扎。我认为你最好使用一个好的教程、书籍或其他资源,而不是尝试通过反复试验和堆栈溢出来推断 PHP 是如何工作的
【解决方案2】:

根据我的经验,许多初学者会因为害怕上课太多而犯错误。他们尝试使用继承以某种方式“节省空间”并最终得到无意义的对象表示。

您认为球员不是球队的延伸是正确的。这些是 2 个不同的实体,因此不能接近 4。

这些数据结构相互保存的方式实际上取决于实际实现和数据模型。我不知道您对数据库和数据模型有多熟悉,但我们这里有一个多对多关系:一个团队有很多球员,一个球员可以(在他的职业)属于多个团队。

你如何在 PHP 对象中实现这种关系就是你想如何使用它的问题。您还会发现,使用您的方法 2 和 3,这些对象通常同时保存在两个地方。

  • 您需要与团队中的所有玩家一起工作吗?将一组玩家存储在 Team 对象中。
  • 您需要一份球员职业生涯中所有球队的名单吗?在 Player 对象中有一组球队。
  • 您是否需要一名球员的当前球队?在 Player 中有一个 Team 对象。
  • 你需要作为队长的球员吗?在 Team 中有一个 Player 对象。

是的,那么你会有这样的方法:

$player->addToTeam($team1);

$team->addPlayer($player);

$team->addPlayers([
    $player1,
    $player2
]);

(作为旁注,请查看 PSR 编码标准,将您的类命名为大写和单数形式:PlayerTeamPitch。尽快通读文档会有所收获。 )

【讨论】:

  • 嗨,非常感谢,我一定会阅读 PSR 编码标准!由于这是一个假设的计划,我对自己没有明确的要求,我是否正确地认为这是一个多对多的关系,我最好保留团队作为球员的属性,反之亦然,所以下线我可以提取任何我需要的信息吗?
  • 简短回答:是的。有时您可能需要Player 对象中的teams 属性,其他时候Team 对象中的players 属性。但问题在这里变得更加复杂。您想防止出现在 Player 中您引用了特定球队,但在引用的 Team 中您不知道该球员的情况。那你相信哪个?您会发现您需要一些普遍的事实来源 - 一个存储数据的地方。这可以是 model(数据库访问层)或例如 service
  • 最后,您实际上并没有将引用的对象相互存储(缓存除外 - 优化性能)。您只需提供像$team->getPlayers() 这样的方法,它反过来会要求服务 提供正确的数据。当您致电$player->getTeams() 时,它会询问使用相同数据的相同服务,并且您没有任何差异。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
相关资源
最近更新 更多