先调用父类中的构造函数,再调用子类中的构造函数
public DrivedClass():base(){}
如果重载了构造函数
构造函数时候,可以使用冒号,将子类传入的参数传入父类的参数中。
传递到父类构造函数的参数不会自动赋值给子类,子类需单独处理自己的参数。
先调用父类中的构造函数,再调用子类中的构造函数
public DrivedClass():base(){}
如果重载了构造函数
构造函数时候,可以使用冒号,将子类传入的参数传入父类的参数中。
传递到父类构造函数的参数不会自动赋值给子类,子类需单独处理自己的参数。
抽象类
定义类的时候,添加abstract关键字
1、类似虚函数virtual,但必须被重写
2、抽象方法可以没有函数体
3、只能被继承,无法被实例化
只有abstract抽象类中,才能创建抽象方法
如果继承了抽象类,那必须实现抽象类中的抽象方法。
throw 抛出异常
密封类、密封方法
Sealed
密封类无法被继承
密封方法:
1、父类中必须包含vitual虚函数或abstract抽象方法
2、子类中进行override的时候,添加Sealed可以让其无法被再次重写(避免方法被多次重写,代码混乱)
sealed 是 override
的修饰,所以必须sealed override
隐藏方法和虚方法的区别
public new void 方法()
实际上是新建了一个方法
方法一:
使用new方式来实现重写
public new void CarInfo()
但严格意义上来说并不是重写,而是隐藏原有的方法新建一个同名的方法
方法二:
使用虚函数+override的方法来实现重写
1、首先要在父类中将可以重写的方法设置为vitual
2、在子类中使用override的方法进行重写
声明父类enemy,但构造的时候以子类enemy = new Boss(); 那么enemy构造后的实例就是子类
在 C# 中,当你使用 Enemy enemy = new Boss();
时,虽然实际创建的是 Boss
的实例,但通过 Enemy
类型的变量 enemy
访问它时,只能调用 Enemy
类中定义的方法和属性,无法直接访问 Boss
特有的成员。这是由 C# 的编译时类型检查和多态机制决定的。
Enemy enemy = new Boss();
这种写法看似反直觉,但它在面向对象编程(尤其是多态)中扮演着核心角色。是否需要避免这种写法,完全取决于具体场景。
核心目的:通过父类引用统一管理不同子类对象,运行时自动调用子类重写的方法。
this 可以访问本地类
base 专门用来访问父类,一般用来重写方法,很少用来重写数据
类中的访问权限
protected 只能被自己的成员访问
继承类的语法
Class 派生类名称:基类名称{}
子类继承父类,不能访问父类的私有数据成员(封装),但并不是无法访问,而是没有访问权限
继承
1、实现继承
2、接口继承
实现继承
基类(父类)、派生类(子类)
重写函数(方法)
多重继承的优缺点:C++,功能强大代码紧凑,多个父亲。C#、JAVA不支持。
但是,多重接口继承可以继承。
Object 是所有类的基类
将对象A赋值给对象B,对象B内的值修改,也会影响到对象A
赋值操作并没有创建一个新的对象(只有new才会创建新的对象),只是将内存引用地址赋值给了对象B
new 之后的对象,都存放在堆里面
对象名存放在栈中,对象的内容存放在堆之中
一个对象会被多个引用,GC将引用的数量做成计数器,当计数器为0后,则会被回收
类的空引用
c1 = null;
两个字符串类型的变量,对应的内容是一样的(处于静态存储区中的字符串)
静态存储区的内容是不可修改的
修改字符串变量只是修改了引用,而并没有修改字符串内容本本身(存在静态存储区)
栈:变量
堆:数组内容
静态存储区:字符串常量(节约内存空间,复用)
VS的自动生成功能
(右键)快速操作和重构-生成构造函数
GC 垃圾回收器
CLR是GC的内存管理机制
数据类型
1、值类型:枚举(对应一个数字)、结构体
2、引用类型:字符串(对应一个ASCII码)、数组、类
值类型:单独内存
引用类型:两段内存,1-实际数据(堆),2-指针(堆中的位置)
调试模式下显示内存信息,直接拖拽变量到窗口内,可查看内存地址
get 和 set 可以简写(不写任何方法)
通过创建属性,自动创建数据成员
var 匿名类型(不指定类型,根据后面的值来确定类型,确定之后就无法更改了)
数据成员一般都用private
使用set、get来获取和修改
void set
int get
通过定义一个属性,可以实现set和get(相当于这两个方法的简写)
set中,直接使用自带的value参数,给数据成员赋值
get中,可以直接return对应的数据成员,获取该数据成员的值
外部使用的时候,可以直接.属性值来使用对该属性的调用,调用其属性可以实现get方法,对其赋值可以实现set方法
另外,可以在set和get中继续撰写代码来实现功能(例如数值校验)
set和get可以设置为private,则外部访问时就会报错
如果我们定义了有参数的构造函数之后,创建类对象的时候就必须写上对应的参数,否则就会出错。
(VS会在创建对象的时候自动提示参数)
this 表示的当前对象(只有类中有这个参数,方法中并不含this)
值类型的默认值为0
引用类型的默认值是null
构造函数
每一个类必须有一个构造函数(会默认创建一个)
作用:构造对象的
1、和类名相同
2、无返回值
3、每一次调用类,都会创建一个新的构造函数
arg 参数 argument
通过撰写构造函数,可以在创建对象的时候,把数据当成参数直接传入。
可以在一个类中设置多个构造函数,利用重载的方式,创建类的对象的时候通过传入不同类型的参数,来实现静态多态(这个是函数重载,然而,一般意义上的多态指的是动态的多态,是在运行中通过重写的方式实现。)
类中变量的访问权限
private 只能在类内部访问
public 直接通过访问类来获取变量
通过公开的方法,来实现对数据的修改
public void SetX(Num)
{
X = Num;
}
使用类,创建对象
申明+赋值
Class1 c1 = new Class1();
类的对象必须赋值后使用
面向对象(object):模块化编程
正常项目几十万行代码
类:数据成员、函数成员
一个类,对应一个.cs文件(也可以包含多个类)
添加-新建项-类(可以选择多个类模板)
类和结构体类似
try 里面的语句都是局部变量
用while死循环,嵌套try和catch,如果catch捕捉到异常则一直循环,如果try语句通过就break跳出死循环。