对象创建,父类子类转换,内存解析

每个对象本质上就是内存的一块空间,只是不同的对象占用不同的空间而已,声明变量就是告知我要这么大范围的一块空间进行访问,当真正new Object()
实例化的时候才真实给这个变量分配了一块空间,一般情况下都是你要多大的就实例化多大的不涉及类型转换,而如果你要的和分配的范围不一样就要涉及到类型转换了

//*****声明不需要类型转换的对象(声明的和分配的同样大小)*****
//ParentClass
PayInfo pay = new PayInfo();
pay.MerchantId = "pay";
//ChildClass
PayMsgContent msg = new PayMsgContent();
msg.TradeSerialNo = "msg";

//*****声明需要类型转换的对象(声明的和分配的不同大小)*****
/*
 * 【比如父类占用60的空间,子类占用100的空间】
 * 子类转父类:父类的变量可操作的范围小于子类对象分配的范围,编译器就会暂时把变量类型可以操作的部分(内存空间)给它操作,
 * 而不可操作的部分(内存空间)并不会被丢弃而是暂不可用的状态,而这种操作是安全的所以编译器可以通过
 */
PayInfo pay1 = new PayMsgContent();

/*
 * 父类转子类:子类的变量可操作的范围大于父类对象分配的范围,编译器就会告诉你“亲~需要类型转换后才可以呦~”,
 * 所以我们加上一个显式类型转换,但真正运行时还是会报错,告诉你“类型无法转换”因为实际实例化的是父类,
 * 它始终无法覆盖子类的范围所以无法转换,那既然无法转换,为什么又告诉我转换就可以呢?实际它真实的想法是下面的例子
 */ 
PayMsgContent msg1 = (PayMsgContent)new PayInfo();

//*****可以进行父类转子类的方式*****
//当声明父类变量而实例化是一个子类对象时,会直接分配一块子类对象范围的内存空间屏蔽掉其中属于子类的那部分来给父类变量使用,所以实际上它还是一个子类对象,只是使用父类引用来操作而已
PayInfo pay2 = new PayMsgContent();
//此时进行子类转父类的操作,会将这个对象中暂不可用的子类属性开启变成完整的子类对象,来赋给这个子类变量使用
PayMsgContent msg2 = (PayMsgContent)pay2;

 如果一定有业务操作需要父类转换子类的需求,可以使用如下方式实现 

//*****如果一定有业务操作需要父类转子类可以用下面方法*****
//1、父类创建参数为父类对象的有参构造
/*
public PayInfo(PayInfo payInfo)
{
    CustomerNo = payInfo.CustomerNo;
    AccountNo = payInfo.AccountNo;
    //do something...
}
 */
//2、子类创建参数为父类对象的有参构造并调用父类此有参构造
/*
public PayMsgContent(PayInfo payInfo) : base(payInfo)
{
    //do something...
}            
 */
//3、这样在我这个需求里就可以完成自动赋值的操作了
原文地址:https://www.cnblogs.com/taiyonghai/p/6515979.html