如果我们可以通过setter和getters访问私有成员那么private的用途是什么?
答案 0 :(得分:3)
您需要私有来强制执行封装。它是面向对象编程的基本范例之一,用于保持与接口分离的实现。这减少了不同程序部件之间的耦合,并且从长远来看使其更易于维护。
采用以下示例:
class toto {
private String someThing;
public String getSomething();
public void setSomething(String Something);
}
如果你改变上面只是简单地把someThing公开,确定你有更少的代码,但是如果有一天someThing需要更改为更复杂的对象以获得某些新功能,而旧代码仍可以使用字符串正常工作那么你需要改变一切。通过隔离someThing的内部表示,您可以更轻松地改进系统
class toto {
private ComplexSomeThing someThing;
public String getSomething(){ someThing.toString();}
public void setSomething(String something){ something = new ComplexSomeThing(something);}
public ComplexSomeThing (getComplexSomething();
public void setComplexSomething(ComplexSomething someThing);
}
还有其他原因使封装成为一件好事(tm),这只是一个愚蠢的例子来说明这一点。
EDIT 现在对于使用protected vs private或使用类似于某些语言(Delphi,C#)中的属性的概念而不是getter和setter(如Java中)存在一些争论。 受保护而非私有将允许代码的客户端更容易地更改,但它确实暴露了系统的内部,因此在API的可用性和可维护性之间存在平衡。然而,封装的基本原则仍然存在。 无论选择何种选项,人们仍然需要公开连贯的功能,并且在相同的抽象层次上,并隐藏如何完成这一过程的血腥细节。
对我来说,争论的目的不是宣称对私人进行圣战,而是要找到一种方法来提供可扩展性和灵活性,同时又不破坏API的连贯性。
Here some interesting如果您想进一步深入了解私人话题。但是我必须强调,在形成关于私人的观点之前,你应该真正掌握encapsulation和polymorphism的概念,它们显而易见的简单性确实隐藏了一些微妙的complexities。
答案 1 :(得分:1)
因为getter和setter可以充当代理。它们使得您可以隐藏类的实际内部,并且只允许外部类通过方法访问数据。允许你按照自己的意愿对待课程内容。
仅仅因为你的getter / setter被命名为getName()
并且你的属性被称为name
,并不意味着它总是那样。
如果您想将变量更改为fullName
,该怎么办?如果直接访问公共变量,则更改会破坏大量代码。相反,您只需重新映射getName()
从中检索数据的位置。
我最好的一个例子是我自己的URL类,我允许创建和操作URL。如果要设置方案,可以获得$obj->setScheme()
。但是,您不知道我是否每次更改URL时手动创建字符串,无论我是将它们存储为单独的部分。这给了我灵活性,因为我可以存储你想要的数据。
此外,我可以在存储之前对数据进行操作。在我的URL类中,我假设所有方案和主机名都是小写的。我可以通过将通过setHost()
保存的所有字符串转换为小写,然后存储它们来标准化。如果我使用了公共变量,则必须假设放入数据的客户端正确存储它。
他们还可以验证传入的信息以确保它是有效数据,如果不是,则会导致错误。
答案 2 :(得分:1)
没有人强迫你为每个变量输入getter和setter。确实,盲目地使用私人成员+虚拟吸气剂&每个变量的setter都是没有意义的,尽管许多“面向对象的封装”教程由于某种原因一直这样做。首先,这种封装是从并发角度看的 no 封装。
答案 3 :(得分:0)
我认为你真正想要理解的是为什么我们将公共属性与私有支持字段一起使用,而不是仅仅使用公共字段。这样有几个问题;这是一个:
What is the difference between a Field and a Property in C#?
答案 4 :(得分:0)
到目前为止,我认为你有很好的答案(信息隐藏和所有这些)。只想添加一个关于使用setter的建议。
正如您所提到的,使用访问器使私有变量有点无意义,在某些环境中,使用getter和setter的性能后果只会使它变得毫无价值。
另一方面,如果你没有这样的担忧,我认为使用getter并不是那么糟糕,但是在使用setter之前你应该三思而后行。它们使您的对象可变,这在并发环境中尤其难以维护。