假设我有一个 User 类
public Class User
{
public string Name { get; set; }
public string Surname { get; set; }
public int Level {get;set;}
}
User user1 = new User();
user1.Name = "name";
user1.Surname = "Surname";
user1.Level = 0;
User user2 = new User();
user2.Name = "name";
user2.Surname = "Surname";
Run Code Online (Sandbox Code Playgroud)
当我检查user1.Level == user2.Level它返回时,true因为默认int值是0.
那么有什么方法可以让我理解 Level 属性user2未设置,以便我可以说这两个不相同?
class My_Class:
def __init__(self):
self._x = 0
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
Run Code Online (Sandbox Code Playgroud)
如果我从上面的代码中删除以下 getter:
@property
def x(self):
return self._x
Run Code Online (Sandbox Code Playgroud)
代码停止工作。如何在没有 getter 的情况下创建 setter?
在Python中,我们可以使用@property装饰器来管理对属性的访问。例如,如果我们定义类:
class C:
def __init__(self,value):
self._x = value
@property
def x(self):
"""I'm the 'x' property."""
return self._x
Run Code Online (Sandbox Code Playgroud)
我们可以获取 x 的值,但不能更改它:
c = C(1)
#c.x = 4 # <= this would raise an AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)
但是,如果属性是可变类型(例如列表),我们可以为属性的位置设置不同的值:
c = C([0,0])
c.x[0] = 1 # <= this works
Run Code Online (Sandbox Code Playgroud)
有办法预防吗?如果 x 是一个列表,我希望能够仅使用 C 类的方法来更改 x 位置的值。
我无法理解为什么 getter/setter 方法的名称必须与属性具有相同的名称。
我尝试在这里阅读亚伦·霍尔的答案,但我仍然找不到(或错过了)关于为什么我们必须使用各自名称的解释。
class Car(object):
def __init__(self, color='blue'):
self.color = color
self.current_model = 'Opel'
@property
def model(self, new_model):
return self.current_model
@model.setter
def model(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
# model = model.setter(models) but doing this works
@model.getter
def model(self):
return self.current_model
Run Code Online (Sandbox Code Playgroud)
编辑: 我发现令人困惑的是,如果我将方法重命名为:
@model.setter
def model_new(self, new_model):
if new_model == 'Audi':
raise ValueError ('NO AUDI ALLOWED')
else:
self.current_model = new_model
Run Code Online (Sandbox Code Playgroud)
我尝试运行:
audi = Car()
audi.model = 'BMW' # …Run Code Online (Sandbox Code Playgroud) 修改setter参数是否正常?让我们假设我们有setString方法.我们真的想保留一个修剪过的字符串形式.所以带尾随空格的字符串无效,但我们不想抛出异常.
什么是最好的解决方案?修剪设定器中的值,例如
public void setString(String string) {
this.string = string.trim();
}
Run Code Online (Sandbox Code Playgroud)
或者在调用者中修剪它(不止一次),例如
object.setString(string.trim());
Run Code Online (Sandbox Code Playgroud)
或者别的什么?
为什么Wrapper类(如Integer,Double等)没有内部原始值的setter是什么原因?
我问这个是因为这种功能会简化微积分,并使Java语言更灵活一些.
让我举几个例子.
1)我们来看下面的例子:
Integer x = new Integer(5);
x++;
Run Code Online (Sandbox Code Playgroud)
幕后的前一个代码是执行自动装箱.就像是:
int x_tmp = x.intValue();
x_tmp++;
x = new Integer(x_tmp); // Yes that's a new memory allocation
Run Code Online (Sandbox Code Playgroud)
由于这个问题,在Wrapper上执行微积分比在普通原始类型上执行要慢.使用setter,可以更容易地增加内部值,而无需在堆上分配另一个对象.
2)另一个困扰我的问题是,在Java中编写交换函数是不可能的,就像我在C(使用指针)或C++(指针或引用)中所做的那样.
如果我写,void swap(Integer x, Integer y)我无法访问内部值因为,并且我将无法交换值.
PS:我的一个朋友建议我应该考虑更大的图景,并考虑并发性和类型不变性.
所以你有解释吗?谢谢!
我想知道我们是否可以在Delphi中这样做:我有一个私有程序:
procedure SetMySend(const oValue: TTM_MySend_Profile;
displayValue: string = '...');
Run Code Online (Sandbox Code Playgroud)
我有一个公共财产:
property MySend: TTM_MySend_Profile displayLocateID '...'
read FMySend write SetMySend;
Run Code Online (Sandbox Code Playgroud)
我可以在这里给一个参数displayValue作为setter的第二个参数吗?我不能得到这个编译.
我无法弄清楚这样做的正确方法,并想知道我是否可以在Delphi中做到这一点.感谢帮助!
我会尽量保持简短.
我有许多实例变量(30+)的类,因此有许多getter/setter.这些类本身很简单,但由于getter/setter,LOC刚刚爆炸(并且还有太多的代码口号).
所以我删除了属性并将它们存储在地图中,就像这样
public class MyTechnicalToolClassX
{
//...constructor
private Map<String, Object> data;
public Object getAttributeByKey(AttributeKey key)
{
// ...doStuff, check data associated with key, etc
// if (predicate == true) return otherData;
return data.get(key.toString());
}
public void setAttributeByKey(AttributeKey key, Object value) throws IllegalArgumentException
{
if(key.getType().isInstance(value))
{
data.put(key.toString(), value);
}
else
{
throw IllegalArgumentException("The passed value has the wrong type, we expect: "
+ key.getType().getName());
}
}
public enum AttributeKey
{
someKey1("key1", String.class),
someKey2("key2", Date.class),
//...
someKeyN("keyN", SomeType.class);
private String key; …Run Code Online (Sandbox Code Playgroud) if send用于调用带符号的方法(属性为getter方法)
访问setter方法的相反之处是什么?
object.send(:attr) 是的 object.attr
如
______ 是object.attr = value
对不起比喻,我不知道如何更好地解释这一点
所以我对OO编程有点新意.Delphi的属性旨在成为获取类数据的"更优雅"方式,而不是getter/setter(在此处读取业务类中属性vs getter/setter的使用).
我应该何时直接使用这些字段,何时应该在属性中使用getter/setter?我只是在需要操纵数据时才会说话,但我不确定.
编辑:
省略一个除了返回字段本身值之外什么都不做的setter是错误的吗?
property Field :integer read FField write FField;
Run Code Online (Sandbox Code Playgroud) setter ×10
getter ×6
properties ×5
python ×3
delphi ×2
java ×2
c# ×1
class ×1
default ×1
equality ×1
immutability ×1
mutable ×1
parameters ×1
python-3.x ×1
ruby ×1
wrapper ×1