接口中不可能有实例变量或任何实现。但是我们可以有属性。属性不只是获取和设置方法吗?获取和设置方法不仅仅是获取和设置变量的方法吗?这不是作弊吗?据我所知,C++ 和 Java 不允许这样做。似乎 C# 中接口的实现并不那么“纯粹”。
4 回答
属性不只是获取和设置方法吗?
是的,他们是。他们是方法。行为,而不是关于如何实现该行为的实现细节。这就是属性和字段之间的区别——这就是接口中允许属性的原因。
获取和设置方法不仅仅是获取和设置变量的方法吗?
不,它们是方法。它们可以随心所欲地实施。它们可以通过简单的字段来实现——但它们可能不是。(你认为DateTime.Now
阅读哪个领域?)
据我所知,C++ 和 Java 不允许这样做。
Java当然允许您将getter和setter方法放在接口上......
您在接口中看到的不是具体的属性,它只是属性签名(例如,属性名称、返回类型访问修饰符,以及它是否具有 get 和 set)必须看起来像的定义在任何实现此接口的类中。
在接口中,它不是一个 get 和 set 方法,它根本不是一个实际的方法,它只是 get 和 set 方法在任何实现此接口的类中必须看起来的定义。
这听起来可能很微妙,但事实并非如此。这是一个巨大的区别。
我知道在抽象类中,我们指的是诸如
public abstract void Required(int a, string b);
作为抽象方法。我猜这是语义,这里所说的任何内容都不会改变普遍接受的用法,但它们(就像接口定义一样)实际上只是一个规范和对派生自此的类中方法签名的要求抽象类。
属性只是两个方法,包作为一个名称。通过在接口中定义一个属性(Name
例如),您实际上是在定义两个单独的方法(get_Name
和set_Name
)。您可以根据需要定义方法(get
和set
访问器)。通常您返回或设置字段的值,但这不是强制性的。
您可以通过定义两个单独的方法(例如)在 Java 或 C++ 中执行相同的getName
操作setName
。
接口中的属性,可能看起来像C# 自动实现的属性,但它们确实不同。当您定义这样的接口时:
interface IPerson
{
string Name { get; set; }
}
您正在强制接口实现者创建一个名为 的读/写属性Name
,但是当您在类中执行相同操作时:
class Person
{
public string Name { get; set; }
}
编译器自动创建一个支持字段来保存字符串值,并定义了两个从该字符串字段读取/写入的方法。
属性只是获取器和设置器,是的(您可以通过使用monodis
或ildasm
您的可执行文件来确认这一点,并看到它们只是方法。
所以接口中的属性只是抽象函数。无论您是否有支持领域都没有关系。支持字段(属于该属性的变量)本质上与属性本身无关。
所以不,属性不需要内存,也不是数据,它们的支持字段可能是,但属性本身不是数据。