关于php:最好使用私有方法还是受保护的方法?

Best to use Private methods or Protected methods?

在我的许多PHP项目中,我最终得到的类具有我不打算扩展的非公共函数。

最好声明这些是受保护的还是私有的?

我可以从两个方面看到参数——使它们私有化是一种保守得多的方法,但是可以说,如果我希望扩展方法,并且它清楚地表明哪些方法是由基类扩展的,那么可以在以后对它们进行保护。

另一方面,在某种程度上使用私有的反社会的,因为它阻碍了理论上未来的开发人员在不修改的情况下扩展我的代码?


我的直觉是保持他们的隐私,直到你需要他们否则。

有人认为(可悲的是,我把链接放错了位置),将方法私有化是反社会的,这与将它们设为"最终"的方式非常相似,因为它对人们如何使用您的代码相当专横。

但是,我不相信,我同意你应该只公开你真正需要的东西。例外情况是一个库或工具箱,在这个库或工具箱中,您将期望用户希望(在一般意义上)以您永远无法预见的方式扩展您的代码。在这种情况下,使精心选择的方法受到保护可以看作是提供了弹性点。


我认为你应该只在需要的时候暴露你所需要的。这使得对变更进行影响评估变得更加容易。也就是说,如果一个方法是私有的,你知道如果你改变它,影响将是最小的。


就我个人而言,我觉得尽可能多地保密是合适的。我只查看每个方法,并问自己是否希望派生类能够调用它。使所有的东西都受到保护,这就为错误调用方法打开了大门。

我想归根结底就是"除非特别允许,否则一切都禁止"或者"除非特别禁止,否则一切都允许"。

另一个因素是很容易在将来的版本中使私有方法受到保护。一旦一个方法被保护起来,它就几乎不可能私有化,因为你永远不知道还有什么其他的代码会失效。


如果您打算为继承构建一个类,那么您必须这样设计它,即使那些方法受到保护,从而允许其他开发人员按照您想要的方式改变类的行为。简单地保护所有方法并不是一个很好的设计。请记住,所有受保护的方法都成为公共API的一部分,因此如果您稍后更改内容,将破坏其他人的代码。

一般来说,如果你不是为继承而设计,你应该禁止它。


我一般避免使用private。我的推理是,如果您在两个类之间有继承关系,并且存在私有成员,那么这就非常强烈地表明您应该将私有部分分解成一个单独的对象。


好吧,private关键字是有目的的。如果您不想让变量把继承的类弄乱(或者不想让人们在继承的类中与它们一起玩),那么为什么还要考虑让它们受到保护呢?

不要让别人碰你的私处:)


如前所述,如果您打算稍后扩展一个类,那么您可以随时更改它。

但是如果你可以避免使用继承,你应该这样做。如果可能的话,在设计时最好使用其他模式。

基本上,要做的是优先考虑组合而不是继承和程序到接口,而不是实现。

如果您只让类有一个严格定义的目的,那么您就不能组合对象,而不是让它们彼此继承。如果您使用接口而不是继承,那么您很可能会定义小而有效的接口。然后您将看到继承将减少,因此受保护的需求将减少到。

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
interface sound {
 public function makeSound();
}

class bark implements sound{
 public function makeSound() {
   return"Bark!!!";  
 }
}

class mew implements sound{
 public function makeSound() {
   return"Mewmew!!!";  
 }
}

class forLeggedAnimal {
  private $sound;

  public function forLeggedAnimal($sound){
    $this->sound = $sound;
  }

  public function eat(){
    echo $this->sound->makeSound();
  }

}

$cat = new forLeggedAnimal(new mew());
$dog = new forLeggedAnimal(new bark());

我知道这远非一个完美的例子。但它说明了该技术,您可以在许多方面使用它。例如,你可以将它与不同的创造模式相结合来建造猫和狗,也许不必知道猫是吠叫还是叫。但是无论如何…它不同于必须生成一个基类,然后用猫和狗扩展它,因此必须使"声音"方法受到保护或重写公共EAT方法。

彼得


如果您已经实现的函数是特定于类的,并且不应该在该类的上下文之外使用,那么就不允许它被继承。例如,如果我们有一个动物的等级,其中一个动物只有一个非常独特的东西,比如说"layeggsinsand()",就像一只乌龟。这对乌龟来说可能是独一无二的(乌龟,随便什么!)因此不应该被其他动物继承。在这种情况下,我们会说它是私有的。另一方面,如果函数是"walk()",那么它不是唯一的,因此它应该是可继承的。

一开始看起来很模糊,因为大多数时候事物都应该被继承,但是很少有情况下它们不应该被继承,因为它们是这种类型的独有。


我会声明这些方法是私有的。它清楚地表明它们不是公共API的一部分。

别担心将来会发生什么。


我通常在一些非常特殊的场合使用private,在这种情况下,方法/变量是非常内部的,不应该被任何其他子类读或写(所以基本上几乎从不读)。我使用private变量的唯一情况是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
final public function init():void
{
    if(!_initialized)
    {
        _init();
        _initialized = true;
    }

}

protected function _init():void
{
    // specific code.
}

在大多数其他情况下,方法和变量对于继承应该是有用的,至少作为一个读取函数。因为大多数时候,当我使用别人编写的代码时,当这个代码使用私密的东西时,总是会遇到很多麻烦:

  • 所需行为尚未实现或完成
  • 我不能使用方法,因为它是私有的
  • 我不能更改此方法,因为它是私有的
  • 如果它是受保护的(或者我把它改为受保护的),那么我就不能重写代码(也就是说,在两条指令之间添加行为,因为这段代码的一部分使用私有方法或变量…

    =在末尾,您几乎将所有访问器更改为protected,以获得扩展类的能力!

因此,如果您认为这个类可以被扩展,那么除了非常具体的情况外,所有的东西都优先受保护(如果您认为只应该使用一个特定的方法,而不应该更改,那么使用final protected)。

如果您认为在任何情况下都不应该扩展这个类:使用private。