重写和隐藏的定义:
重写:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.
隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。
自己的理解:
比如父类A,有个方法标记为virtual,a(){}子类B继承A,也声明一个方法a(){}
如果B里面的a()使用override,那么访问A的方法时实际上调用了B里面声明的方法,相当于A的方法被覆盖了,new就不是,
访问A的a还是A里面定义的方法,访问B就是B里面定义的方法.
说白了:new是覆盖,override是重载,“覆盖”并不意味着“删除”,但“重载”意味着“删除”,
这就是“覆盖”和“重载”的区别
隐藏(new)示例:
用父类调用方法,就是父类的结果,除非是override重写了,发生了多态才是子类的方法结果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NewOveride
{
class Program
{
/*
重写和隐藏的定义:
重写:基类方法声明为virtual(虚方法),派生类中使用override申明此方法的重写.
隐藏:基类方法不做申明(默认为非虚方法),在派生类中使用new声明此方法的隐藏。
自己的理解:
比如父类A,有个方法标记为virtual,a(){}子类B继承A,也声明一个方法a(){}
如果B里面的a()使用override,那么访问A的方法时实际上调用了B里面声明的方法,相当于A的方法被覆盖了,new就不是,
访问A的a还是A里面定义的方法,访问B就是B里面定义的方法.
说白了:new是覆盖,override是重载,“覆盖”并不意味着“删除”,但“重载”意味着“删除”,
这就是“覆盖”和“重载”的区别
隐藏(new)示例:
*/
static void Main(string[] args)
{
int aa=0;
B b = new B();
b.ClassA();
A a = b;
a.ClassA();
Console.WriteLine("\n");
B2 b2 = new B2();
b2.ClassA2();
A2 a2 = b2;
a2.ClassA2();
Console.ReadKey();
}
}
//
class A
{
public void ClassA()
{
Console.WriteLine("A.ClassA()");
}
}
class B : A
{
new public void ClassA()
{
Console.WriteLine("B.ClassA()");
}
}
//
class A2
{
public virtual void ClassA2()
{
Console.WriteLine("A2.ClassA2()");
}
}
class B2 : A2
{
public override void ClassA2()
{
Console.WriteLine("B2.ClassA2()");
}
}
}
内存地址 分析(不一定理解的正确)
在即时窗口 用 &变量名 打印内存地址
======================
&aa int型
0x0694e9c8 栈地址
*&aa: 0 栈值
&b 引用型
0x0694e9c4 栈地址
*&b: {50730256} 栈值:保存的对应的堆上的地址
*&b
{50730256} 堆地址
m_value: 0x03061510 堆内的值
&a 引用型 地址同上b
0x0694e9c0
*&a: {50730256}
*&a
{50730256}
m_value: 0x03061510
*&aa 直接打印int型aa的栈地址中的值
0
这段我也分析不明白了。。。。。。
说明: A a = b; 这种 多态后,a内部指向的仍然是b 的地址,没有new 就没有开辟新的堆空间。
所以后面 a.ClassA(); 与 a2.ClassA2(); ,
本质上的地址是 b.ClassA(); 与 b2.ClassA2() 的地址调用。
因为B 类型,ClassA() 是new , B2类型 ClassA()的ovveride 。
下面怎么写。。。。。。。