关于C++中的访问器方法的几个问题已经被问到,但没有一个能够满足我对这个问题的好奇心.
我试图尽可能避免使用访问器,因为像Stroustrup和其他着名的程序员一样,我认为一个类很多都是OO的标志.在C++中,我可以在大多数情况下为类添加更多的责任或使用friend关键字来避免它们.但在某些情况下,您确实需要访问特定的班级成员.
有几种可能性:
1.根本不要使用存取器
我们可以公开相应的成员变量.这在Java中是不行的,但对于C++社区似乎没问题.但是,我有点担心的情况是一个显式副本或一个对象的只读(const)引用应该返回,是夸大了吗?
2.使用Java样式的get/set方法
我不确定它是否来自Java,但我的意思是:
int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount
Run Code Online (Sandbox Code Playgroud)
3.使用客观的C风格的get/set方法
这有点奇怪,但显然越来越普遍:
int amount(); // Returns the amount
void amount(int amount); // Sets the amount
Run Code Online (Sandbox Code Playgroud)
为了使其工作,您必须为您的成员变量找到不同的名称.有些人附加下划线,其他人加上"m_".我也不喜欢.
你使用哪种风格?为什么?
我目前在Qt等C++工作.我正在拥有具有私有数据成员和公共成员函数的类.我有班级中可用的数据成员的公共getter和setter.
现在我的问题是,如果我们的类中有数据成员的getter和setter,那么将这些数据成员设置为私有的重点是什么?我同意基类中的私有数据成员听起来合乎逻辑.但除此之外,拥有私人会员以及他们的吸气者和制定者对我来说似乎并不合乎逻辑.
或者我们可以将所有变量都公开,以便根本不需要getter和setter吗?拥有那些是一个好习惯吗?我知道让私有成员确保数据抽象,但让getter和setter实际上可以很容易地访问这些变量.欢迎任何关于此的指示.
我需要foo
在我的子类中为字段(我们称之为)编写自定义setter方法NSManagedObject
.foo
在数据模型中定义,Xcode分别自动生成@property
和@dynamic
.h和.m文件中的字段.
如果我像这样写我的二传手:
- (void)setFoo: (NSObject *)inFoo {
[super setFoo: inFoo];
[self updateStuff];
}
Run Code Online (Sandbox Code Playgroud)
然后我在调用时收到编译器警告super
.
或者,如果我这样做:
- (void)setFoo: (NSObject *)inFoo {
[super setValue: inFoo forKey: inFoo];
[self updateStuff];
}
Run Code Online (Sandbox Code Playgroud)
然后我最终陷入无限循环.
那么为NSManagedObject的子类编写自定义setter的正确方法是什么?
有没有办法在TypeScript中为属性设置私有的setter?
class Test
{
private _prop: string;
public get prop() : string
{
return this._prop;
}
private set prop(val: string)
{
//can put breakpoints here
this._prop = val;
}
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨getter和setter的可见性不匹配.我知道我可以设置支持字段,但是当设置值时我不能设置断点.
我虽然使用接口来隐藏setter,但是接口只能定义一个属性,而不是它是否在setter上有getter.
我在这里错过了什么吗?似乎没有任何理由不允许私有的setter,结果JS不会强制执行可见性,并且似乎比当前的替代品更好.
我错过了什么吗?如果不是,没有私人制定者的充分理由?
我无法理解C#语言中getter和setter的概念.在像Objective-C这样的语言中,它们似乎是系统中不可或缺的一部分,但在C#中并没有那么多(据我所知).我已经阅读过书籍和文章了,所以我的问题是,对于那些了解C#中的getter和setter的人,如果你将这个概念教给一个完整的初学者,你会亲自使用什么样的例子(这将包括几行代码尽可能)?
Allen Holub写了以下内容,
如果没有一些耦合,你就无法拥有一个程序.尽管如此,您可以通过盲目地遵循OO(面向对象的)规则来最大限度地减少耦合(最重要的是对象的实现应该完全隐藏在使用它的对象之外).例如,对象的实例变量(非常量的成员字段)应始终为私有.期.没有例外.永远.我是认真的.(您可以偶尔有效地使用受保护的方法,但受保护的实例变量是令人厌恶的.)
这听起来很合理,但他继续说,
你不应该出于同样的原因使用get/set函数 - 它们只是过于复杂的方式使字段公开(尽管返回完整对象而不是基本类型值的访问函数在返回对象的情况下是合理的class是设计中的关键抽象).
坦率地说,这对我来说听起来很疯狂.
我理解信息隐藏的原理,但是如果没有访问器和更改器,你根本就不能使用Java bean.我不知道如何在模型中没有访问器的情况下遵循MVC设计,因为模型不能负责渲染视图.
但是,我是一名年轻的程序员,而且我每天都在学习更多关于面向对象设计的知识.也许拥有更多经验的人可以在这个问题上权衡.
我如何使用set和get方法,为什么要使用它们?他们真的很有帮助吗?你也可以给我一些set和get方法的例子吗?
我正在尝试创建一个使用getter定义属性的抽象类.我想将它留给派生类来决定是否要为属性实现setter.这可能吗?
到目前为止我所拥有的:
public abstract class AbstractClass {
public abstract string Value { get; }
public void DoSomething() {
Console.WriteLine(Value);
}
}
public class ConcreteClass1 : AbstractClass {
public override string Value { get; set; }
}
public class ConcreteClass2 : AbstractClass {
private string _value;
public override string Value {
get { return _value; }
}
public string Value {
set { _value = value; }
}
}
public class ConcreteClass3 : AbstractClass {
private string _value;
public override string …
Run Code Online (Sandbox Code Playgroud) 到目前为止,我已经看到了两种在Java中设置变量值的方法.有时使用带参数的构造函数,其他setter方法用于设置每个变量的值.
我知道一旦使用"new"关键字对类进行实例化,构造函数就会在类中初始化一个实例变量.
但是我们何时使用构造函数,何时使用setter?
之前有一些关于StackOverflow的问题,质疑如何通过作用域链访问局部变量,比如你想用括号表示法和字符串引用局部变量,你需要类似的东西__local__["varName"]
.到目前为止,我还没有找到实现这一目标的最骇客的方法,并且在数小时利用我知道的每一招之后都没有提出一种方法.
它的目的是在任意非实现变量上实现getter/setter.Object.defineProperties或__defineGet/Setter__
要求调用上下文.对于全局或窗口上下文中的属性,您可以实现具有用于直接引用对象的setter/getter的目标.
Object.defineProperty(this, "glob", {get: function(){return "direct access"})
console.log(glob); //"direct access"
Run Code Online (Sandbox Code Playgroud)
即使在我与编译成一个改良的铬自定义扩展我之前的任何窗口创建,其内容具有实际全球范围内,甚至试图调用运行测试,this
直接在全球范围内崩溃我的程序,我能拉这一关没有一个障碍:
Object.defineProperty(Object.prototype, "define", {
value: function(name, descriptor){
Object.defineProperty(this, name, descriptor);
}
};
define("REALLYglobal", {get: function(){ return "above window context"; }});
Run Code Online (Sandbox Code Playgroud)
然后,它可以在以后创建的所有帧中作为通过指定的getter/setter路由的全局帧.旧的__defineGet/Setter__
也适用于该上下文而没有指定要调用它的内容(虽然在Firefox中不起作用,但上面的方法确实如此).
因此,基本上可以为对象上的任何变量定义get/set guard,包括直接调用对象的窗口/全局上下文(您不需要window.propname
,只是propname
).这是无法引用未填充的范围变量的问题,是唯一可以在可访问范围但没有可寻址容器的类型.当然,它们也是最常用的,所以它不是一个优势.这个问题也超越了ES6/Harmony中Proxies的当前实现,因为它是一个问题,特别是无法使用语言的语法来处理本地对象的容器.
我希望能够做到这一点的原因是,它是允许重载大多数数学运算符以用于复杂对象(如数组和散列)并导出复杂结果值的唯一障碍.如果在我为重载设置的对象类型上设置了值,我需要能够挂钩到setter.没有问题,如果对象可以是全局的,或者可以包含在父对象中,这可能就是我要用的东西.它仍然有用a.myObject
,但目标是尽可能透明地使用它.
不仅如此,能够完成这样的事情真的很有用:
var point3d = function(){
var x, y, z;
return {
get: function(){ return [x, y, z]; },
set: function(vals){ x=vals[0]; y=vals[1]; z=vals[2]; }
};
};
Run Code Online (Sandbox Code Playgroud)
(这与ES6的解构类似,但具有更多通用应用程序,用于实现获取/设置所附带的功能,而不仅仅是传输复杂的值).即使这个基本代码也会完全失败:
var x …
Run Code Online (Sandbox Code Playgroud) setter ×10
getter ×6
accessor ×2
c# ×2
c++ ×2
java ×2
closures ×1
constructor ×1
core-data ×1
immutability ×1
javascript ×1
local ×1
methods ×1
objective-c ×1
oop ×1
properties ×1
scope ×1
typescript ×1