C#学习笔记 09.01

C#学习笔记 09.01

(学习视频来自bilibili的传智播客赵老师基础教学视频)

面向过程与面向对象

这两个都是指的思考方式

面向过程

强调的是完成一个事情的动作。
面向过程的思想是自己把事情都做了。
比如将大象塞进冰箱需要三步

  1. 打开冰箱门
  2. 把大象塞进冰箱
  3. 关上冰箱门
面向对象

面向对象是找一个对象把事情解决掉。
比如把大象放进冰箱这件事,涉及到了三个对象,自身,大象,冰箱
在这件事情中,自己是主动的,大象是被动的,冰箱也是被动的
因为需要开门,塞大象,关门三个动作,涉及次数最多的是冰箱
所以我们将冰箱视为对象。

  1. 冰箱门可以被打开
  2. 大象可以被塞进冰箱
  3. 冰箱门可以被关闭

这样一来,不论主体是谁,都不需要关心,所以通用性会更强。

面向过程的思想,会造成更改的时候,或者拓展的时候很麻烦。

云里雾里中……
再来个例子

去中关村买电脑

面向过程的思想
  1. 查找要买的电脑的型号和价格
  2. 坐车去中关村
  3. 跟服务员讨价还价
  4. 被骗……

这种情况下,如果换个人想买的话,就需要重新表达一次这个过程

面向对象的思想

找一个大牛

  1. 大牛去查找要买的电脑的型号和价格
  2. 大牛坐车去中关村
  3. 大牛跟服务员讨价还价
  4. 大牛被骗……

这样不论是谁买电脑,买电脑的过程都简化成了 给钱,至于给完钱之后的事情就不用操心了

面向对象的三大特征

封装、继承、多态

比如 Console.WriteLine()
我们不需要知道是什么原理,只需要知道它能实现什么就行了

描述一个对象的时候一般分为两部分:特征,行为
对应在程序中使用的就是:属性、方法

对象是需要具体到某个,看得见摸得着的才是对象……

对象的共性指的也就是相同的属性和方法。

我们把具有相同属性和行为的对象进行进一步的封装,提取出一个名叫类的概念。类就是一个模子,确定了对象应该具有的属性和方法。

类,就不再是一个能看的见摸得着的东西了,而是一个模子,确定了其下的对象所拥有的属性和方法。

这部分如果要是玩过 Revit 的话就会比较好理解一些,比如墙就是一个类,画出来的墙就是对象。

试着写写。。。

新建好一个类之后,一般就会先加一个 public 变成公开的,也就是可以在其他平行的类中进行调用的。

关键字

class 类 enum 枚举 struct 结构

访问修饰符

public 公开的
pravite 私有的(外部不能访问到)

类的语法

【访问修饰符】class 类名
{
类的成员(字段,属性,方法)
}
访问修饰符 public。

当我们写好了一个类之后一般需要创建一个属于这个类的对象(静态类除外static修饰的),这个过程称为类的实例化。
使用关键字 new

字段与属性

字段一般用来存储内容,如果公开,则可以在外可以进行赋值
写方法的时候如果用 static 修饰就是静态的,不加就不是静态的。
写方法的时候用 this 就代表是当前类的对象 将需要的字段 “.” 出来。
this 这个东西貌似可加可不加,但是一旦在类内有同名变量的存在,就容易出现混淆,得不到我们想要的结果,但是。。。。没人会声明和字段同名的变量的吧。。。。

类是不占内存的,只有当类被实例化了之后才会占内存。

在一个类中,应该给每个字段配备一个属性,属性的本质是由 get 和 set 两个方法,用来取值和设值。为什么这样呢,是因为字段如果被公开之后,可以随意的更改,这在某些情况是不合适的。所以我们引入一个叫属性的东西,将所有字段都私有,利用属性控制外部是否可以对字段进行赋值或者读取。
虽然最终通过属性我们还是在给字段进行赋值和取值,但是利用属性我们让这个访问过程可控,可选择。

属性的用法

string _name; //声明字段的时候不加 public 修饰,这样字段就是私有的,不能被外部访问
public string Name // 配合一个公开的方法(属性,这个方法其实比较特别,因为不是()结尾的)
{
get { return _name; }
set { _name = value; }
}
如果我们在 set 这个方法中设定一些判定进去,那么就会实现在赋值时进行一些条件判定,让我们对应的字段的取值区间有一个管控。
而取值的时候可以把一些判定卸载 get 里面,从而实现对取值这个过程也有所把控。

有 get 无 set 那么就只读了(只读属性)
无 get 有 set 那么就只写了(只写属性)
不过这俩至少是要有一个的,俩都有也是可以的。。。

对象

类名 对象名 = new 类名();
给对象的每一个属性进行赋值的过程,称为对象的初始化。
如果属性特别多,这个过程就会变得很麻烦。
所以我们引入一个东西:构造函数

构造函数

构造函数其实就是一个函数(方法)
语法:
public 构造函数名 () //一定是 public
{
代码;
}
构造函数的特点:

  1. 构造函数的函数名一定是和类名一样的
  2. 构造函数没有返回值,也不需要写 void
  3. 构造函数可以重载
  4. 类有一个无参数的默认构造函数,当写了一个新的构造函数之后,这个默认的构造函数将不再默认生成,如果还需要一个无参数的构造函数,那么需要自己写一个。

构造函数的作用其实是将我们为各个属性赋值的过程写在这个构造函数里面,然后让我们的对象在声明的时候可以像一个方法那样,把属性都写在括号里面,从而简化一个个点出来,再赋值的过程。

调用构造函数的时候一定就是实例化对象的时候,因为 new 做了三个事情:

  1. 在内存 堆 中开辟空间
  2. 在开辟的 堆 空间中创建对象
  3. 调用对象中的构造函数

值类型和引用类型

值类型:int double char bool decim struct enum
引用类型: string 数组 自定义类

值类型是存储在 栈 中的
引用类型是存储在 堆 中的

变量名指向的都是栈,而值类型通过变量名就直接找到了值。
引用类型也是变量名指向栈,不过栈中存储的是对应的值所在堆中的位置,需要顺着这个存储的位置再去找到对应的值。

静态和非静态

  1. 看一个成员是否是静态的,就看是否以 static 修饰。
  2. 以 static 修饰的就是静态的,反之则是非静态的。
  3. 在一个非静态类中,是可以出现静态成员的,比如控制台一打开的这个类是非静态的,而 mine 函数是静态的。
  4. 非静态的函数中可以访问到非静态成员和静态成员。
  5. 静态函数中不可以访问到非静态成员。
  6. 静态类中也不可以出现非静态成员。
  7. 通过 对象 . 能点出来的都是实例成员(实例成员需要用对象去调用)
  8. 静态方法调用 类名 . 方法名就可以(静态成员要用类名去调用)
  9. 静态类不可以实例化,成员都类名点出来就行了。

什么时候用静态类,什么时候用非静态类

如果一个类是工具形的,那么写成静态类比较合适(面向过程的思路)
静态类最大的好处是资源共享,静态类其实是占内存的,比如登陆完QQ之后通过QQ打开各种链接都不需要重新登陆,账号密码大概就是存在静态类中了。
非静态类在面向对象的思路中会比较有用……

C# 垃圾回收

C# 不需要手动去释放资源
当我们程序结束之后,GC会看一下空间中有没有未被指向的,找到之后就会销毁。。

析构函数

在程序调用的时候不会运行,而是程序结束的时候自动调用
声明时候前面加 ~
因为 C# 不需要我们手动释放资源,所以一般没啥用。。。

写个小类,举个例子

一个车票类,距离决定价格,一旦确定了就不可更改。

using System;

namespace _13_MianXiangDuiXiang
{
    class Program
    {
        static void Main(string[] args)
        {
            Ticket chePiao1 = new Ticket(50.3584564);
            Console.WriteLine(chePiao1.JiaGe);
            Console.ReadKey();
        }
    }

    public class Ticket
    {
        double _juLi, _jiaGe;
        public double JuLi
        {
            get { return (int)_juLi; }
        }
        public double JiaGe
        {
            get { return (int)(_jiaGe * 100 + 0.5) / 100.00; }
        }
        public Ticket(double juLi)
        {
            this._juLi = juLi < 0 ? 0 : juLi;
            jiSuanJiaGe();
        }
        void jiSuanJiaGe()
        {
            this._jiaGe = this._juLi * 1;
            if (this._juLi <= 100)
            {
            }
            else if (this._juLi <= 200)
            {
                this._jiaGe = this._jiaGe * 0.95;
            }
            else if (this._juLi <= 300)
            {
                this._juLi *= 0.9;
            }
            else
            {
                this._juLi *= 0.8;
            }
        }
    }
}

在一个项目中想用另一个项目中的类

  1. 添加引用
  2. 添加命名空间
  3. 类应该是 public 的
再回忆一下访问修饰符

public 公开
private 默认修饰类成员的修饰符,实现类内私有
internal 默认修饰类的修饰符,实现程序集外不可访问

字符串

因为是引用类型,所以不断重新赋值会不断开辟新空间,占用大量内存。
如果我们需要对一个字符串进行大量的重新赋值或者拼接操作,那么建议使用 StringBuilder
因为对 string 不断重复赋值需要不断的重新开空间(每一次赋值都像是实例化了一个新对象),所以运行效率也很低。而 StringBuilder 是一个对象,利用其方法对其进行修改的时候都是在他原有的空间上进行操作,所以效率比较高;
字符串 string 这个东西有点像一个由 char 组成的数组,所以可以用 [ ] (索引)进行访问,但是直接这么访问的时候是只读的,如果我们想修改,需要将其转化成真正的 char 数组:
char【】 起个名 = 字符串名.ToCharArray();
这样一来就可以利用索引进行访问并修改,改好了之后再拼回去;
str = new string (char)

字符串这个东西最重要的就是他这一坨属性与方法
  1. ToCharArray() 方法 将字符串变成一个 Char 数组
  2. Length 属性 返回字符串长度
  3. ToUpper() 方法 将字符串转成大写
  4. ToLower() 方法 将字符串转成小写
  5. Equals() 方法 比较两个字符串是否相同,这个方法有重载,以一个枚举类型来确定是否忽略大小写。
  6. Split() 方法 分割字符串有6个重载,以一个 char 数组描述存储分割符号 ,返回一个字符串数组,可以补充一个枚举型参数来确定是否忽略空值。
  7. Replace() 方法 将出现的指定字符替换成另一字符(当然,后面用正则表达式会比较多,然而我现在还不知道啥是正则表达式)
  8. Substring() 方法 截取字符串 有点像 Excel 的 mind
  9. StartsWith() 方法 判断是否以某一字符串开头
  10. EndsWith() 方法 判断是否以某一字符串结尾
  11. Contains() 方法 判断字符串中是否包含后裔字符串
  12. IndexOf() 方法 返回某一字符串首次出现的索引,如果找不到就返回 -1
  13. LastIndex() 方法 返回某一字符串最后出现的索引,如果找不到就返回-1
  14. Trim() 方法 返回一个去掉了前后空格的字符串,值得一提的是位于字符串中间的空格是不能被去掉的。相应的还有两个加个 start 或者 end 的方法,是去掉字符串前面的空格和后面的空格。

string 这个类还有一些静态方法
string.Join() 将一堆字符串以特定分割符连接在一起,类似 Excel 里面的 textjoin

那么问题来了,怎么解决中间的空格呢?

这就需要前面那个 Split 方法,将空格视为分隔符,也就把空格去掉了,灵活运用一下。往往灵活运用这个东西是最神奇的。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中的各种名词: 常数:声明时用const修饰,是隐式静态类型 域:一个代表和某对象或类相关的变量的成员 字段:和属性相同,是用来存储对象的值,可以直接访问数据且不能对数据添加任何限制,但是属性不能且可以对数据添加访问限制。一个在类或结构的定义中声明的变量。可以被这个类或者结构的所有成员函数(方法、构造函数)使用,可以是值类型或引用类型,主要有实例字段和静态字段。区别于局部变量在于局部变量只能被给定的函数或代码块使用 属性:一种用于访问对象或类的特性的成员。属性的访问器是一种使属性可以像公共数据成员一样被使用的特殊方法(get/set方法)。属性结合了字段和方法的多个方面,对于对象的用户,它显示为字段;对于类的实现者,它是一个或两个代码块(用于表示get/set访问器)。写类的时候使用System.Serializable属性以便使类的成员可以序列化 方法:是一种用于实现可以由对象或类执行的计算或操作的成员。类的方法主要是和类相关联的动作,它是类的外部界面,对于那些私有的字段来说,外部界面实现对它们的操作一般只能通过方法来实现。方法在类或结构中声明,声明时需要制定访问级别、返回值、方法名称及方法参数。一个方法的签名由它的名称以及它的形参的个数、修饰符和类型组成。方法的签名是方法的唯一标识(同一个类中的区别标识)。 方法的重载:是指方法名相同,但参数类型、个数或顺序不同的方法,与返回值无关(同一类或子类之间) 方法的重写:子类对父类方法的重新实现(方法头相同,方法体即代码块不同) 事件:是使得对像和类提供通知的成员。一个类通过提供事件声明来定义一个事件,这看起来与域和事件声明相当类似,但是有一个event关键字。这个声明的类型必须是delegate类型。如下例子: public delegate void EventHandler(object sender, Event e); public class Button { public event EventHandler Click; public void Reset() { Click = null; } } 索引:是使得对象可以像数组一样被索引的成员 结构:一种值类型,几个数据组成的数据结构。向方法传递结构时,是通过传值方式传递的,结构实例化可以不用new,结构可以声明构造函数,但必须带参数,且声明的构造函数是用来对成员初始化的,必须包含每个字段。结构不能从另一个结构或类继承而来,但可以实现接口,结构中不能初始化实例。结构存储在栈中且只用来表示小的数据结构,类存储在托管堆中 类:是一种数据结构,是具有相同或相似结构、操作和约束规则的对象组成的集合。算法和数据结构的集合(对象),具有封装、继承、多态等特点。父类—基类、子类—派生类。类的多态是指不同的类进行同一操作可以有不同的行为。类是相同对象的集合,并为这些对象定义了编程语言上的属性和方法。类修饰符:new在类声明时使用,public公共的,访问不受限,protected只能从其所在类和所在类的子类中进行访问,internal只有其所在类才能进行访问,private私有的,abstract抽象类,不能实例化,sealed密封类,不能被继承 虚拟成员:声明为virtual的类成员 析构函数:以类名+~来命名的,不能有参数,不能有任何修饰符而且不能被调用。当某个类的实例被认为不再有效并符合析构条件时,.NET Framework类库的垃圾回收功能就会调用该类的析构函数实现垃圾回收,一个类只能有一个析构函数。一般准则是,除非有迫不得已的原因,不要使用析构函数,而应把清楚操作交给运行时完成 接口:声明的所有成员隐式的为public和abstract。在命名空间中声明的接口可以被授予public或internal访问类型。嵌套的接口可以被授予public、protected、internal、protected internal或private访问类型。默认为internal.接口的成员隐式的被声明为public和abstract访问类型且没有实现没有修饰符 密封类:密封类不能作为基类被继承,但可以继承别的类或接口,密封类中不能声明受保护的成员或虚成员,密封类不能声明为抽象的,声明密封类用sealed.密封方法只能用于对基类的虚方法进行实现,声明密封方法时同时使用sealed和override且必须通过重写基类中的虚方法来实现 名称空间:类似java中的包 集合: 代表: 访问修饰符:private、public、protected、internal:局部的 readonly:只读修饰符 new(新的)、static(静态的)、virtual(虚拟的)、override()、sealed(密封的)、abstranct(抽象的)、extern(外面的) 派生类调用基类的方法可以使用base关键字,如base.Method();

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值