前言

本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base、this、new、override、abstract、virtual以及针对static字段和static构造函数之间的执行问题。

base关键字

base 关键字用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数、实例方法和实例属性访问器中:

  • 调用基类上已被其他方法重写的方法。

public class Father

{

public virtual void Say()

{

Console.WriteLine("Father Say");

}

}

public class Son : Father

{

public override void Say()

{

base.Say();

Console.WriteLine("Son Say");

}

}

  • 指定创建派生类实例时应调用的基类构造函数。

public class Father

{

public string Name { get; set; }

public Father()

{

Name = "Father";

}

}

public class Son : Father

{

public Son()

: base()

{

}

}

从静态方法中使用 base 关键字是错误的。

this关键字

其用于引用类的当前实例,也包括继承而来的方法,通常可以隐藏this:

  • 限定被相似的名称隐藏的成员

public class Person

{

public string Name { get; set; }

public int Age { get; set; }

public Person(string Name, int Age)

{

this.Name = Name;

this.Age = Age;

}

}

  • 将对象作为参数传递到其他方法

public class Person

{

public string Name { get; set; }

public int Age { get; set; }

public Person(string Name, int Age)

{

this.Name = Name;

this.Age = Age;

}

public void CallTest(Person person)

{

Console.WriteLine(person.Name+person.Age);

}

public void Call()

{

CallTest(this);

}

}

  • 声明索引器

public class Person

{

string[] PersonList = new string[10];

public string this[int param]

{

get { return PersonList[param]; }

set { PersonList[param] = value; }

}

new关键字

一、new运算符

1、new一个class时,new完成了以下两个方面的内容:一是调用new class命令来为实例在托管堆中分配内存;二是调用构造函数来实现对象初始化。

2、new一个struct时,new运算符用于调用其带构造函数,完成实例的初始化。

3、new一个int时,new运算符用于初始化其值为0。

4、 new运算符不可重载。

5、new分配内存失败,将引发OutOfMemoryException异常。

二、new修饰符

new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然可以在不使用 new 修饰符的情况下隐藏成员,但会生成警告。 如果使

用 new 显式隐藏成员,则会取消此警告,并记录要替换为派生版本这一事实。

在子类中用 new 关键字修饰 定义的与父类中同名的方法,叫覆盖。 覆盖不会改变父类方法的功能。

public class A

{

public virtual void Test()

{

Console.WriteLine("A.Test()");

}

}

public class B : A

{

public new void Test()

{

Console.WriteLine("B.Test()");

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a.Test();

B b = new B();

b.Test();

A c = new B();

c.Test();

Console.ReadLine();

}

}

}

当用子类创建父类的时候,如 A c = new B(),覆盖不会改变父类的功能,仍然调用父类功能。(和override有区别,下面进行讲解)

三、new 约束

new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。 如果要使用 new 约束,则该类型不能为抽象类型。

当与其他约束一起使用时,new() 约束必须最后指定:

public class ClassA<T>where T : IComparable, new()

{

////

}

override关键字

要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。

由 override 声明重写的方法称为重写基方法。 重写的基方法必须与 override 方法具有相同的签名。

不能重写非虚方法或静态方法。 重写的基方法必须是 virtual、abstract 或 override 的。

用关键字 virtual 修饰的方法,叫虚方法。可以在子类中用override 声明同名的方法,这叫“重写”。相应的没有用virtual修饰的方法,我们叫它实方法。 重写会改变父类方法的功能。

public class A

{

public virtual void Test()

{

Console.WriteLine("A.Test()");

}

}

public class B : A

{

public override void Test()

{

Console.WriteLine("B.Test()");

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

a.Test();

B b = new B();

b.Test();

A c = new B();

c.Test();

Console.ReadLine();

}

}

new override

1、 不管是重写还是覆盖都不会影响父类自身的功能。

2、当用子类创建父类的时候,如 A c = new B(),重写会改变父类的功能,即调用子类的功能;而覆盖不会,仍然调用父类功能。

3、虚方法、实方法都可以被覆盖(new),抽象方法,接口 不可以。

4、抽象方法,接口,标记为virtual的方法可以被重写(override),实方法不可以。

5、重写使用的频率比较高,实现多态;覆盖用的频率比较低,用于对以前无法修改的类进行继承的时候。

abstract关键字

针对abstract关键字暂时总结了以下五点:

1.用关键字abstract定义的类即为抽象类,且只能作为基类,也不能被实例化。
2.用abstract定义的类不一定包含抽象方法,也可以包含非抽象方法。
3.abstract定义的方法一定包含在抽象类中。
4.抽象类不能定义为密封类(sealed),抽象方法不能使用virtual、static、private修饰符
5.如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。

virtual关键字

Virtual方法(虚方法)

virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:

情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。

情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

static字段和static构造函数

主要来说明执行的顺序:

  1、编译器在编译的时候,先分析所需要的静态字段,如果这些静态字段所在的类有静态的构造函数,那么就会忽略字段的初始化;如果没有静态的构造函数,那么就会对静态字段进行初始化。

  2、如果存在多个静态类,那么初始化的静态成员的顺序会根据引用的顺序,先引用到的先进行初始化,但如果类的静态成员的初始化依赖于其他类的静态成员,则会先初始化被依赖的静态成员。

  3、而带有静态构造函数的类的静态字段,只有在引用到的时候才进行初始化。

下面我们来看两个简单的小例子:

public class A

{

public static int X = B.Y+1;

static A() { }

}

public class B

{

public static int Y=A.X+1;

}

class Program

{

static void Main(string[] args)

{

Console.WriteLine("A.X={0},B.Y={1}",A.X,B.Y);

Console.ReadLine();

}

}

结果如何呢?再来看第二个小例子:

public class A

{

public static int X = B.Y+1;

}

public class B

{

public static int Y=A.X+1;

static B() { }

}

class Program

{

static void Main(string[] args)

{

Console.WriteLine("A.X={0},B.Y={1}",A.X,B.Y);

Console.ReadLine();

}

}

对比一下,这两个例子,如果你想的和你执行后的结果一致,那说明你应该已经明白它们的执行顺序了。

base、this、new、override、abstract、virtual、static的更多相关文章

  1. C#基础知识系列七(base、this、new、override、abstract、virtual、static)

    前言 本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base.this.new.override.abstract.virtual以及针对static字段和s ...

  2. C#基础知识(base、this、new、override、abstract、virtual、static)

    前言 本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base.this.new.override.abstract.virtual以及针对static字段和s ...

  3. C#中的Virtual、Override和new关键词理解

    来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...

  4. abstract、override、new、virtual、sealed使用和示例

    abstract修饰类名为抽象类,修饰方法为抽象方法.如果一个类为抽象类,则这个类智能是其他某个类的基类.抽象方法在抽象类中没有函数体.抽象类中的抽象方法是没有方法体的,继承其的子类必须实现抽象类的抽 ...

  5. c#中abstract、override、new、virtual、sealed使用

    abstract     修饰类名为抽象类,修饰方法为抽象方法.如果一个类为抽象类,则这个类智能是其他某个类的基类.抽象方法在抽象类中没有函数体.抽象类中的抽象方法是没有方法体的,继承其的子类必须实现 ...

  6. c#中abstract、override、new、virtual、sealed使用和示例

    原文地址:http://blog.csdn.net/richerg85/article/details/7407544 abstract      修饰类名为抽象类,修饰方法为抽象方法.如果一个类为抽 ...

  7. [C#] 區分 abstract、virtual、override 和 new

    abstract.virtual.override和new是在類別的繼承關係中常用的四個修飾方法的關鍵字,在此略作總結. 1. 常用的中文名稱: n   abstract => 抽象方法. n  ...

  8. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

  9. 一、重写(覆盖)override

    一.重写(覆盖)override 子类可以继承父类对象的方法,在继承后,重复提供该方法,就叫做方法的重写,又叫做覆盖override package property; //父类对象 public c ...

随机推荐

  1. 【bfs+优先队列】POJ2049-Finding Nemo

    基本上算是普通但略有些繁琐的广搜.给出的墙面和门的坐标为点,而Nemo位于方格中. [思路] 首先思考一下如何存储下整个坐标系.我们预先约定,用一个方格的左下角顶点坐标来作为这个方格的坐标.map[i ...

  2. SpringBoot 整合 Jpa

    项目目录结构 pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&quo ...

  3. Problem I: 零起点学算法88——青年歌手大奖赛_评委会打分

    #include<stdio.h> int main(void) { ],n,i; while(scanf("%d",&n)!=EOF) { n>& ...

  4. poj 1654:Area 区域 ---- 叉积(求多边形面积)

    Area   Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19398   Accepted: 5311 利用叉积求多边形面 ...

  5. 8VC Venture Cup 2016 - Final Round (Div. 2 Edition) D. Factory Repairs 树状数组

    D. Factory Repairs 题目连接: http://www.codeforces.com/contest/635/problem/D Description A factory produ ...

  6. GMT-CMSP系统维护步骤整理

    一.关闭前端各服务1.北京代理,韩国代理节点nginx/etc/init.d/nginx stop2.关闭WEB1,WEB2 NGINX和PHPpkill nginx && pkill ...

  7. Word中公式从单栏排版变为双栏排版后公式和编号错开了

    如上图公式(2),把自己做的共识从通栏复制到期刊的双栏里就变成这样了(先复制过来参考文献,再复制正文,那么参考文献没事),原来一直搞不懂,今天把它显示所有标记发现多了个制表符(我原来以为是行标记),鼠 ...

  8. windows 配置环境变量快捷方式

    在 Windows 设置环境变量 在环境变量中添加软件A的目录: 在命令提示框中(cmd) : 输入 path %path%;C:\A, 按下"Enter". 注意: C:\A是软 ...

  9. 转-"进程android.process.acore已意外停止" 解决办法

    运行手机虚拟机时,老是弹出这样的“android.process.acore“服务已意外停止,虽不影响正常使用,但终究影响心情.网上找的方案,按如下步骤操作,可以解决问题: 出现这个提示不用担心,并不 ...

  10. ubuntu安装elasticSearch及插件

    原文地址:http://www.niu12.com/article/18 前提 1.安装好Java1.8以上环境并配置好JAVA_HOME(elasticsearch运行环境) 2.node环境6.5 ...