使用getter和setter的优点是什么 - 只能获取和设置 - 而不是简单地使用公共字段来存储这些变量?
如果getter和setter做的不仅仅是简单的get/set,我可以非常快地解决这个问题,但我并不是100%清楚如何:
public String foo;
Run Code Online (Sandbox Code Playgroud)
更糟糕的是:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
Run Code Online (Sandbox Code Playgroud)
而前者需要很少的样板代码.
我目前正在开发一个简单的Java游戏,有几种不同的模式.我扩展了一个主要的Game类,将主要逻辑放在其他类中.尽管如此,主要的游戏类仍然非常沉重.
在快速浏览一下我的代码后,其中大部分是Getters and Setters(60%),而其余部分则是游戏逻辑真正需要的.
一些谷歌搜索声称Getters和Setters是邪恶的,而其他人声称他们是良好的OO练习和伟大的程序所必需的.
所以我该怎么做?应该是哪个?我应该为我的私人变量更改我的Getters和Setter,还是应该坚持使用它们?
我原来是来自C#的世界,我正在学习C++.我一直想知道在C++中获取和设置函数.在C#中,这些使用非常流行,而像Visual Studio这样的工具通过使它们变得非常容易和快速实现来促进使用.但是,在C++世界中似乎并非如此.
这是C#2.0代码:
public class Foo
{
private string bar;
public string Bar
{
get { return bar; }
set { bar = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
或者,在C#3.0中:
public class Foo { get; set; }
Run Code Online (Sandbox Code Playgroud)
可能人们会说,那是什么意思呢?为什么不创建一个公共字段,然后在需要时将其变为属性; 老实说,我其实不确定.我只是出于好的做法,因为我已经看过很多次了.
现在因为我已经习惯了这样做,我觉得我应该把习惯延续到我的C++代码中,但这真的有必要吗?我没有像C#那样频繁地完成它.
无论如何,这是我收集的C++:
class Foo
{
public:
std::string GetBar() const; // Thanks for the tip Earwicker.
void SetBar(std::string bar);
private:
std::string bar;
}
const std::string Foo::GetBar()
{
return bar;
}
void Foo::SetBar(std::string bar)
{
// Also, I always wonder if using 'this->' is good …Run Code Online (Sandbox Code Playgroud) 我是PHP的新手.出于某些原因,在其他类型的编程语言(如JAVA)中,我对使用每个变量的setter和getter没有任何问题,但是当我在PHP编程时可能因为它非常灵活,感觉有点浪费时间.在大多数时候将类属性设置为公共并且像这样操纵它们感觉更简单.问题在于,当我这样做的时候,我觉得我做错了什么并且反对OO原则.
不使用setter和getter真是错吗?为什么或者为什么不?大多数时候你们是如何做到的?
是否有一个良好的,没有,一个非常充分的理由,要通过使用getter和setter方法的面向对象语言的所有麻烦吗?使用对属性或方法的直接引用有什么问题?人们不想在礼貌的公司谈论某种"语义掩盖"吗?当有人走出去说"你应该写大量的代码以获取吸气剂和制定者"时,我是否太累了并且睡着了?
一年后的后续行动:
它似乎是Java的常见现象,而不是Python. 我开始怀疑这是否更像是一种文化现象(与语言的局限性有关),而不是"圣人的建议". 由于我不使用Java编程(目前可供选择),因此无法进行评估.
就我而言,目前(截至本文写作2010-03-22)-1问题得分已经完成了lulz.有趣的是,有一些特定的问题被低估了,不是因为它们是"坏问题",而是因为它们触及某人的原始神经.
那么让我们来解决问题.我重复一遍:
What's wrong with just using a direct reference to a property or method?
这是不成文的推论:
Are we so undisciplined as programmers that we can't keep our hands off of things that are clearly marked "no touchy"?
我有一个类'数据',它使用getter访问某些数组.如果数组为null,那么我希望Data访问该文件,填充数组,然后返回特定值.
现在这是我的问题:
在创建getter和setter时,您是否也应该使用相同的访问器属性作为访问该阵列的方式(在本例中)?或者你应该直接访问数组?
我在类中使用访问器的问题是,当调用类在Data.array中查找某些信息时,我得到无限循环,getter发现数组为null,所以从文件中获取它,并且该函数结束再次从Data中调用getter,数组再次为null,我们陷入无限循环.
编辑:
那么对此没有官方立场吗?我看到不使用具有文件访问权限的Accessors的智慧,但是你们中的一些人说要始终在类中使用访问器,而其他人则说从不使用类中的访问器......... ...................................
根据这些评论编辑:
你的意思是"财产"与"战场"吗?public String S1; vs public String S2 {get; 组; } - 达娜
完全是达娜,我的意思是一样的.- 阿萨德
阿萨德:你真的需要尝试用其他术语来描述你的意思,这样我们才能更好地理解你的问题.C#没有全局变量.您可以在C#中定义的字段不是全局的 - 它们是类类型的成员.- dthorpe
嗨fellas,
需要您对Fieldand 之间差异的专家意见Property.在我的项目中,我使用了某些全局变量,后来我改为"属性".我的经理问的是使用Properties变量代替的好处是什么Fields.
虽然我回复了他Property提供了一种安全/安全/间接访问,Field而不是直接修改它们,如果它们被声明public或protected.但请给我一些更有说服力的论据.
感谢致敬
@Asad:你应该把你的术语说得对:Fields不是Global Variables,C#没有全局变量(正如一些评论者提到的:你可以模拟全局变量,但你不应该这样做).
我可以用2种方式调用变量.
一个就是这样做:
MyClass myClass = new MyClass();
myLocalVar = myClass.myVarVal;
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用这样的getter:
myLocalVar = myClass.getMyVarVal();
Run Code Online (Sandbox Code Playgroud)
两种方式都运行良好,但我想知道最有效/最合适的方法是什么?
谢谢
如果我们谈论域对象,为什么setter在接口上是坏的?
澄清:
我有一个存储在db中的域对象.它有几个领域,设置成本很高.即
class JurasicPark {
private long area;
...other fields ...
getters and setters
....
private Collection<Dinosaur> dinosaurs;
private Collection<ExoticTree> flora;
public Collection<Dinosaur> getDinosaurus(){
...
}
public Collection<ExoticTree> getFlora(){
...
}
}
Run Code Online (Sandbox Code Playgroud)
字段dinosaurs并且flora初始化和设置成本非常高.但在许多情况下,我不需要每次都设置这个字段.
问题是,如果我返回到JurasicPark类的用户实例,dinosaurs或者flora没有初始化它,那么填充导致NPE或我自己投掷的一些预期.我不想让api用户考虑这个并记住哪些字段可能没有设置.
因此,为了解决这个问题,我考虑创建两个接口IJurasicPark,IFullJurasicPark第一个将所有访问方法声明为简单字段,前者将声明访问方法flora和dinosaurs字段.
interface IFullJurasicPark extends IJurasicPark
class IJurasicPark implements IFullJurasicPark
Run Code Online (Sandbox Code Playgroud)
在这种方法中IJurasicPark接口将包含getter和setter,所以我实际上问这个设计是不是很糟糕?
我也不想在使用LazyInit异常的hibernate风格中实现它.