函数参数是否违反封装?
Do function arguments violate encapsulation?
这个问题与一般的 OOP 实践有关。
假设我们有一个 class 和一个 public 函数接受从对象外部传入的参数。这本身不违反封装吗?另一方面,为什么这种做法被如此广泛地使用?毕竟 class 的构造函数和成员变量在调用函数时是一种 "by-passed" 。作为 OOP 的一个相对较新的程序员和我对封装的理解,我的函数参数通过 setter 传递到对象中,因此我只使用传入的成员变量来保留我的所有函数而没有任何参数。
我知道某些参数可以通过构造函数传入(顺便说一句,我使用依赖注入),但是如果这些参数在对象被实例化后发生变化怎么办?必须有一种方法可以在创建对象后更改这些值。到目前为止,除了使用 setter 来完成这项任务,我没有找到其他选择,但是在程序员之间长期以来一直在讨论 getter 和 setter 是 "evil" 或者至少被认为不是好的编程习惯。
谁能告诉我我错过了什么以及如何以干净的方式解决这个难题?
非常感谢您的支持。
这是一个使用 C# 的非常简单的具体示例:
我们在 windows 表单项目中有一个表单,其中包含 3 个文本框,分别命名为 textBox1、textBox2 和 textBox3。
任务是添加 textBox1 和 textBox2 的值,并使用 class 每当 textBox1 或 textBox2 的值发生变化时由事件处理程序实例化的 AddTextboxValues 将结果返回给 textBox3:
我经常看到的方式问是否违反封装:
public class AddTextBoxValues
{
public double TextBoxValueSum(double textBox1value, double textBox2Value)
{
return textBox1value + textBox2Value;
}
}
根据我对封装的理解,目前我是这样使用的:
public class AddTextBoxValues
{
private double textBox1Value;
private double textBoxValue2;
private double textBoxValue3;
public double TextBox1Value
{
set { textBox1Value = value; }
}
public double TextBoxValue2
{
set { textBoxValue2 = value; }
}
public double TextBoxValue3
{
get { return textBoxValue3; }
}
public void TextBoxValueSum()
{
textBoxValue3= textBox1Value + textBoxValue2;
}
}
这还有一个好处,就是可以将其注入到表单构造函数中。
非常感谢任何评论。
非常感谢 Jon Skeet,你是一位真正的专业人士。
您准确地诊断了我的问题,并因缺乏理解和找到解决我自己问题的知识而睁开了眼睛。确实是对封装和 "object state" 的更深入理解构建了我的拼图中缺失的一块。
现在对我来说一切似乎都合乎逻辑且清晰,我希望将来也能对其他人有所帮助。
这两个例子都不是面向对象编程。它们是过程式编程的例子。
首先 "class" 实际上只是一个 命名空间 包装 TextBoxValueSum
函数。
第二个 "class" 只是一个 结构 和 public 字段(getters-setter 和 public 字段之间没有区别)。
如果你想使用真正的面向对象编程,你应该想到对象,它们是 事物 的表示。
在你的情况下,我会写 class Sum
这是一个真实的东西,代表 一个具体的总和 :
class Sum {
private double a, b;
public Sum (double a, double b) { this.a = a; this.b = b; }
public double value() { return this.a + this.b; }
}
这个问题与一般的 OOP 实践有关。 假设我们有一个 class 和一个 public 函数接受从对象外部传入的参数。这本身不违反封装吗?另一方面,为什么这种做法被如此广泛地使用?毕竟 class 的构造函数和成员变量在调用函数时是一种 "by-passed" 。作为 OOP 的一个相对较新的程序员和我对封装的理解,我的函数参数通过 setter 传递到对象中,因此我只使用传入的成员变量来保留我的所有函数而没有任何参数。 我知道某些参数可以通过构造函数传入(顺便说一句,我使用依赖注入),但是如果这些参数在对象被实例化后发生变化怎么办?必须有一种方法可以在创建对象后更改这些值。到目前为止,除了使用 setter 来完成这项任务,我没有找到其他选择,但是在程序员之间长期以来一直在讨论 getter 和 setter 是 "evil" 或者至少被认为不是好的编程习惯。 谁能告诉我我错过了什么以及如何以干净的方式解决这个难题? 非常感谢您的支持。
这是一个使用 C# 的非常简单的具体示例:
我们在 windows 表单项目中有一个表单,其中包含 3 个文本框,分别命名为 textBox1、textBox2 和 textBox3。
任务是添加 textBox1 和 textBox2 的值,并使用 class 每当 textBox1 或 textBox2 的值发生变化时由事件处理程序实例化的 AddTextboxValues 将结果返回给 textBox3:
我经常看到的方式问是否违反封装:
public class AddTextBoxValues
{
public double TextBoxValueSum(double textBox1value, double textBox2Value)
{
return textBox1value + textBox2Value;
}
}
根据我对封装的理解,目前我是这样使用的:
public class AddTextBoxValues
{
private double textBox1Value;
private double textBoxValue2;
private double textBoxValue3;
public double TextBox1Value
{
set { textBox1Value = value; }
}
public double TextBoxValue2
{
set { textBoxValue2 = value; }
}
public double TextBoxValue3
{
get { return textBoxValue3; }
}
public void TextBoxValueSum()
{
textBoxValue3= textBox1Value + textBoxValue2;
}
}
这还有一个好处,就是可以将其注入到表单构造函数中。
非常感谢任何评论。
非常感谢 Jon Skeet,你是一位真正的专业人士。 您准确地诊断了我的问题,并因缺乏理解和找到解决我自己问题的知识而睁开了眼睛。确实是对封装和 "object state" 的更深入理解构建了我的拼图中缺失的一块。 现在对我来说一切似乎都合乎逻辑且清晰,我希望将来也能对其他人有所帮助。
这两个例子都不是面向对象编程。它们是过程式编程的例子。
首先 "class" 实际上只是一个 命名空间 包装 TextBoxValueSum
函数。
第二个 "class" 只是一个 结构 和 public 字段(getters-setter 和 public 字段之间没有区别)。
如果你想使用真正的面向对象编程,你应该想到对象,它们是 事物 的表示。
在你的情况下,我会写 class Sum
这是一个真实的东西,代表 一个具体的总和 :
class Sum {
private double a, b;
public Sum (double a, double b) { this.a = a; this.b = b; }
public double value() { return this.a + this.b; }
}