一、abstract抽象类
1.有抽象方法的类一定是抽象类,抽象方法只有方法定义没有方法体。
2.抽象类不能实例化
3.抽象方法必须是被子类重写的方法。
二、virtual关键字
有virtual修饰的方法可以被重写。
三、sealed类
1.被sealed修饰的类不能被继承
四、static类
静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量。在声明一个类时使用static关键字,具有两个方面的意义:首先,它防止程序员写代码来实例化该静态类;其次,它防止在类的内部声明任何实例字段或方法。
1、静态类的主要特性:
[1] 仅包含静态成员。
[2] 无法实例化。
[3] 静态类的本质,是一个抽象的密封类,所以不能被继承,也不能被实例化。
[4] 不能包含实例构造函数。
[5] 如果一个类下面的所有成员,都需要被共享,那么可以把这个类定义为静态类。
2、静态类与私有构造函数区别:
[1] 私有构造器方式仍然可以从类的内部对类进行实例化,而静态类禁止从任何地方实例化类,其中包括从类自身内部。
[2] 使用私有构造器的类中,是允许有实例成员的,编译器不允许静态类有任何实例成员。
[3] 使用静态类的优点在于,编译器能够执行检查以确保不致偶然地添加实例成员,编译器将保证不会创建此 类的实例。
[4] C#编译器会自动把它标记为sealed。这个关键字将类指定为不可扩展;换言之,不能从它派生出其他类。
3、类中的静态方法的调用:不能通过 对象.方法名调用,只能通过类名.方法名调用!!!
这里总结的挺有意思,帮助理解:https://zhidao.baidu.com/question/1865326161086272107.html
1. sealed——“断子绝孙”
密封类不能被继承。密封方法可以重写基类中的方法,但其本身不能在任何派生类中进一步重写。当应用于方法或属性时,sealed修饰符必须始终与override一起使用。
即:密封类不会有子类,所以是“断子绝孙”。
2. new——“你是我的,我是我的”
new关键字用于显式隐藏从基类继承的成员。也就是在使用派生类时调用的方式方法是new关键字新定义出来的方法,而不是基类的方法。
在不使用new修饰符的情况下隐藏成员是允许的,但会生成警告。使用new显式隐藏成员会取消此警告,并使用派生类新定义的方法。
即:好比是不用祖宗的东西,而是用自己创造(new)的东西。
3. virtual——“为了子孙后代”
virtual关键字用于修改方法或属性的声明,在这种情况下,方法或属性被称做虚成员。虚成员的实现可由派生类中的重写成员更改。
调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。
在默认情况下,方式是非虚拟的。非虚方法不能重写。
不能将virtual修饰符与一下修饰符一起使用:static、abstract和override。
除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。
在静态属性上使用virtual修饰符是错误的。
通过override修饰符的属性声明,在派生类中重写虚拟继承属性。
即:virtual是为了让子孙后代可以实现各自的梦想而做的。
4. abstract——“我是上帝”
abstract修饰符可以和类、方法、属性、索引器及事件一起使用。
在类声明中使用abstract修饰符,以指示该类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
抽象类具有以下特性:
抽象类不能实例化。
抽象类可以包含抽象方法和抽象访问器。
不能用sealed修饰符修改抽象类,这意味着该类不能被继承。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实现。
在方法或属性声明中使用abstract修饰符以指示此方法或属性不包含实现。
抽象方法具有以下特性:
抽象方法是隐式的virtual方法。
只允许在抽象类使用抽象方法声明。
抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在结束后没有花括号。
实现由override方法提供,它是非抽象类的成员。
在抽象方法声明中使用static或virtual修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
在静态属性上使用abstract修饰符是错误的。
在派生类中,通过包括使用override修饰符的属性声明可以重写抽象的基础属性。
即:abstract是一种抽象,好比上帝,是人们对神的抽象,看似什么都能干,其实什么都干不了。
5. override——“一手遮天e68a84e799bee5baa6e79fa5e9819331333363353838”
使用override修饰符来修改方法、属性、索引器或事件。主要是提供派生类对基类方法的新实现。覆盖上面abstract、virtual两种关键字修饰的成员。
由重写声明重写的方法称为重写基方法。重写基方法必须与重写方法具有相同的签名。
重写基方法必须是虚拟的、抽象或重写的。不能重写非虚方法或静态方法。
不能使用下列修饰符修改重写方法:new、static、virtual和abstract。
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。
即:override好比不但不用祖宗的那套,而且还自己创一套新功夫代替祖宗那套。
五、String与StringBuilder区别
C#中String 与StringBuilder的区别(转自:https://www.cnblogs.com/Echolh/p/11901412.html)
首先要明确一点, String是引用类型, String str=null 。 并且要知道String的值是不可变的。为什么String的值不可变?
这个地方我在网上查了一下,暂时没有好的答案,后面找到之后再补充。
String的不可变性举例来说: String a ="123"; a +="45"; 这个时候你可能会以为,a 的值明明变成了"123456".
但是实际情况是这样的。第一次string a ="123"; 堆上分配内存,存储值“123”,这里的 a 只是一个内存地址,指向堆上的"123",
当a+="45" 的时候,堆上又分配了一块内存,存放“12345”,这时候a 只是变成了指向"12345"地址的一个对象。
所以a 的值每次发生变更,实际上是新增了一个值,之前的"“123”并没有消失。所以在做string拼接字符串的时候,
特别是for循环中,使用a+=这种
的语法时,会造成大量的内存损耗。这时候就推荐使用StringBuilder对象了。StringBuilder拼接不会创建新的内存空间。
StringBuilder是一个可以拼接字符串的类,初始化时可以指定stringBuilder对象一个长度,StringBuilder中有一个int类型的Capacity属性,
用来指定stringBuilder中容器的长度。StringBuilder提供一个Append(string str)方法用于拼接字符串,并且可以自动检测字符串长度,
当长度超过之前指定的最大长度时,会自动增加一个capacity的长度。所以在进行大量字符串拼接时,应该使用StringBuilder对象。
六、类与结构体区别
https://www.runoob.com/csharp/csharp-struct.html
类和结构有以下几个基本的不同点:
- 1.类是引用类型,结构是值类型。
- 2.结构不支持继承。
- 3.结构不能声明默认的构造函数。