C#基础知识系列七(base、this、new、override、abstract、virtual、static)
前言
本文主要来讲解一下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[];
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+;
static A() { }
} public class B
{
public static int Y=A.X+;
} 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+;
} public class B
{
public static int Y=A.X+;
static B() { }
} class Program
{
static void Main(string[] args)
{
Console.WriteLine("A.X={0},B.Y={1}",A.X,B.Y);
Console.ReadLine();
}
}
对比一下,这两个例子,如果你想的和你执行后的结果一致,那说明你应该已经明白它们的执行顺序了。
C#基础知识系列七(base、this、new、override、abstract、virtual、static)的更多相关文章
- 基础知识系列☞Abstract和Virtual→及相关知识
转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...
- 学习javascript基础知识系列第三节 - ()()用法
总目录:通过一段代码学习javascript基础知识系列 注意: 为了便于执行和演示,建议使用chrome浏览器,按F12,然后按Esc(或手动选择)打开console,在console进行执行和演示 ...
- IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路
1.引言 在即时通讯网经常能看到各种高大上的高并发.分布式.高性能架构设计方面的文章,平时大家参加的众多开发者大会,主题也都是各种高大上的话题——什么5G啦.AI人工智能啦.什么阿里双11分分钟多少万 ...
- 基础知识系列☞C#中→属性和字段的区别
"好吧...准备写个'基础知识系列',算是记录下吧,时时看看,更加加深记忆···" 其实本来准备叫"面试系列"... 字段.属性.你先知道的哪个概念? ***我 ...
- 学习javascript基础知识系列第二节 - this用法
通过一段代码学习javascript基础知识系列 第二节 - this用法 this是面向对象语言中的一个重要概念,在JAVA,C#等大型语言中,this固定指向运行时的当前对象.但是在javascr ...
- java基础解析系列(七)---ThreadLocal原理分析
java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...
- Linux基础知识第七讲,用户权限以及用户操作命令
目录 Linux基础知识第七讲,用户权限以及用户操作命令 一丶简介linux用户,用户权限,组的概念. 1.1 基本概念 1.2 组 1.3 ls命令查看权限. 二丶用户权限修改命令 1.chmod ...
- C# 基础知识系列- 3 集合数组
简单的介绍一下集合,通俗来讲就是用来保管多个数据的方案.比如说我们是一个公司的仓库管理,公司有一堆货物需要管理,有同类的,有不同类的,总而言之就是很多.很乱.我们对照集合的概念对仓库进行管理的话,那么 ...
- C# 基础知识系列- 9 字符串的更多用法(一)
0. 前言 在前面的文章里简单介绍了一下字符串的相关内容,并没有涉及到更多的相关内容,这一篇将尝试讲解一下在实际开发工作中会遇到的字符串的很多操作. 1. 创建一个字符串 这部分介绍一下如何创建一个字 ...
随机推荐
- C++类所占内存大小计算
C++类所占内存大小计算 说明:笔者的操作系统是32位的. class A {}; sizeof( A ) = ? sizeof( A ) = 1明明是空类,为什么编译器说它是1呢? 空类同样可以实例 ...
- Python开发之【简单计算器】
开发一个简单的python计算器 1.实现加减乘除及括号优先级解析 2.用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * ...
- [转]highcharts图表入门之:如何让highcharts图表自适应浏览器窗体的大小或者页面大小
本文转自: http://jsfiddle.net/vCZ8V/1/ http://www.stepday.com/topic/?740 http://blog.csdn.net/yueritian/ ...
- FIR数据广播结构-提高时钟速率
直接型的信号流图 采用转置得到广播结构的信号流图 对于一个常系数四阶的FIR滤波器 直接型的RT L结构如下: 转置后的RTL结构
- uva 120 stacks of flapjacks ——yhx
Stacks of Flapjacks Background Stacks and Queues are often considered the bread and butter of data ...
- Linux的交叉编译 及configure配置
这两天需要把一个CDVS的工程代码从Linux 平台上移植到ARM平台上,花了两天才搞定,之前很早申请的博客,到现在还没有技术文章会,以后决定凡是花两三天才搞定的东西都会把解决过程发到这里,很多东西靠 ...
- iOS开发之——制作framework静态库教程
环境: 硬件:macbook air 系统:OSX EI Capitan 版本:10.11.3 xcode : Version 7.2.1 (7C1002) 最近在做ios的静态库(据说framewo ...
- 利用python爬取海量疾病名称百度搜索词条目数的爬虫实现
实验原因: 目前有一个医疗百科检索项目,该项目中对关键词进行检索后,返回的结果很多,可惜结果的排序很不好,影响用户体验.简单来说,搜索出来的所有符合疾病中,有可能是最不常见的疾病是排在第一个的,而最有 ...
- SpringBoot 快速入门
本篇文章翻译来源为:http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/ 首先springboot ...
- github结合TortoiseGit使用sshkey,无需输入账号和密码
1.github上支持三种方式进行项目的clone https,ssh,subversion https://github.com/用户名/版本库.git ssh的方式 git@github.c ...