C#基础 继承和实例化
有代码如下,问输出的是多少:
class Program
{
static void Main(string[] args)
{
B b = new B();
Console.ReadKey();
}
class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields() { }
}
class B : A
{
int x = ;
int y;
public B()
{
y = -;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}", x, y);
}
}
}
结果:x=1;y=0;
刚开始有点不理解,觉得输出是x=1;y=-1;然后反编译看了下IL代码,然而。。还是没看出来,IL代码如下:
.class private auto ansi beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: nop
L_0007: ret
} .method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack
.locals init (
[] class ConsoleApplication1.Program/B b)
L_0000: nop
L_0001: newobj instance void ConsoleApplication1.Program/B::.ctor()
L_0006: stloc.0
L_0007: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
L_000c: pop
L_000d: ret
} .class auto ansi nested private beforefieldinit A
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: nop
L_0007: nop
L_0008: ldarg.0
L_0009: callvirt instance void ConsoleApplication1.Program/A::PrintFields()
L_000e: nop
L_000f: ret
} .method public hidebysig newslot virtual instance void PrintFields() cil managed
{
.maxstack
L_0000: nop
L_0001: ret
} } .class auto ansi nested private beforefieldinit B
extends ConsoleApplication1.Program/A
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack
L_0000: ldarg.0
L_0001: ldc.i4.1
L_0002: stfld int32 ConsoleApplication1.Program/B::x
L_0007: ldarg.0
L_0008: call instance void ConsoleApplication1.Program/A::.ctor()
L_000d: nop
L_000e: nop
L_000f: ldarg.0
L_0010: ldc.i4.m1
L_0011: stfld int32 ConsoleApplication1.Program/B::y
L_0016: ret
} .method public hidebysig virtual instance void PrintFields() cil managed
{
.maxstack
L_0000: nop
L_0001: ldstr "x={0},y={1}"
L_0006: ldarg.0
L_0007: ldfld int32 ConsoleApplication1.Program/B::x
L_000c: box int32
L_0011: ldarg.0
L_0012: ldfld int32 ConsoleApplication1.Program/B::y
L_0017: box int32
L_001c: call void [mscorlib]System.Console::WriteLine(string, object, object)
L_0021: nop
L_0022: ret
} .field private int32 x .field private int32 y }
}
IL代码
最后打断点,找到了原因

原因分析:
B b = new B();
执行顺序:
1、int x = 1;int y;给x赋值1,给y赋值默认为0(int类型)
2、public B(),然后关键点来了
3、public A(),执行A里面的PrintFields();但是A里面的这个方法是个虚方法,会调用B里面重写的方法
4、public override void PrintFields()这个是B里面的然后Console.WriteLine("x={0},y={1}", x, y);结果当然就是x=1;y=0;
5、然后才回到了B的public B(),接着给y赋值y = -1;这个时候y才变了,如果这个时候打印y的值才是-1,这个时候B的实例化就完成了
关键点:实例化类的时候,会先执行继承的父类的构造函数,如果父类构造函数含有虚方法又会回调子类的重写方法,之后才回到初始类的构造函数
C#基础 继承和实例化的更多相关文章
- python基础——继承和多态
python基础——继承和多态 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类.父类或超类 ...
- python基础——继承实现的原理
python基础--继承实现的原理 1 继承顺序 class A(object): def test(self): print('from A') class B(A): def test(self) ...
- python基础——继承与派生、组合
python基础--继承与派生 1 什么是继承: 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类成为基类或超累,新建的类成为派生类或子类 1.1 继承分为:单 ...
- api的使用机制:继承、实例化、实现(继承)配置、实例(参数化)配置、机制管理模块
api的使用机制:继承.实例化.实现(继承)配置.实例(参数化)配置.机制管理模块 facade模式.管理模块
- 《Java基础——继承》
Java基础--继承 一.类的继承: 规则: 1.一个子类只能有一个父类,但一个父类可以有多个子类,每个子类都可以作为父类使用. 2.若一个类没有声明父类,则默认其父类为Object. 3.父 ...
- JAVA基础-子类继承父类实例化对象过程
之前在项目中碰到这样一个问题: 类B继承了类A,B在实例化的时候,A的构造方法中调用了B的某个方法,并且B的方法中对B的成员属性进行了初始化,然后最后得到的B对象的成员属性为空. 代码场景如下: 这里 ...
- python基础----继承与派生、组合、接口与归一化设计、抽象类、子类中调用父类方法
一.什么是继承 继承是一种创建新的类的方式,在pyth ...
- 03Java基础——继承
1.继承 例如一个员工类,包括开发员工和经理. package cn.jxufe.java.chapter2.demo12; public class Employee { String name; ...
- Java 基础 - 继承
子类继承父类的private字段么? Oracle的Java Documentation对Inheritance的定义: 很直白,定义里面就告诉你了这不叫继承.继承的意思是你可以对其进行直接的调用和修 ...
随机推荐
- Redis查询&JDBC查询&Hibernate查询方式的效率比较...
比较三种查询方式查询效率对比...我是用的JavaWeb的方式通过通过JSP页面查询的填写查询的参数...给予反馈.... 整个demo的下载地址:http://files.cnblogs.com/f ...
- XSS、CSRF与验证码等等
XSS漏洞的原理 XSS是应用最为广泛的web安全漏洞之一,全称为跨站脚本攻击(cross site scripting),从名称来看,应该是css,但是和层叠样式表重叠,所以称为XSS,另外,在英文 ...
- android动态权限获取
android动态权限获取 Android6.0采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候 ...
- 【Spring】Spring MVC文件上传--整合bootstrap-fileinput和jQuery-File-Upload
前言 这里分享两个使用Spring MVC进行文件上传的简单示例, 分别整合bootstrap-fileinput 和 Jquery File Upload , 代码十分简单, 都是入门的示例,因此这 ...
- linux内核模块的安全
linux可以动态的加载内核模块,在很多场合可能需要确保加载内核的安全性.如果被攻击者加载恶意内核模块,将会使得内核变得极其危险. 当然,稳妥的做法就是给内核模块进行签名,内核只加载能正确验证的签名. ...
- 如何修复“sshd error: could not load host key”
问题:当我尝试SSH到一台远程服务器时,SSH客户端登陆失败并提示“Connection closed by X.X.X.X”.在SSH服务器那端,我看到这样的错误消息:“sshd error: co ...
- 【jQuery源码】事件存储结构
a. jQuery事件原型——Dean Edwards的跨浏览器AddEvent()设计 源码解读 重新梳理一下数据结构,使用一个例子 <input type="text" ...
- 安卓的SlidingMenu配置
最近用到了界面的优化,使用SlidingMenu开源库比较方便,为了方便学习,我整理了一下配置过程. 1.准备资料. 首先下载这两个ActionBarSherlock和SlidingMenu,如图:
- getCurrentSession 与 openSession() 的区别
1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会. 2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而ope ...
- PullToRefreshListView 进入界面不能立即显示刷新控件的bug 解决方案
1.首先定位到PullToRefreshListView.java这个文件 2.找到onRefreshing(final boolean doScroll)方法 @Override protected ...