面向对象概念:字段、属性和方法 您所在的位置:网站首页 什么是职业属性的概念 面向对象概念:字段、属性和方法

面向对象概念:字段、属性和方法

2024-07-03 14:57| 来源: 网络整理| 查看: 265

1、字段和属性的概念和区别

      字段:一个成员,它表示与对象或类关联的变量

     在面向对象里,属性表示的是一个对象的状态,既然是状态那么肯定是用来获取或设置的。

     在Java里,为了避免外界对属性的直接访问,从而建议程序员对于每个属性,都应该提供getter和setter来保护。      在C#里,为了更直接和方便的处理属性这一字段,从而提供了“属性”这一特殊语法,当然也必须提供getter或setter:

     C#中, 属性语法提供灵活的机制来读取,编写或计算私有字段的值。属性是一种用于访问对象或类的特性的成员。属性是成员的自然扩展,二者都是关联类型的命名成员。

     在C#中,我们可以非常自由的、毫无限制的访问公有字段,但在一些场合中,我们可能希望限制只能给字段赋于某个范围的值、或是要求字段只能读或只能写,或是在改变字段时能改变对象的其他一些状态,这些单靠字段是无法做到的,于是就有了属性,属性中包含两个块:set和get,set块负责属性的写入工作,get块负责属性的读取工作。    在两个块中都可以做一些其他操作,如在set中验证赋的值是否符合要求并决定是否进行赋值。当缺少其中一块时属性就只能读或只能写,set和get块中属性必需有一个,因为即不能读又不能写的属性是没有意义的。

C#代码:

class X { private int a; public int A { get { return a; } set { a = value; } } static void Main() { X x = new X(); x.A = 1; int i = x.A; } } x.A = 1; // 看起来像是给一个字段赋值,但其实还是调用了setter int i = x.A; // 同样通过getter来把值赋值给i

    C#的属性提供灵活的机制来读取,编写或计算私有字段的值。

    c++本身并不直接支持严格支持严格意义上的属性语法和规则,因此可以认为C++默认不支持属性机制。当然,     C++同样可以通过实现set和get成员函数,来获取或设置对象的状态。

C++代码:

class X { public: void setA(int i) { a = i; } int getA() { return a; } private: int a; };       上面的代码里,c++只是函数模仿,而属性本身是可以作左值的,函数实现方式不能是左值.也只是按照Java那样的风格来写的getter和setter;C#支持属性机制,让一个变量看起来像左值,但其实还是调用了方法。

   公共字段只是类用public修饰符所公开的简单公共变量,而属性则是对字段的封装,它使用get和set访问器来控制如何设置或返回字段值。

   由于属性的实质是方法(get或set方法)。所以对于开发过程中常用的赋值和取值操作来说,使用公共变量肯定会比使用属性速度要快,性能上也稍高(方法和变量哪个速度不用说了吧)。

    公共字段虽然在速度上快,但它必须开放字段为public,这样一来对象的调用者便可以直接修改其值,值的内容是否合法,运行中是否会出错,就没有了保障,进而会大大降低类的可重用性;相反,属性类似于方法,它可以对存入的变量的值进行处理,如果觉得该值不合法,可以就地变换或者直接提出警告。这对该类的对象的使用安全有很大好处,在运行过程中,因公共变量值的错误而产生的问题会大大减少。

    从上述内容来看,两者各有优缺点,在实际项目开发过程中,我们究竟选择使用哪一种方式呢?

    如果满足下面几个条件,那么我们便可以大胆地使用公共字段:

1. 允许自由读写;

2. 取值范围只受数据类型约束而无其他任何特定限制;

3. 值的变动不需要引发类中其它任何成员的相应变化;

属性的使用条件则恰好跟变量相反,只要满足下面任何一个条件,就应该使用属性:

1. 要求字段只能读或者只能写;

2. 需要限制字段的取值范围;

3. 在改变一个字段的值的时候希望改变对象的其它一些状态;

     总结:虽然在实际项目的开发过程中,公共字段和属性在合适的条件下都可以使用,但是我们应该尽可能的使用属性(property),而不是数据成员(field);把所有的字段都设置为私有字段,如果要暴露它们,则把它们封装成属性,这也是微软推荐的方式。

    一般来说对于标准C++而言是不存在成员属性这个概念的,以前大家都是用GetXXX/SetXXX来访问或取得数据,好象也没有感觉到任何不便。但是当我们用过C#之类的语言之后,我们总觉得C++这个方式太老土了。于是我们想去实现“属性”这个C++语言缺乏的要素。 

(1)为什么需要属性?请看如下C++代码:

 class CEmployee   {   public:   int Old; //年龄   };   CEmployee employee;   employee.Old=22;   int old =employee.Old;

它有一个成员变量,我们可以直接对它们进行赋值或者读取,但是往往会缺少一个很重要的东东,就是不能对所赋值进行校验,这可是个大问题,比如我们给 Old一个负值,比如-50,提示程序运行时不会有任何错误,但是的确这个成员变量的值在逻辑上是不正确的。于是我们会写上GetOld、SetOld。现在OK了,这个小问题解决了,但新问题来了。我们的类使用者,他们需要重新把他们的代码成写如下的样子,而不是上面的那样。

CEmployee employee;   employee.SetOld(22);   int old =employee.GetOld(); 你的伙伴一定会在写代码时诅咒你写了一个垃圾的类。所以你决定要改变这个现状。

我们可以通过定义宏的形式来实现:

//简化属性性定义的宏 //定义读写属性 #define PROPERTY_DECLARE_RW(property_name, type, class_type, set, get) / ReadWriteProperty property_name; //定义只读属性 #define PROPERTY_DECLARE_R(property_name, type, class_type, get) / ReadProperty property_name; //定义只写属性 #define PROPERTY_DECLARE_W(property_name, type, class_type, set) / WriteProperty property_name; #define INIT_PROPERTY(property_name) property_name.SetObj(this); #endif//PROPERTY_H //定义读写属性 #define PROPERTY_DECLARE_RW(property_name, type, class_type, set, get) /     ReadWriteProperty property_name; //定义只读属性 #define PROPERTY_DECLARE_R(property_name, type, class_type, get) /     ReadProperty property_name; //定义只写属性 #define PROPERTY_DECLARE_W(property_name, type, class_type, set) /     WriteProperty property_name; #define INIT_PROPERTY(property_name) property_name.SetObj(this); #endif//PROPERTY_H

具体实现可参考文章: http://blog.csdn.net/pankun/article/details/594274 (给C++添加属性机制)

那么,我们支持属性机制的C++代码可写成如下:

class CEmployee  { private: int Salary; public: CEmployee(int Salary) { INIT_PROPERTY( Salary ); this->Salary = Salary; } void SetSalary (const int& Salary) { cout


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有