本文描述内容转载 https://zhidao.baidu.com/question/1174413218458798139.html 感谢 冥冥有你PD 的解答!!!

问题思索1

类成员包括变量和方法。如果希望其他类能够访问成员变量的值,就必须定义成公有的,而将变量设为公有public,那这个成员变量的就可以被任意访问(包括修改,读取),这样不利于数据安全。那怎么办呢?

解决方案

1.C#通过属性特性读取和写入字段(成员变量),而不直接直接读取和写入,以此来提供对类中字段的保护。

2.属性可用于类内部封装字段。属性是C#面向对象技术中封装性的体现(注意:字段就是类的成员变量,为配合属性而这样称呼的)

属性和字段的区别

1.属性是逻辑字段;

2.属性是字段的扩展,源于字段;

3.属性并不占用实际的内存,字段占内存位置及空间。

4.属性可以被其它类访问,而类中大部分字段不能直接访问。

5.属性可以对接收的数据范围作限定,而字段不能(也就是增加了数据的安全性)最直接的说:属性是被“外部使用”,字段是被“内部使用”。

问题思索2

要属性这种华而不实的东西做什么?为什么不直接放一个public字段?

class Card
{

  public string Name;    //而非要做一个private字段+public属性?
}

#region ClassStart***************************************************

class Card{

  private string name;
  public string Name{

  get { return this.name;}

  public string sex;

}

  //声明一个类去使用User类

  class Property{

    static void Main(){

    //实例化一个张三User对象

    User zs = new User();
    //对其赋值

    zs.name = "张三";

    zs.sex = "男";

    Console.WriteLine("姓名:" + zs.name + "性别:" +zs.sex);

  }
}

#Endregion ClassEnd***************************************************

通过编译执行,这段代码正常运行,这个程序乍看一下感觉没有什么问题。但是仔细分析,就会发现:所有字段都是公有的,不利于字段的保护,只要实例化了这个类,都可以修改其中的值。

如果性别输入了男女之外的字符,系统是不会识别的。比如把zs.sex = "男";改成zs.sex = "牛";

运行代码结果肯定张三的性别成牛了...这个时候就不合逻辑了。现在大家可以明显的感觉到User类的封装非常不合理,存在着非常大的缺陷,那么该如何修改呢?这个时候大家马上会想到是不是可以专门声明一个方法给性别赋值呢,

#region ClassStart***************************************************

using System;

class User

{

  public string name;
  public string sex;
  //SetSex方法

  public void SetSex(string values)

  {if (values == "男" || values =="女") {
    sex =values;}

  else{

    Console.WriteLine("性别只能为“男”或“女”"); }

  }

}

class Property

{

  static void Main() {

  User zs = new User();
  zs.name = "张三";

  //直接调用SetSex赋值

  zs.SetSex("牛");

   Console.WriteLine("姓名:" + zs.name + "性别:" +zs.sex);

  }
}

#Endregion ClassEnd***************************************************

SetSex这个方法乍一看还可以,但是不要忘记name和sex字段还是public属性,我们依然可以直接去调用它,或者说去修改它,一样可以把sex设为“牛”。

给类的字段设置为public意味着破坏了类的封装,这样会存在潜在的危险。所以要设为private,这个时候就分别声明方法去读取和设置这2个字段。

#region ClassStart***************************************************

using System;

class User{

  //设为私有的

  private string name;
  private string sex;
  //设置

  public void SetName(string values){

    name = values;

  }

  //读取

  public string GetName(){

    return name;

  }

  public void SetSex(string values)

  {if (values == "男" || values =="女") {
    sex =values;

  }

  else{

    Console.WriteLine("性别只能为“男”或“女”");

   }

}

  public string GetSex(){

    return sex;

  }

}

class Property{

  static void Main(){

    User zs = new User();

    zs.SetName("张三");

    zs.SetSex("牛");

    Console.WriteLine("姓名:" + zs.GetName() +"性别:" +zs.GetSex());

  }
}

#Endregion ClassEnd***************************************************

现在这个类的设计就比较合理了,我们看name和sex它们是private字段,也就是说在类的外部是不能访问的,这样呢就保证了它的安全性。

当用户想给性别字段添加非法字段的时候,SetSex方法内会对这个添加的值进行判断,如果不为男或女,值就不会被添加。

通过方法虽然解决了上面的问题,但是每创建一个对象,输入字段值时就必须调用上面方法。

如果不知道,就无法调用。关键是不够简便。为了提高数据安全性,并且有效解决上面的问题。

C#推出了属性。可以创建属性,将字段和属性封装在一起。通过属性可以像访问字段一样访问数据成员。

实现数据的封装,避免使用非法数据赋值,保证数据完整性,同时类内部发生修改时,避免整个程序的修改。

C#类中字段封装为属性的更多相关文章

  1. c#类中字段和方法中变量的声明问题

    字段和局部变量的作用域冲突 某些情况下可以区分名称相同,作用域相同的两个标识符.原因是C#在变量之间有一个基本的区分,它把在类级别声明的变量看作 字段,而把在方法中声明的变量看作局部变量. class ...

  2. MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致

    MyBatis系列二  之   数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致         使用ResultMap节点配置信息  在映射文件中  ...

  3. 在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句:

    在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句: 如果是String类型的字符串进行判空的时候: <if test=&q ...

  4. Json串的字段如果和类中字段不一致,如何映射、转换?

    Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...

  5. Android Studio查看类中所有方法和属性

    ctrl+f3效果: alt+7效果: 注意区别:虽然所有方法都有,但是顺序自己一看效果便知.一个是根据类中的顺序,另一个是根据a-z的开头字母顺序. 百度查了一下快捷键是ctrl+f12.但是自己试 ...

  6. C#类中字段,属性与方法

    person类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  7. 第8.11节 Python类中记录实例变量属性的特殊变量__dict__

    一. 语法释义 调用方法:实例. __dict__属性 __dict__属性返回的是实例对象中当前已经定义的所有自定义实例变量的名和值,用字典存储,每个元素为一个"实例变量名:值" ...

  8. 关于entityframework 自动生成实体类中加验证的属性重新生成后属性被覆盖解决办法

    1.手动创建一个部分类 (你可以手动创建 partial class, 内容为空) [MetadataType(typeof(AppleMetadata))] public partial class ...

  9. MOOC(7)- case依赖、读取json配置文件进行多个接口请求-测试类中调用封装的mock(10)

    封装mock后,在单元测试中调用 # -*- coding: utf-8 -*- # @Time : 2020/2/11 8:35 # @File : test_class_10.py.py # @A ...

随机推荐

  1. 通过cassandra-cli客户端了解cassandra的内部数据结构

    和cassandra数据库交互的方式有两种,一种是通过类似于cassandra-cli命令的thrift api,或者通过cassandra提供的cql(cassandra query lanugag ...

  2. URL to load resources from the classpath in Java

    In Java, you can load all kinds of resources using the same API but with different URL protocols: fi ...

  3. Java类型中ParameterizedType,GenericArrayType,TypeVariabl,WildcardType详解

    (1). 和反射+泛型有关的接口类型 java.lang.reflect.Type:java语言中所有类型的公共父接口 java.lang.reflect.ParameterizedType java ...

  4. 一篇文章有若干行,以空行作为输入结束的条件。统计一篇文章中单词the(不管大小写,单词the是由空格隔开的)的个数。

    #include <iostream>using namespace std; int k = 0;int n = 0;int main() { char c; char a[1000]; ...

  5. Intellij下Jquery中文乱码

    今天在用Jquery+Ajax实现检查用户名是否可用的功能时,意外的发生了乱码,谷歌了很久后终于找到了解决办法: 把js文件复制一份在桌面 用记事本打开,另存为UTF-8格式 复制粘贴回去,覆盖之前的 ...

  6. 基础数据类型的坑和集合及深浅copy

    一.基础数据类型的坑: 元组: 如果一个元组中,只有一个元素,且没有逗号,则该"元组"与里面的数据的类型相同. # 只有一个数据,且没有逗号的情况: print(tu1,type( ...

  7. unity中把一个图片切割成两个UI图片

    1.在unity3D的Project视图下选中需要更改的图片,将图片的Texture Type更改为Sprite (2D and UI),点击Apply即可.操作如图所示: 2.完成步骤一,点击App ...

  8. 修改Host,配置域名访问

    修改Host,配置域名访问   虽然我们已经能够通过localhost访问本地网站了,为了提高逼格,我们可以修改host文件,设置一个自己喜欢的域名指向本地网站,岂不是更高大上. 明确需求 通过配置, ...

  9. log4j不输出日志的解决方案

    参考:http://blog.csdn.net/qq994406030/article/details/53433159 主要是log4j.properties log权限和log输出方式没配好.

  10. OOP⑸

    1.封装: 继承: extends java只支持单根继承!(一个类只能有一个直接的父类) 是代码重用的一种方式! 将子类共有的属性和方法提取到父类中去! Object:超类/基类==>java ...