【问题标题】:Why use getters and setters [duplicate]为什么使用 getter 和 setter [重复]
【发布时间】:2010-02-12 14:49:35
【问题描述】:

可能重复:
Why use getters and setters?

为什么要使用 getter 和 setter?

【问题讨论】:

  • 只有我,还是其他人看到这个问题最初带有自己的答案 [encapsulation] 的讽刺意味?
  • 我已经回滚到原来的问题。应该用新问题提出新问题,而不是用现有问题完全替换它。
  • 令人惊讶的是,连被骗的主题标题都一模一样。另一个证据 OP 根本没有搜索或查看“相关主题”列表。
  • 问题的措辞不完全正确,但它是一个有效的问题。

标签: encapsulation


【解决方案1】:

限制对对象内部状态的访问。

考虑一类几何形状的经典示例。比如说,一个 Circle 对象。当您设置半径时,您可能希望自动计算面积(这将是一个只读属性)

class Circle
{
     float radius;

    public float Radius
    {
        get { return radius; }
        set { radius = value;  area = Math.Pi * radius * radius;}
    }

    float area;
    float Area
    {
        get { return area;}
    }
}

如果您允许直接访问“radius”数据成员,则当它更改时您无法更新area。此外,如果您允许直接访问 area,用户可以随意更改它而不考虑 radius。

【讨论】:

  • 如果radius 和area 有单独的字段,则并非所有字段值组合都有效。另一方面,如果要定义Area 属性来计算并返回圆的面积,那么Radius 可以替换为一个字段并且写入它会“改变”Area .在实际情况下,最好定义结构的语义,以使所有可能的字段值组合都有效,而不是设计不是这种情况的结构。
【解决方案2】:

封装,这样你就可以如何在你的类中存储数据一个实现细节。如果您的班级有 getter/setter:

private string _mystring = string.Empty;
public string SomeValue
{
 get
 {
   return _mystring;
 }
}

这使您可以更改将来管理“SomeValue”的方式。例如,您可能决定不将其存储在字符串中,而实际上将其作为引擎盖下的 Guid。现在你可以去:

private Guid _myguid= Guid.NewGuid();
public string SomeValue
{
 get
 {
   return _myguid.ToString();
 }
}

使用您的类并访问“SomeValue”属性的任何地方都将以这种方式保持不变。

验证

你也可以验证传入的值,所以在另一个例子中:

private string _mystring = "My Value";
public string SomeValue
{
 get
 {
   return _mystring;
 }
 set
 {
   if (string.IsNullOrEmpty(value))
   {
     throw new InvalidArgumentException();
   }
   else
   {
     _myString = value;
   }
 }
}

确保存储的字符串永远不会设置为空/空字符串

【讨论】:

    【解决方案3】:

    封装。

    【讨论】:

      【解决方案4】:

      如果您将一个字段设为私有并设置一个 getter 和一个 setter 来访问它,那么所有其他代码都必须通过这些方法来获取该数据。然后,您有更多的控制权。

      • 您可以将其设为只读(无 setter)。
      • 您可以在 setter 中验证输入,如果不可接受则拒绝它。
      • 只有在需要时,即首次调用 getter 时,才能实例化对象。
      • 您可以稍后更改其工作方式。

      如果您严格使用 getter 和 setter 来访问该字段,您也可以在类中获得这些相同的好处。所以对于很多人来说,这是他们一直在做的事情。

      Getter 和 setter 最初看起来不太好,因为它们看起来需要大量额外的输入。但是,如果您愿意,像 Eclipse 这样的 IDE 可以自动为您创建 getter 和 setter。像 Objective-C 和 Ruby 这样的语言也可以使用缩写语法来做到这一点。 C# 可以将 getter 和 setter 包装在“属性”中,它们在代码中就像字段一样使用,但在底层它调用您编写的 getter 和 setter。

      所以有很多理由使用 getter 和 setter,还有很多设施可以减轻痛苦。

      【讨论】:

      • 绝妙的答案加上我不知道属性在 Obj-C 之前的 C# 中!
      【解决方案5】:

      一个原因是在某些语言中为对象提供更统一的接口——您不再需要处理字段和方法之间的语法差异;你总是处理方法。

      第二个原因是您隐藏了对象的实现,允许您在内部更改它而不影响其客户端。一个经典的例子是坐标之一 - 如果您有一个通过笛卡尔坐标表示的坐标,并将内部表示切换为极坐标,如果您使用 getter 和 setter,即使 x 和 y 字段消失,您的程序仍然可以工作。这也允许您使用多态性——两个对象代表相同的抽象,但每个对象的状态实现不同。

      通过方法访问状态还可以让您添加同步等内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-09
        • 2012-08-25
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        • 2014-12-20
        • 2023-03-09
        • 2014-02-23
        相关资源
        最近更新 更多