【C#基础详解】(十二)类

12.1 类与对象

我们在代码中描述一个对象,是通过描述这个对象的属性方法,对象必须是看得见摸得着的。

例如:

灯:拥有属性和方法

属性:外形:圆的;功耗:500w;颜色:白色;牌子:xx

方法:发光

电风扇:拥有属性和方法

属性:外形:三个叶片;颜色:白色;品牌:xx

方法:转动、扇风

我们把这些具有相同属性相同方法的对象进行进一步的封装,抽象出来“类”这个概念。

类就是一张图纸,确定了对象具有的属性和方法,对象是根据类创建出来的。

类就是一个盖大楼的图纸,对象就是盖出来的大楼。

12.2 类的语法

[public] class〈类名〉

{

        字段(Field);

        属性(property);

        方法(Method);

}

         属性与字段是对同一个元素不同的称呼。字段是从数据库角度的名字,也可以称为属性,属性是从面向对象角度的名字。        

        写好了一个类后,我们需要使用关键字new创建这个类的对象,我们称创建这个类的过程叫做实例化,this:表示当前这个类的对象。类是不占内存的,而对象是占内存的。

12.3 属性

1)简介:

        属性是字段的自然扩展。从命名上看,字段更偏向于实例对象在内存中的布局。属性更偏向于反映现实世界对象的特征。属性的作用就是保护字段、对字段的赋值和取值进行限定,属性的本质就是两个方法,一个叫get一个叫set。

        建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或protected

2)语法:

public 返回类型 标识符

{

        get{ retrun 输出值;} 访问器为属性获取值

        set{ 赋值 = value;} 访问器为属性赋值

}

既有get也有set我们称之为可读可写属性

只有get没有set我们称之为只读属性

没有get只有set我们称之为只写属性,只写属性很少出现,常用于限制对敏感数据的访问

封装属性的快捷键:Ctrl+R+E

        在进行设值(赋值)限定的时候,参数用的是value,在进行取值(输出值)限定的时候参数用的是字段

示例:

private string name;

public string Name

{

        get{return name;}

        set{name=value;}

}

3)new关键词:

Person zs Person = new Person();

new帮我们做3件事:

① 在内存中开辟一块空间

② 在开辟的空间中创建对象

③ 调用对象的构造函数进行初始化对象

 4)this关键词:

代表当前类的对象。

在类当中显示的调用本类的构造函数:this。

 5)属性练习:在同一命名空间下,新建Person类,判断用户赋值的姓名、性别、年龄,如果性别赋值的不是男/女,默认为中,年龄如果小于0或者大于100,默认为0。

//首先在Person类下封装属性,写方法:
public class Person
{
    private string _name;
    public string Name
    {
        //当你输出属性的值得时候 会执行get方法
        get { return _name; }
        //当你给属性赋值的时候 首先会执行set方法
        set { _name = value; }
    }
    private int _age;
    public int Age
    {
        get { return _age; }
        set
        {
            if (value < 0 || value > 100)
            {
                value = 0;
            }
            _age = value;
        }
    }    
    private char _gender;
    public char Gender
    {
        get
        {
            if (_gender != '男' && _gender != '女')
            {
                return _gender = '中';
            }
            return _gender;
        }
        set { _gender = value; }
    }
    public void Say()
    {
        Console.WriteLine("我叫{0},我今年{1}岁了,我是{2}生,我	可以说话", this.Name,     this.Age, this.Gender);
    }
}
//再在Main函数实例化Person对象,并赋值:
class Program
{
    public static void Main(String[] args)
    {
        Person p = new Person();
        p.Name = "张三";
        p.Age = 20;
        p.Gender = '女';
        p.Say();
        Console.ReadKey();
    }
}

运行结果:

我叫张三,我今年20岁了,我是女生,我可以说话

12.4 构造函数

1)构造函数简介:

        首先它是一个方法(函数),因为具有“构造”的作用,所以称之为构造函数(构造方法)。构造函数就是与类具有相同名称的成员函数,通常使用类中的构造函数来初始化类的成员属性,不包含返回类型。

作用:在创建实例对象时自动调用,可以对实例对象进行初始化。

为何要初始化?

我们一个类可以实例化出很多实例对象,每个对象都需要定一下属性。

通过下面的方式进行赋值:

对象1.属性1 = 值1;

对象1.属性2 = 值2;

对象2.属性1 = 值3;

对象2.属性2 = 值4;

当实例化对象很多时会存在大量的重复代码

因此,我们用构造方法对对象进行初始化,在刚开始实例化对象的时候就对其进行赋值操作。

如下:

类名 对象1 = new 类名(值1,值2)

类名 对象2 = new 类名(值3,值4)

简洁而优美

2)构造函数的语法要求:

public 类名([ 参数 ])

{

        构造函数代码;

}

注意:

① 构造函数必须用public修饰符,不能用private,public:公开的公共的,在哪儿都能访问。private:私有的,只能在当前类内部进行访问,除了这个类就访问不到了。

② 构造函数是创建对象的特殊函数,函数名和类名一样,没有返回值,连void都不用写。

③ 构造函数可以有参数,new对象的时候传递函数参数即可,当对象被创建的时候(new),构造函数被执行。

④ 构造函数没有返回值,所以不用在函数名前面加void、int、string等返回值类型。

⑤ 构造函数不能被继承,也不能被重写。但子类可以通过base()调用父类的构造函数。

⑥ 构造函数可以重载:我们可以不定义构造函数,这时候系统用自带的空的构造函数。当你写了一个新的构造函数之后,不管是不是无参数的,那个默认的无参数的构造函数都被干掉了,当一个类中有两个以上的构造函数时,可以看做是构造函数的重载。

如下为空构造函数:

public 类名()

{

        此处啥也不写

}

我们在实例化对象的时候有两种方式

        ① 调用无参数的构造函数实例化对象

        People p1 = new People();

        ② 调用有参数的构造函数实例化对象

        People p1 = new People("张三",20,"学生");

3)构造函数练习1:

写一个ticket类,有一个距离属性(本属性只读, 在构造方法中赋值),  不能为负数,有一个价格属性,价格属性只读,并且根据距离distance计算价格price(1元/公里) :

0 - 100公里 票价不打折

101 - 200公里 总额打9.5折

201 - 300公里 总额打9折

300公里以上 总额打8折

//首先写ticket类:
public class Ticket
{
    private double distance;
    public double Distance
	{
        get { return distance; }
    }
    //构造函数
    public Ticket(double distance)
    {
        if (distance < 0)
        {
            distance = 0;
        }
        this.distance = distance;
    }
    private double price;
    public double Price
    {
        get
        {
            if (distance > 0 && distance <= 100)
            {
                price = distance * 1.0;
                return price;
            }
            else if (distance >= 101 && distance < 200)
            {
			    price = distance * 0.95;
				return price;
            }
            else if (distance >= 201 && distance < 300)
            {
                price = distance * 0.9;
                return price;
            }
            else
            {
                price = distance * 0.8;
                return price;
            }
        }
    }
    public void ShowTicket()
    {
        Console.WriteLine("{0}公里需要{1}元", Distance, Price);
    }
}
//再在Main函数中调用有参数的构造函数实例化对象:
class Program
{
    public static void Main(String[] args)
    {
        Ticket t = new Ticket(358);
        t.ShowTicket();
        Console.ReadKey();
    }
}

输出结果:

358公里需要286.4元

4)构造函数练习2:编写一个Student类,其中包括4个数据成员:姓名、性别、年龄、所在学校,以及若干成员函数。同时编写主函数使用这个类,实现对学生数据的赋值和输出。

要求:使用成员函数实现对数据的输出(显示学生的相关信息);使用构造函数实现对数据的输入(可以重载多个构造函数并使用)。

//首先在Student类中编写:
    public class Student
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private string gender;
        public string Gender
        {
            get { return gender; }
            set
            {
                if (value != "男" && value != "女")
                {
                    value = "中";
                }
                gender = value;
            }
        }

        private int age;
        public int Age//设为属性
        {
            get { return age; }//得到  return返回值
            set //设置判断的条件,规定该属性的正确要求
            {
                if (value < 0 || value > 100)
                {
                    value = 18;
                }
                age = value;
            }
        }
        private string school;
        public string School
        {
            get { return school; }
            set { school = value; }
        }
        public void ShowStudent()
        {
            Console.WriteLine("该学生姓名为:{0},性别为{1}生,年龄为{2}岁,学校为{3}", Name, gender, Age, School);
        }
        public Student(string name, string gender, int age, string school)
        {
            this.Name = name;
            this.Gender = gender;
            this.Age = age;
            this.School = school;
        }
        public Student(string name, string gender)
        {
            this.Name = name;
            this.gender = gender;
        }
    }

//再在Main函数中实例化新的对象:
    class Program
    {
        public static void Main(String[] args)
        {
            Student s1 = new Student("小丽", "女", 22, "南昌大学");
            s1.ShowStudent();
            Student s2 = new Student("张三","未知");
            s2.ShowStudent();
            Console.ReadKey();
        }
    }

输出结果:

该学生姓名为:小丽,性别为中生,年龄为22岁,学校为南昌大学

该学生姓名为:张三,性别为未知生,年龄为0岁,学校为

12.5 析构函数

1)析构函数简介:

        可以定义在垃圾回收程序最终销毁对象之前调用的方法,该方法称为析构函数。当程序结束时,析构函数才执行,帮助我们释放资源,不写析构函数GC(Garbage Collection垃圾回收器)会自动清理释放资源。

        什么意思呢?我们平常用的比较多的都是构造函数,因为我们每次new一个对象,程序就会自动调用对象中的构造函数,从而给对象动态的开辟一块内存。但是有没有想过,内存没用完,怎么办,得有回收机制,去回收空闲的内存。

        C#有自己的垃圾回收机制。这个的“垃圾”包含空闲内存,不需要程序员手动去释放空间,人家是自动的,但是有一点不好的是!他这个自动是随机的,不是你每次运行程序他就必须回收,他是看心情。

        析构函数是在你对象被进行销毁之前被执行的一个函数,也就是在垃圾回收完成之前调用的一个函数,在释放内存之前,你可以写在析构函数中,写你想实现的东西。

2)析构函数语法:

~类名()

{

        代码体;

}

注意:析构函数不能有任何参数;析构函数无返回值,无访问修饰符; 析构函数由系统调用;析构函数可不写;程序退出时会调用析构函数。

释放资源GC(Garbage Collection)垃圾回收器。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值