Home » Code » C# » C#基础之类与面向对象

C#基础之类与面向对象

类的字段与属性

C#中类的成员默认的可访问性都是private。

C#中有字段(Field)与属性(Property)之分。一般约定字段开头字母小写(另一约定还在开头添加下划线_,如_name),为private;属性开头字母大写,为public,通过为属性设置set&get访问器对字段进行读写操作。

class Person
{
    int age;//默认为private
    public int Age
    {
        set { this.age = value; }//value自动传递,为要设置的值
        get { return this.age; }
    }
}

也有以下的简写:

class Person
{
    public int Age { set; get; }
}

这种情况下,编译器会自动为我们生成对应的字段age以及set函数和get函数。当然真实自动生成的字段及函数命名不是这个,但类似且功能一致。这个语法糖为我们节省了一点代码量。

需要注意的是,属性是不存储数据的,数据存储在字段上。对字段上数据的读取通过属性的set&get访问器进行。如下边的写法是明显的错误:

class Person
{
    public int Age
    {
        set { this.Age = value; }//死循环
        get { return this.Age; }
    }
}

上边是新手易范的一个错误。属性的set访问器为属性自身赎值,一赎值就进行set操作,进行了set操作即进行了赎值,再进行set操作。。。无限循环。

相同点

都是类的成员,属性是类的属性,而字段是类的数据成员。

不同点

  • 属性可进行数据绑定
  • 属性可通过set和get方法进行数据安全性检验,而字段不行
  • 属性可进行线程同步
  • 性可以是抽象的,而字段不行
  • 属性可以接口的形式表现
  • 基于属性的索引
  • 不要直接把字段转化为属性
  • 字段在值的处理上并不是那么的灵活,给它赋什么它就是什么,不允许经过逻辑处理。如果把一个人的身高写成一个字段,给它赋值1000M,这显示是不正常的数据,字段无法处理这种特殊数据。
  • 与字段不同,属性不作为变量来分类。因此,不能将属性作为ref参数或out参数传递。

看不懂无所谓,先有个印象。以上参考自:http://www.studyofnet.com/news/144.html

类的构造函数

构造函数与类名一致,且必须为public。构造函数没有返回值,连void也不用写。构造函数可以有多个,通过接收不同的参数来区分。

class Person2
{
    public string Name { set; get; }
    public int Age { set; get; }

    public Person2()
    {
        Name = "未命名";
        Age = 0;
    }

    public Person2(string name)
    {
        this.Name = name;
        Age = 0;
    }

    public Person2(string name, int age)
    {
        this.Name = name;
        this.Age = age;
    }
}

在main函数中进行调用如下:

class Program
{
    static void Main(string[] args)
    {
        Person2 p1 = new Person2();
        Console.WriteLine("名称:{0},年龄:{1}", p1.Name, p1.Age);

        Person2 p2 = new Person2("小明");
        Console.WriteLine("名称:{0},年龄:{1}", p2.Name, p2.Age);

        Person2 p3 = new Person2("小明", 18);
        Console.WriteLine("名称:{0},年龄:{1}", p3.Name, p3.Age);
    }
}

输出结果如下:

CSharp_class_construct
类的继承

类的继承使用冒号 : 操作符。

class Person
{
    public void sayHello()
    {
        Console.WriteLine("我是人");
    }
}

class Man : Person
{
    public void playGame()
    {
        Console.WriteLine("我要玩游戏");
    }
}

关于对象的声明与转换,看下面的示例代码与说明。(使用上边定义的两个类Person与Man)

Person p = new Person();//一个人
Man m = new Man();//一个男人

Person p2 = m;//要人,给了男人,可以
p2.sayHello();//是人可以sayHello
//p2.playGame();//出错,Person未包含playGame()的定义。终究只是人,并没有因此成为男人而拥有playGame()

//Man m2 = p;//出错,无法将Person隐式转换为Man。要男人,给人,不行
//Man m2 = (Man)p;//强制转换,编辑器不报错。但实际运行起来仍然报错,无法强制将Person转换为Man

Object m2 = p;//可以,Object是所有类的基类

类的静态成员

在static方法中可以调用自己类本身及其他类的static成员,但不能调用自己类本身及其他类的非static成员。静只能调用静,不能调用非静。

在非静态方法中可以调用自己类本身及其他类的静态成员。

静态类使用static修饰,就是不能被实例化的类。

常量其实也是静态成员,但不能显式的使用static来进行修饰。

class Person
{
    public const int LegCount = 2;

    public static int TotalCount = 2;//静态成员

    private string Name = "张三";

    public void sayHello()
    {
        Console.WriteLine("我是人" + TotalCount);//自已的静态变量直接使用。非静态成员可以调用静态成员
    }

    public static void Cry()
    {
        //Console.WriteLine(Name + "在大哭。。。");//错误,静态方法Cry()中不能调用非静态成员Name
        Console.WriteLine(TotalCount);
    }
}

class Man : Person
{
    public void playGame()
    {
        Console.WriteLine("我要玩游戏" + TotalCount);//父类的静态变量可直接使用。不需要self之类
    }
}

//静态类,不能被new
static class Helper
{
    public static int ReadInt()
    {
        string str = Console.ReadLine();
        return Convert.ToInt32(str);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.