C#学习笔记(八)——第七章:面向对象编程(一)

博文适用于编程小白,基于《叩响C#之门》,传送门:链接:https://pan.baidu.com/s/1y2UegjDUJz-xrOQu3qKMjQ 密码:4v2n
《叩响C#之门》通俗易懂,又不失专业性,比传统的《C#入门经典》《C#从入门到精通》这类书好的多,是一本不可多得的好教材。


C#学习笔记(一)——第一章:初识编程
C#学习笔记(二)——第二章:变量
C#学习笔记(三)——一、二章内容练习及一些杂项
C#学习笔记(四)——第三章:运算符和表达式
C#学习笔记(五)——第四章:流程控制
C#学习笔记(六)——第五章:枚举、结构体和数组(还没写好)
C#学习笔记(七)——第六章:函数
C#学习笔记(八)——第七章:面向对象编程(一)




面向对象的由来,科普

这里写图片描述
这里写图片描述
这里写图片描述

面向对象基本概念

这里写图片描述

这里写图片描述

封装

这里写图片描述
这里写图片描述

接口

这里写图片描述
这里写图片描述

对象

创建类

例子:
创建这么一个类——类。
它有3个属性
①名字
②年龄
③抓到的老鼠数(私有)
它有3个方法
①喵喵叫
②捉老鼠
③打招呼(私有)

类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloClass2
{
    class Cat
    {
        //字段成员
        public string name;
        public int age;
        private int miceCount = 0;  //用于记录捉到了多少只老鼠

        //方法成员
        //方法:打招呼
        private void Hello()
        {
            Console.Write("Hi,我是{0}", name);
        }

        //方法:喵喵叫
        public void Meow()
        {
            Hello();
            Console.WriteLine("喵,喵~~~~");
        }

        //方法:捉老鼠
        public void ChaseMice()
        {
            miceCount++;
            Hello();
            Console.WriteLine("我已经抓住了{0}只老鼠!", miceCount);
        }
    }
}

主函数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloClass2
{
    class Program
    {
        static void Main(string[] args)
        {
            //声明对象
            Cat kitty = new Cat();

            //访问数据成员
            kitty.name = "Kitty";
            kitty.age = 3;
            Console.WriteLine("hi,我是{0},我{1}岁了。", kitty.name, kitty.age);

            //调用方法

            kitty.Meow();
            kitty.ChaseMice();  //捉老鼠(私有属性micecount在这里体现)
            kitty.ChaseMice();  //再次捉老鼠
        }
    }
}

动图
这里写图片描述

小结一下

这里写图片描述

这里写图片描述
这里写图片描述

对象构造器

这里写图片描述

说白了就是两种构造实例的方式。第一种略显迂腐,第二种简洁且代码清晰。且python中更倾向于第二种。

属性

说到面向对象编程(OOP)的属性,就有的聊了。


先说个题外话,有没有想过,为什么很多(甚至全部)OOP中,类的定义,实例,都会有且只有2种大的分类——①属性②方法?为什么没有第③种XX?为什么这两种刚好就是这2个?有没有觉得突兀?是谁规定的?
这个问题的回答,颇有些哲学的意味,但是这却是客观世界的真理!

我们都知道,OOP是一种贴近客观世界的描述物体的编程思想。那么想一下,给你个篮球,让你尽可能的描述它,你会怎么说?

嗯,,,能弹起来,大概100块,橘黄色,表面摩擦系数0.4,能充气,直径30cm,有点软,能滚动,1斤重……差不多就这些了。

自己想一下这些描述的词语,我们发现他们能且刚好能被归为2大类
1.大概100块,橘黄色,表面摩擦系数0.4,直径30cm,有点软,1斤重
2.能弹起来,能充气,能滚动,

这第1类,是用来描述物体性质的,被称为属性
第2类,是用来描述物体能干什么的,被称为方法

其实,不止是篮球,世间万物都可以用这两大类——属性方法完整刻绘
所以,在OOP中,类的定义也好,实例自身也好,都有且刚好只有这两大类数据——属性方法


言归正传。
属性这个东西,有个非常非常典型,非常非常常用的操作,甚至可以说是每种编程语言都会用到的操作——设置,读取。
这个从客观事物的角度很好理解,属性嘛,物体自身的性质,自然会用到读取,和设置两种操作(如果你说有的属性我不用啊,那就不用设置,读取了。对,那你想想,如果你不用这种属性,干嘛写在类里(微笑脸)。)。
那么问题来了,我们最直接的设置方法,就是直接用点运算符进行赋值。但是这也会带来一个问题——设置的值没有经过任何检查,可能会使值不合理,比如学生的成绩student1.score=-19。这就会出现意想不到的错误。该怎么办呢?再进一步想,我们可以给输入的数值进行一定的操作,来进行检查。进行操作,就需要用到函数(类中的方法)。比如这样
这里写图片描述

但是问题又来了!属性,最直接的访问方法一定是用点运算符,而非用函数。你想想,student.score=77看着舒服,还是student.SetScore(77)舒服?这便捷性和功能性似乎有矛盾——方便快捷的,功能性不强;功能强的,又不方便。有没有两全其美的办法呢?——又便捷,功能又强大。答案是——有!
基于这种对物体性质这种经常性的操作,很多编程语言都专门设置了一种方法,用来实现我们想要的又快捷又功能强的操作。比如python中的@setter@getter装饰器。C#当然也有。请看下面例子

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里的value是个关键字。

自动属性

构造函数

构造函数,顾名思义,就是用来按照图纸(类定义)生产产品(实例)的函数。
每个实例的生成,都必须要用到构造函数。就如Cat kitty=new Cat();,这里的Cat()就是默认的构造函数。构造函数在创建实例时,会给成员变量分配初始化的值。默认函数通常给的值都是null0这些。
有时候我们需要设定初始值,该怎么办呢?用自定义的构造函数!

C#里面的构造函数相当于python类中的__init__。道理差不多的。

默认构造函数

例子:(还是用最初的类代码)

这里写图片描述

效果:
这里写图片描述
类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HelloClass2
{
    class Cat
    {
        //字段成员
        public string name;
        public int age;
        private int miceCount = 0;  //用于记录捉到了多少只老鼠

        //方法成员
        //方法:打招呼
        private void Hello()
        {
            Console.Write("Hi,我是{0}", name);
        }

        //方法:喵喵叫
        public void Meow()
        {
            Hello();
            Console.WriteLine("喵,喵~~~~");
        }

        //方法:捉老鼠
        public void ChaseMice()
        {
            miceCount++;
            Hello();
            Console.WriteLine("我已经抓住了{0}只老鼠!", miceCount);
        }
    }
}

主程序代码

            //声明对象
            Cat kitty = new Cat();

            Console.WriteLine("姓名:{0}", kitty.name);
            Console.WriteLine("年龄:{0}", kitty.age);
            kitty.ChaseMice();

这里写图片描述

自定义构造函数

自定义构造函数位置:类内
自定义构造函数格式:public Cat(string nameValue,int ageValue)(参数可选)
在类内添加代码

        public Cat(string nameValue, int ageValue)
        {
            name = "kitty2";  //可以直接在这里赋给默认值
            age = ageValue;

            Console.WriteLine("一只猫诞生了!调用了构造函数!");
        }

这里写图片描述
这里写图片描述

既然参数是可选的,我们来试一试
类代码:

        public Cat()
        {
            name = "kitty2";  //可以直接在这里赋给默认值
            age = 3;

            Console.WriteLine("一只猫诞生了!调用了构造函数!");
        }

效果

这里写图片描述
这里写图片描述

析构函数

2句话总结:①在C#中可以不用管析构的问题,因为C#中有垃圾回收器。②真要写析构函数,可以按如下格式来写

        ~Cat()  //函数名与类名相同,前面加~,函数体没有内容
        {
        }

实例:
在Cat()类中添加

        ~Cat()
        {
            Console.WriteLine("这只猫去了天堂~~~");
        }

主程序

            //声明对象
            Cat kitty = new Cat();

            kitty.Meow();
            kitty.ChaseMice();
            kitty.ChaseMice();

            Console.WriteLine("\n其它语句:");
            Console.WriteLine("------------");
            Console.WriteLine("-------------");
            Console.WriteLine("这是最后一条语句。");

这里写图片描述

实例演练:Time类

这里写图片描述

效果:

类代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp9
{
    class Time
    {
        /*-----------以下为私有成员--------------*/
        private int hour;
        private int minunt;
        private int second;

        private void SetTime(int h, int m, int s)
        {
            Hour = h;
            Minunt = m;
            Second = s;
        }







        /*-----------以下为公有成员--------------*/
        //属性:Hour
        public int Hour
        {
            get
            {
                return hour;
            }
            set
            {
                hour = ((value >= 0 && value < 24) ? value : 0);
            }
        }

        //属性:Minunt
        public int Minunt
        {
            get
            {
                return minunt;
            }
            set
            {
                minunt = ((value >= 0 && value < 60) ? value : 0);
            }

        }

        //属性:Second
        public int Second
        {
            get
            {
                return second;
            }
            set
            {
                second = ((value >= 0) && (value < 60) ? value : 0);
            }
        }


        //构造函数:无参数
        public Time()
        {
            SetTime(0, 0, 0);
        }

        //构造函数:一个参数
        public Time(int hourValue)
        {
            SetTime(hourValue, 0, 0);
        }

        //构造函数:三个参数
        public Time(int hourValue, int minuntValue, int secondValue)
        {
            SetTime(hourValue, minuntValue, secondValue);
        }

        //方法:返回24小时时间制
        public string ToString24()
        {
            string output = Hour + ":" + Minunt + ":" + Second;
            return output;
        }

        //方法:返回12小时制
        public string ToString12()
        {
            int hour12 = (Hour == 12) || (Hour == 0) ? 12 : (Hour % 12);
            string AMPM = (Hour < 12) ? "AM" : "PM";
            string output = hour12 + ":" + Minunt + ":" + Second + AMPM;
            return output;
        }
    }
}

主程序代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            Time time1 = new Time();
            Time time2 = new Time(22);
            Time time3 = new Time(22, 36, 30);

            string a = time1.ToString24();
            Console.WriteLine("time1:");
            Console.WriteLine("24小时制时间:"+ a);
            Console.WriteLine("12小时制时间:"+ time1.ToString12()+"\n");

            Console.WriteLine("time2:");
            Console.WriteLine("24小时制时间:" + time2.ToString24());
            Console.WriteLine("12小时制时间:" + time2.ToString12()+"\n");

            Console.WriteLine("time3:");
            Console.WriteLine("24小时制时间:" + time3.ToString24());
            Console.WriteLine("12小时制时间:" + time3.ToString12()+"\n");

        }
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值