C#_面向对象

继承

用法:

场景:

可能会在一些类中写出些重复的成员,可将这些重复的成员单独封装在一个类中作为父类
子类可以调用父类,但父类永远不能调用子类。
例子:
student、teacher、driver为子类、派生类
person为父类、基类

继承特性

  1. 单根性:一个子类只能有一个父类
  2. 继承的传递性(子类可以继承父类的所有前辈的东西)
    可在视图-类图,查看类图,了解类之间的关系

继承内容:

继承属性和方法,但不继承私有字段
不继承构造函数,但会默认调用父类无参的构造函数(子类创建对象时会创建一个父类对象,让子类可以使用父类中的成员)
如果在父类写了有参构造函数后子类报错:

  1. 在父类重新写一个无参的构造函数(一般不建议这样)
  2. 在子类中显示的调用父类的构造函数,使用关键字“:base()”【用法:在子类的构造函数小括号右侧加上:base(需要的变量),这样就不用写父类里写过的相关的内容】
    object是所有类的基类(若新建类时没设置父类,则默认继承object类)

命名空间

可认为类是属于命名空间的
若当前项目中找不到类的命名空间,可以手动导入

导入方法:

  1. 鼠标点类名左下角的小方块
  2. Alt+Shift+F10
  3. 记住名字手动添加引用

使用不同项目中的类:

  1. 添加引用
  2. 引用命名空间

值类型和引用类型

区别:

  1. 值类型和引用类型在内存上存储的地方不一样
  2. 在传递时传递的方式不一样(值传递和引用传递)
值类型引用类型
存储在内存的栈中存储在内存的堆中,在栈中存了放了数据的堆的地址
int、double、bool、char、decimal、struct、enumstring、自定义类、数组
但是字符串比较特殊,它具有不可变性,每次赋值都会开辟新的空间

字符串

不可变性:

给字符串重新赋值时,老值仍然在,只是使用了新值的地址,当程序结束时,GC扫描整个内存,若发现有空间没有被指向,则立即销毁

方法

ToCharArray():把字符串转化为char数组

New string(char[] shs):


把char数组转化为字符串

  1. 可将string看作char的一个只读数组,所以可通过下标访问字符串的某一个元素
  2. 可将string转换为数组
    Char[] char 变量名=string 变量名.ToCharArray();
    也可将char数组再变成string

例:

string s “abcdefg”;
char[] chs=s.ToCharArray();
chs[0]=Z;
s=new string[chs];

字符串提供的方法:

方法定义例子
length获取字符段长度
toUpper()将字符串转换为大写变量名=变量名.toUpper();
toLower()将字符串转换成小写
Equals比较两个字符串,加入括号里逗号后的内容可以忽略大小写变量1 Equals(变量2,stringComparison.OrdinalIgnoreCase)
+字符串的链接,若任何一边是字符串,则另一个也会变成字符串
spilt()把字符串分割成字符串数组,有六种方式可以用来重载spilt例子:`string s =”a b s,dasd_+=…”;char[] chs={” “,”_”,”.”};string[] str=s.split(chs,stringSpiltOptions.RemoveEmptyEntries);//可通过添加这一option来决定是否保留分割后的空白
replace将字符串中的出现oldValue的地方替换为newValuestring.replace(string oldValue.string newValue)
substring取从位置startIndex开始长度为length的子字符串,如果子字符串长度不足length则报错string.substring{int startIndex.int length}
substring取从位置startIndex开始一直到最后的子字符串string.substring(int startIndex)
boolContains(string value)判断字符串中是否含有字串value字符串.Contains(string value)
int indexOf(string value)取子串value第一次出现时的位置,找不到时会输出-1int indexOf(string value)
LastIndexof
Trim()从字符串中去掉前面的空格和后面的空格
TrimEnd()从字符串中去掉前面的空格
TrimStart()从字符串中去掉前面的空格
isNullOrEmpty()判断字符是否为null或空
Join可用于合并数组中的元素/或直接元素,并添加分隔符string.join()
int indexof(string value, int startIndex)

当需要对string类型大量赋值操作又不想太占内存,可以使用stringbuilder
stringbuilder一般最后还是要变回string
sb.toString,tostring方法有很多特别用法,在括号里输入不同参数可以有不同效果

里氏转换

  1. 子类可以赋值给父类(如果有地方需要一个父类作为参数,那么可以给一个子类作为代替)
    例子:
student s =new student();
person p=s;

简写:

person p=new student();
  1. 如果父类中装的是子类对象,那么可以将父类强转为子类对象(接上例):
student ss=(student)p;
if (p is student)
{
    student ss=(student)p;
    ss.studentsayhello();
}
else
{
    console.writeline{"转换失败"};
}
ss.studentsayhello();

或者

student t =p as student
  1. 转换时使用的判断:
    is:如果能够转换成功,则返回一个true,否则返回一个false
    as:如果能够转换则返回相应的对象,否则返回一个null
    可以用父类数组随机往里面装子类,然后使用时通过转换重新得到子类(狼人杀的感觉)

多态

如果父类的方法有默认的实现,且父类需要被实例化,可以考虑把父类定义为一个普通类,用虚方法来实现多态
如果父类的方法没有默认实现,父类也不需要被实例化,则可将父类定义为抽象类

虚方法

抽象类

接口

装箱和拆箱

序列化与反序列化

部分类

密封类

重写对象的tostring

泛型

泛型类型

为什么需要泛型

泛型方法

进程类与多线程

方法

阻塞(Blocking)

本地vs共享的状态

向线程传递数据