为什么一个对象可以用父类声明,却用子类实例化

基本概念

这个实例是子类的,但是因为你声明时是用父类声明的,所以你用正常的办法访问不到子类自己的成员,只能访问到从父类继承来的成员。

在子类中用override重写父类中用virtual申明的虚方法时,实例化父类调用该方法,执行时调用的是子类中重写的方法;

如果子类中用new覆盖父类中用virtual申明的虚方法时,实例化父类调用该方法,执行时调用的是父类中的虚方法;

 /// <summary>  
 /// 父类  
 /// </summary>  
 public class ParentClass  
 {  
     public virtual void ParVirMethod()  
     {  
         Console.WriteLine("父类的方法...");  
     }  
 }  

 /// <summary>  
 /// 子类1  
 /// </summary>  
 public class ChildClass1 : ParentClass  
 {  
     public override void ParVirMethod()  
     {  
         Console.WriteLine("子类1的方法...");  
     }  
 }  

 /// <summary>  
 /// 子类2  
 /// </summary>  
 public class ChildClass2 : ParentClass  
 {  
     public new void ParVirMethod()  
     {  
         Console.WriteLine("子类2的方法...");  
     }  

     public void Test()  
     {  
         Console.WriteLine("子类2的其他方法...");  
     }  
 }  
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

执行调用:

ParentClass par = new ChildClass1();  
par.ParVirMethod(); //结果:“子类1的方法”,调用子类的方法,实现了多态

par = new ChildClass2();  
par.ParVirMethod();//结果:“父类的方法”,调用父类的方法,没有实现多态
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

深究其原因,为何两者不同,是因为原理不同:
override是重写,即将基类的方法在派生类里直接抹去重新写,故而调用的方法就是子类方法;而new只是将基类的方法在派生类里隐藏起来,故而调用的仍旧是基类方法。

应用举例

有这样的需要的,比如People类有一个Run方法,Man和Woman这两个类都是继承自People的类,并且都重写(override)了Run这个方法(男人女人跑起步来不一样).
现在有一群人一起跑步,有男人有女人.
我们可以把这些都装进一个People数组(假设为peoples).
然后

foreach(People p in peoples)//peoples中对象不同(即有男有女),用于实例化的子类就不同。
{
    p.Run();//故而,调用的方法也不同,实现了多态
}
 
 
  • 1
  • 2
  • 3
  • 4

由于多态性,在调用p.Run()的时候p对象本身如果是男人就会自动调用男人的Run方法,是女人就会调用女人的Run方法。

依赖倒置原则

依赖倒置原则,DIP,Dependency Inverse Principle DIP的表述是:
1、高层模块不应该依赖于低层模块,二者都应该依赖于抽象。 2、抽象不应该依赖于细节,细节应该依赖于抽象。 这里说的“依赖”是使用的意思,如果你调用了一个类的一个方法,就是依赖这个类,如果你直接调用这个类的方法,就是依赖细节,细节就是具体的类,但如果你调用的是它父类或者接口的方法,就是依赖抽象, 所以DIP说白了就是不要直接使用具体的子类,而是用它的父类的引用去调用子类的方法,这样就是依赖于抽象,不依赖具体。

其实简单的说,DIP的好处就是解除耦合,用了DIP之后,调用者就不知道被调用的代码是什么,因为调用者拿到的是父类的引用,它不知道具体指向哪个子类的实例,更不知道要调用的方法具体是什么,所以,被调用代码被偷偷换成另一个子类之后,调用者不需要做任何修改, 这就是解耦了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值