01 struct
结构是一种值类型,比如 int,无需 new 来实例化,它在栈中分配空间;而类是引用类型,它在堆中分配空间,栈中保存的只是引用。
由于结构是值类型,并且直接存储数据,因此在一个对象的主要成员为数据且数据量不大的情况下,使用结构会带来更好的性能。
class Program { static void Main(string[] args) { NewYorkTime? currentTime = null; // 结构类型也是值类型,可以声明为可空 } } struct NewYorkTime { private int hours, minutes, seconds; // 可定义构造函数,但不能定义无参构造函数 public NewYorkTime(int hh, int mm) { hours = hh; minutes = mm; seconds = 0; } }
02 abstract
作为 抽象类 和 抽象方法 的修饰
抽象类不可以实例化,只能作为其他类的基类
抽象方法只有签名,即函数名,返回值和参数列表,没有具体的函数体
当类继承抽象类时,需要实现 所有 的抽象成员,包括方法、属性等。
// 抽象类 public abstract class Person { public abstract string SayHello(); } // 派生类 public class Chinese : Person { public override void SayHello() { System.Console.WriteLine("您好"); } }
03 interface
接口是一种代码规范,继承该接口的 类和结构 需要实现其所有成员,接口不能包含数据和静态成员。
// 接口 public interface IPerson { // 默认为public,不需要加任何修饰符 void SayHello(); string Name { get; set; } } // 接口实现 public class American : IPerson { public void SayHello() { System.Console.WriteLine("Hello"); } public string Name { get; set; } }
interface 和 abstract 区别
类只能继承一个抽象类,但可以有多个接口
类继承接口后,需要实现其所有成员,包括方法、属性、事件等
04 virtual/override/new
virtual用于定义一个虚方法,且所定义的方法可以包含方法体,并且允许在派生类中重写override对象,重写之后父类中的方法即被覆盖。
new除了用于实例化对象之外,还可以作为修饰符,表示显式隐藏父类中同名的方法,但不覆盖父类中的方法。
public abstract class Person { // 不能包含方法体 public abstract void SayHello() ; // 可以有方法体 public virtual void SayHello1() { System.Console.WriteLine("Say something"); } } public class Chinese : Person { // 在派生类中重新实现虚方法 public override void SayHello1() { System.Console.WriteLine("您好"); } } public class Japanese : Person { // 注意new ,表示显式隐藏父类里的同名函数,而不是重新实现 public new void SayHello1() { System.Console.WriteLine("こんにちは"); } } // 执行基类方法 Person japaneseOne = new Japanese(); japaneseOne.SayHello1();// 输出结果“Say something” // 执行派生类方法 Japanese japaneseTwo = new Japanese(); japaneseTwo.SayHello1();// 输出结果“こんにちは”
05 sealed
密封类不能被继承,因此不能和abstract同时使用,密封方法表示重写后的方法不能再一次被重写,即必须与 override 连用。
通常用于实现第三方类库时不想被客户端继承,或用于没有必要再继承的类以防止滥用继承造成层次结构体系混乱,恰当的利用 sealed 修饰符也可以提高一定的运行效率,因为不用考虑继承类会重写该成员。
// 密封类 class A {} sealed class B : A {} // B继承A,但B不能被任何其他类继承 // 密封方法 public class A { protected virtual void M() { Console.WriteLine("A.M()"); } protected virtual void M1() { Console.WriteLine("A.M1()"); } } public class B : A { protected sealed override void M() { Console.WriteLine("B.M()"); } protected override void M1() { Console.WriteLine("B.M1()"); } } public sealed class C : B { /* ConsoleApplication1.MSFun.Sealed.C.M()': * cannot override inherited member 'ConsoleApplication1.MSFun.Sealed.B.M()' * because it is sealed */ //protected override void M() { Console.WriteLine("C.M()"); } protected override void M1() { Console.WriteLine("C.M1()"); } }