在过去的几天里,我一直在尝试找出封装方法,并且想知道我的理解是否正确。
是当您创建类或结构,在类或结构内创建不希望其他类或结构访问的私有变量和方法,然后创建读取,写入或使用公共方法时的封装其他类或结构内部的私有变量和方法?
如果是,您为什么要这样做?您怎么知道何时使用它?与不使用封装相比,这有什么优势?如果可能的话,是否可以提供一些可以从封装中受益的“不良”代码的示例?
感谢您抽出时间阅读我的问题。
答案 0 :(得分:2)
要投入我的两分钱。
对于封装,基本上有两个原因。
您必须意识到,编写的代码不仅为您自己,而且还供其他人阅读和使用(他们无法更改您的代码),尤其是在创建库或框架时。当其他人使用您的班级/图书馆时,他们将不会想到您班级的所有实施细节。他们希望您的代码在直观使用时能够正常工作。
组织:
将相关信息放在正确的位置。例如,在c#List<T>
中有一个属性Count
,很自然地一直跟踪列表中有多少个项目,用户也可以问我列表中有多少个项目。 List
类应该负责对其进行跟踪,并且要容易得多。如果您不提供此属性怎么办。使用必须自己跟踪。每次您想知道列表中有多少项时,都必须编写重复的代码和逻辑以自己计算。当您在“列表”之外跟踪错误时很容易出错,在很多地方发生错误时也很难更改代码。Count
信息自然属于您的List
类,并且应该自然地保存在那里。每当您想知道计数时,只需询问您的List
对象。
保护:
为保护您的对象内部状态,请始终通过使用来纠正。
来自的相同示例。 “ Count”属性实际上是公共读取和私有写入。
当您实现Add
Remove
时,您会记得增加或减少Count
,您将记得保护Count
与列表中的多少项保持同步,并且永远不会低于0。想象一下,如果没有封装,一切都是公开的。 10年后用户或您自己不会Count = -100
做任何事情(相信我,十年后其他用户或您自己会这样做),那么您的List
对象将变得毫无意义。而且它将创建许多难以发现的错误,甚至造成真实单词的巨大损失,而永远不会低估程序的破坏程度
错误可以解决。
答案 1 :(得分:0)
封装用于更明确地定义类的[预期]行为。
假设您有一个Person
类,如下所示:
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
一个[真实的]人的年龄只会上升,所以为什么要允许任何人重新分配它呢?
相反,您可以封装年龄,使其必须遵循其预期的行为(以编写更多代码来处理分配/获取值的代价),如下所示:
public class Person
{
private int _age = 0;
public int Age { get => _age; }
public string Name { get; set; }
public void Birthday()
{
_age += 1;
}
}
这样,您可以保证年龄永远不会下降。