C# - 访问修饰符,字段,属性,自动属性,属性的三种类别 065
通过new实例化类得到一个实例,这个实例也叫对象(只是叫法不一样),因为说的是面向对象的编程方式,因此以后再说通过new实例化一个类,统一为得到一个该类的对象
访问修饰符(暂不包含组合)
public:在任何地方都被可以访问 private:只能在本类中被访问
internal:只能在本项目中被访问 protected:在本类与其子类中被访问
访问修饰符的作用:简单来说就是被这些修饰符修饰的字段,属性,方法等在本类以外能否被使用,也可以说是其他的类是否有权限访问本类中的字段,属性等,现今只说前两个(public,private),后两个暂时用不到
//为便于截图,写在一个.cs类文件中
//正确做法就如昨天一样添加一个新.cs类文件
namespace _77类
{
//在类的级别中
//类的默认修饰符为 internal
class Student //定义了一个学生类
{
string name;//默认是private
private char sex;
public int age;
//因此在其他类中只能访问到age"属性"
}
//类的默认修饰符为 internal
class Program //程序默认添加的程序类
{
static void Main(string[] args)
{
//Student 可以在Program类实例化
//的原因就是它们两个在同一项目中 _77类
//如果不在同一项目中以后再说
//实例化一个对象 stu
Student stu = new Student();
//只能访问学生类中被public修饰的"属性"
//那四个可以点出来的方法继承自Object类(按F12可查看)
stu.
}
}
}
字段
简单来说就是定义在类或结构体中的变量被称之为字段(field)
因此字段是一个变量,特殊的地方在于是定义在类或结构体中,是它们的成员,也可以称为成员变量,因此字段是一种表示与对象或结构体关联的变量
字段分为公有字段如public intage; 私有字段如 string name;(因为默认就是private,因此可以称为隐式的私有字段) private char sex;(显示的私有字段)
上面示例中所说的"属性"在C#中正确的术语就是类的字段;两种字段的区别就是公有的字段,外部可以访问到,私有的字段外部访问不到(上面Student类中有,不再举例声明)
面向对象编程的一大特性:封装 将私有字段封装为公有的属性
属性
属性的作用:1)封装字段 2)控制读写与访问级别的权限
//定义了一个学生类
class Student
{
public string name;
public char sex;
public int age;
public void SayHi()
{
Console.WriteLine("我叫{0},我是{1}生,今年{2}岁", name, sex, age);
}
}
//程序默认添加的程序类
class Program
{
static void Main(string[] args)
{
//实例化一个对象 stu
Student stu = new Student();
//为各个字段赋值
stu.name = " ";//名字为空
stu.sex = '0';//性别为0
stu.age = -18;//年龄为负18
//在程序中赋值没问题
//问题在于实际应用中,不希望字段被赋于类似的值
stu.SayHi();
Console.ReadKey();
}
}
编写的应用程序软件是需要在现实中使用的,因此实际应用中字段不能被如此随意赋值,希望能够对类似的不符合实际的赋值(简称不合法)加以约束,因此就出现了属性这个功能
属性简单来说就是约束使用者对字段的任意赋值,在面向对象中是将字段封装为属性,外部不再直接对字段进行赋值而是对该字段对应的属性赋值,在属性中会对使用者的所赋的值进行检测即所赋的值是否符合实际应用中的值(简称合法)
属性固定的语法格式
在类中定义
1 定义一个私有的字段
如无特别要求 两个都可以
string name; 或 private string name
有的是字段名前面加下划线(看实际要求)
string _name; 或 private string _name
2 封装该字段的属性
定义一个变量,变量名即属性名
属性名称是首字母大写的字段名
public int Name
{
该变量中有get/set两个方法
这两个方法格式与之前相比比较特别
//返回给外部的值
get { return name; }
//检测外部赋值
set { name = value; }
}
get/set相当于两个方法因此
get方法用于将字段的返回给外部的使用者
set方法用于将外部接收的值(存储在value中)赋值给字段
示例:通过属性对用户输入的值进行合法性的检测
namespace _77类
{
class Student //定义了一个学生类
{
//定义私有字段
private string name;
//定义公有的属性
public string Name
{
get { return name; }
set { name = value; }
}
private char sex;
public char Sex
{
get { return sex; }
//set方法用于检测用户输入的值是否合法
set
{
//如果外部赋的值不是男/女,就赋默认值 男
if (value == '男' || value == '女')
{
//如果外部赋的是男/女任意一个值
//将将value的值赋值给字段sex
sex = value;
}
else
{
//字段sex赋默认值为 男
sex = '男';
}
}
}
private int age;
public int Age
{
get { return age; }
set
{
//如果赋值<=0,赋默认值为 18
if (value <= 0)
{
value = 18;
}
else
{
age = value;
}
}
}
public void SayHi()
{
Console.WriteLine("我叫{0},我是{1}生,今年{2}岁", name, sex, age);
}
}
class Program //程序默认添加的程序类
{
static void Main(string[] args)
{ //实例化一个对象 stu
Student stu = new Student();
stu.Name = "张三";//没说到正则表达式暂检测
stu.Sex = '男';//赋合法的值
stu.Age = -18;//赋非法的值
stu.SayHi();
Console.ReadKey();
}
}
自动属性
一般不写私有字段,只有公有的不做任意逻辑代码的属性
固定语法格式
在类中
public string CID{get;set;}
只是一个语法糖在编译时,还会自动生成一个对应的字段
属性:
优点:定义属性的时候,可以做一些逻辑判断,检测赋值是否合法
缺点:定义属性的代码多 语法不简洁 繁琐
自动属性:
优点:定义语法简介,高效,减少程序员书写的代码量
缺点:定义属性的时候,不能做一些类似检测合法值的逻辑判断
用自动属性时程序员写的代码少,但是机器做的事情就多了,如果只是针对读写权限的作用,推荐使用自动属性,因为它只是在编译的时候产生负担,运行的不会影响客户运行程序时的效率,具体看情况而定
属性的三种类别
1 读写属性:即属性中包含get与set方法,外部既可以修改属性值,也可以得到属性值
2 只读属性:即属性中只有get方法,外部只能使用属性值,不能修改属性的值
3) 只写属性:即属性中只有set方法,外部只能写入属性值,不能得到这个属性的值
在Student类中
//定义相同类型的私有字段
private int num1, num2, num3;
//读写属性
public int Num1
{
get { return num1; }
set { num1 = value; }
}
//只读或只写属性不能使用自动属性,会报错
//public int num2{get;} public int num2{set;}
//只读属性
public int Num2
{
get { return num2; }
}
//只写属性
public int Num3
{
set { num3 = value; }
}
在Main方法中
Student stu = new Student();
stu.Num1 = 1;//读写属性
int a = stu.Num1;
stu.Num2 = 2;//只读属性
int b = stu.Num2;
stu.Num3 = 3;//只写属性
int c = stu.Num3;