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的定义: 很直白,定义里面就告诉你了这不叫继承.继承的意思是你可以对其进行直接的调用和修 ...
随机推荐
- pythonweb框架Flask学习笔记02-一个简单的小程序
#-*- coding:utf-8 -*- #导入了Flask类 这个类的实例将会是我们的WSGI应用程序 from flask import Flask #创建一个Flask类的实例 第一个参数是应 ...
- leetcode-917-仅仅反转字母
题目描述: 给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转. 示例 1: 输入:"ab-cd" 输出:"dc-b ...
- 冒泡排序实现(Java)
冒泡排序是一种交换排序,它的基本思路是: 两两比较相邻记录的关键字,如果反序则交换,知道没有反序的记录位置. 依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数, ...
- 手机端布局,rem布局动态获取根字体大小
手机端布局,rem布局动态获取根字体大小. 以下代码: //rem布局动态获取根字体大小 function remDynamicLayout(){ var $windowWidth = $(windo ...
- CentOS7启动Tomcat报错:./startup.sh: Permission denied
错误信息:./startup.sh: Permission denied 执行./startup.sh,或者./shutdown.sh的时候, 报:Permission denied,因为是执行tom ...
- (转)用Python写堡垒机项目
原文:https://blog.csdn.net/ywq935/article/details/78816860 前言 堡垒机是一种运维安全审计系统.主要的功能是对运维人员的运维操作进行审计和权限控制 ...
- python的字符串连接操作符+
如图, 运行后提示错误,这是“+” 是字符串连接操作符,字符串连接只能在被连接的每一个都是字符串时起作用.而以上程序试图将一个字符串同一个非字符串连接会引发一个异常,所以会报错. 正确的为: 或者是:
- 《Android应用性能优化》2——内存、CPU、性能测评
4.高效使用内存 4.1 说说内存 Android设备的性能主要取决于以下三因素: CPU如何操纵特定的数据类型: 数据和指令需占用多少存储空间: 数据在内存中的布局 4.2 数据类型 int和lon ...
- Python -- 网络编程 -- 抓取网页图片 -- 豆瓣妹子
首先分析页面URL,形如http://dbmeizi.com/category/[1-14]?p=[0-476] 图片种类对应编号: 1:'性感', 2:'有沟', 3:'美腿', 4:'小露点', ...
- #pragma的一些用法
1.#pragma message message 参数:Message参数能够在编译信息输出窗口输出相应的信息,这对于源代码的信息控制特别重要,其使用方法为: #pragma message(&qu ...