我习惯于将我的所有类变量设为私有,并创建“包装”函数来获取/设置它们:
class Something{
private $var;
function getVar(){
$return $this->var;
}
}
$smth = new Something();
echo $smth->getVar();
我看到有很多人这样做,所以我最终做了同样的事情:)
以这种方式使用它们是否有任何优势:
class Something{
public $var;
}
$smth = new Something();
echp $smth->var;
我知道私有意味着你不能直接在课外访问它们,但对我来说,如果可以从任何地方访问变量,这似乎并不重要......
那么私有变量是否还有其他隐藏的优势?
答案 0 :(得分:4)
它被称为encapsulation,这是一件非常好的事情。封装使您的类与其他类混合使用它的内部,它们只能通过您的方法获得您允许的访问权限。它还可以保护它们免受您对类内部的更改。如果对变量的名称或用法进行更改,则不进行封装,该更改将传播到使用该变量的所有其他类。如果你强制他们通过一个方法,那么你至少有可能处理方法中的变化并保护其他类免受变化的影响。
答案 1 :(得分:3)
访问修饰符在脚本语言中没有多大意义。许多实际的面向对象语言(如Python或Javascript)都没有它们。
天真的getter / setter方法的流行仅仅是因为PHP没有提供明确的构造。 http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/
答案 2 :(得分:3)
如果您希望将私有变量与公共getter和setter一起使用,或者您只是想将变量直接声明为public,则情况会有所不同。
使用“getters”和“setter”可能是好的原因是,如果你想控制某人访问数据的时间。
举个例子,假设你得到了这个:
public setBirthday($date)
然后,您可以确保传递给该setter的日期是有效的生日。
但是,如果你只是将变量声明为像这样的公共
,则不能public $birthday;
根据评论。
另外,如果你决定改变 内部存储机制来自 包含日期的字符串 你自1970年1月1日以来的秒数 仍然可以在外部呈现日期 如果你使用同样的方式 封装,但如果暴露则不会 变量直接。每一块 触及内部的代码 直接变量现在将被打破。
这意味着如果内部存储机制从1970年1月1日起变为秒数,那么您不必更改“外部API”。原因是你可以完全控制它:
public getBirthday() {
// you can still return a string formatted date, even though your
// private variable contains number of seconds from 1/1/1970
}
答案 3 :(得分:2)
用于标记类的实现内部的变量,用于外部更改的变量。还有protected
个变量,供内部使用,并由类的扩展使用。
我们创建变量private
,以便只有类中的代码可以修改变量,保护外部干扰,保证变量的控制和预期行为。
答案 4 :(得分:2)
封装的目的是隐藏对象的内部结构与其他对象。这个想法是对象的外部足迹构成了它的定义类型,将其视为与其他对象的契约。在内部,它可能必须跳过一些环以提供面向外的功能,但这与其他对象无关。他们不应该弄乱它。
例如,假设您有一个提供销售税计算的课程。某种实用服务对象,基本上。它有一些提供必要功能的方法。
在内部,该类正在访问数据库以获取某些值(例如,给定管辖区的税),以便执行计算。它可能是在内部维护数据库连接和其他与数据库相关的事情,但其他类不需要知道这一点。其他课程只涉及面向外部的功能合同。
假设某个时候数据库需要用外部Web服务替换。 (该公司正在提供计算销售税的服务,而不是在内部维护它。)。由于该类是封装的,因此您可以更改其内部实现,以便非常轻松地使用服务而不是数据库。该课程只需要继续提供相同的外向功能。
如果其他课程与课程内部相关,那么重新实施它可能会破坏系统的其他部分。