C#复习笔记(四)
继承
继承的子类拥有父类的所有成员、特征和行为
class 父类:子类{}
特点:
1、单根性 子类只能有一个父类
2、传递性 子类可以间接继承父类的父类
C#运行子类存在和父类同名的成员,但极不建议使用!
里氏替换原则
任何父类出现的地方,子类都可以代替
父类容器装子类对象
public GameObject{}
public Player : GameObject{}
GameObject player = new Player();is 和 as
is判断一个对象是否是指定类对象,返回值为bool
as将一个对象转换为指定类对象,返回值为对象和null
继承中的构造函数
当申明一个子类对象时
先执行父类的构造函数、再执行子类的构造函数
父类的无参构造很重要(子类实例化时,默认调用父类无参构造,无参构造被顶掉就会报错)
子类可以通过使用base关键字调用父类构造
base()括号中加参数可使用父类有参构造万物之父 object
object是所有类型的基类,它是一个类(引用类型)
1、可以利用里氏替换原则,用object容器装所有对象
2、可以用来表示不确定类型,作为函数参数类型
装箱和拆箱
不确定类型时可以方便参数的存储和传递
存在内存迁移,
object x = 1; //装箱
int value = (int)x; //拆箱
万物之父的方法
静态方法:
Object.Equals() 判断两对象是否相等
ReferenceEquals() 比较两对象引用是否相等
成员方法:
GetType() 返回对象运行时的类型Type
MemberwiseClone() 浅拷贝,保护类型方法,需要在内部调用,新创建的对象和拷贝的老对象是同一个引用
虚方法:
可以重写定义自己的规则
Equals()、GetHashCode()、ToString()
密封类 sealed
让一个类无法再被继承(断子绝孙)
密封方法
在父类的方法前使用sealed可使方法无法被子类使用
多态
继承同一父亲的子类,在执行相同方法(行为)时有不同的表现
编译时多态:函数重载
运行时多态:VOB(virtual、override、base)、抽象函数、接口
虚方法
子类可以选择是否实现,是否写逻辑(是否有方法体)
可以被重写
抽象类 abstract
不能被实例化的类
可以包含抽象方法
继承抽象类必须重写其抽象方法抽象函数
只能写在抽象类里
没有方法体(纯虚方法)
不能是私有的
接口 interface
是行为的抽象规范
和类的申明类似,遵循里氏替换原则
不包含成员变量,只包含方法、属性、索引器、事件
成员不能被实现、成员可不用访问修饰符但不能是私有的
接口不能继承类,但是可以继承接口
使用规范:
1、类可以继承多个接口
2、类继承接口后必须实现接口中所有成员
接口是用来继承的
不能被实例化,但是可以作为容器存储对象
父类接口 name = new 继承接口的子类()
语法:
接口命前加“I”
interface IJump{}
显示实现接口:
不同接口相同方法名情况下,使用接口名.方法名特指哪个接口下的方法。
name.way();
look.way();
命名空间
相同命名空间下不可有同名类、不同命名空间中允许有同名类
不同命名空间中的相互使用,需要引用命名空间(using)或指明出处
命名空间可以包裹命名空间
String
string本质是一个char数组
可通过ToCharArray()方法来获取指定位置的字符
字符串拼接:.Format
正向查找:IndexOf()
反向查找:LastIndexOf()
移除指定位置字符串:Remove() //会返回一个移除后新值,所以原字符串不会变,需重新赋值,下述方法同理
str = str.Remove(1);
Remove(1,5)重载:第一个参数指定位置,第二个参数为此位置向后移除字符个数
替换字符串:Replace()
大小写转换:ToUpper()、ToLower()
截取字符串:Substring()
字符串切割:Split()
StringBuilder
C#提供用于处理字符串的公共类
修改字符串而不创建新对象
需要频繁修改和拼接字符串可使用,能提升性能
初始化:StringBuilder str = new StringBuilder("114514")
每次往其中增加字符会自动扩容(以2^n增长)
增:.Append()、.AppendFormat()
插:.Insert()
删:.Remove()
查:str[0]
改:str[0] = "1919" //StringBuilder可以这么改,正常string是只读的
清:.Clear结构体和类的区别
1、结构体是值类型,存储在栈中。类是引用类型存储在堆中
2、结构体成员不能使用protected,变量不能指定初始值,不能申明无参构造、析构函数,不能被静态static修饰。而这些类可以
3、结构体申明有参构造后,无参构造不会被顶掉。而类会被顶掉
4、结构体不能被继承、类可以被继承
5、结构体需要在构造函数中初始化所有成员变量,不能在自己内部申明和自己一样的结构体变量。而类都可以
ps:结构体可以继承接口,因为接口是行为的抽象
如何选择结构体和类
1、想要用继承和多态时,直接淘汰结构体,比如玩家、怪物等
2、对象是数据合集时,优先考虑结构体,比如位置、坐标等
3、从类型上看,经常被赋值传递并改变赋值对象的对象,原对象不想跟着变化时,就用结构体。比如坐标、向量、旋转等
抽象类和接口的相同点
可被继承、可包含方法申明
不能直接实例化
子类必须实现未实现的方法
都遵循里氏替换原则
抽象类和接口的区别
1、抽象类中可以有构造函数和成员变量。接口中不能
2、抽象类只能被单一继承。接口可以被继承多个
3、抽象类可以申明成员方法、虚方法、抽象方法、静态方法。接口中只能申明没有实现的抽象方法
如何抽象类和接口
1、表示对象用抽象,表示行为拓展用接口
2、不同对象拥有的共同行为,往往可以用接口来实现
lei