new
C# new关键字表示隐藏,被new关键字修饰的属性或函数将对本类和继承类隐藏基类的同名属性或函数
using System;
using System.Collections.Generic;
using System.Text;
namespace firstt
{
class parent {
public virtual void outPut() {
Console.WriteLine("i'm parent");
}
}
class child : parent{
public new void outPut() {
Console.WriteLine("i'm child");
}
}
class Program
{
static void Main(string[] args)
{
parent p = new child();
p.outPut();//result is i'm parent
child c = new child();
c.outPut();//result is i'm child
Console.Read();
}
}
}
对于上面这个例子来说,假如运行 parent p = new child(); p.outPut();结果是 i'm parent ,这是因为child继承于parent,现在child中的outPut函数隐藏parent中的outPut,所以从child(包括继承于child的子类)的角度来看类中的outPut就是child.outPut,parent的outPut不可见,但是如果从parent的角度来看child,parent只认识类child中继承于parent的outPut函数,对于child中的outPut它不可见,所以parent
p = new child(); p.outPut();相当于是调用了类B中继承于parent的outPut函数
override
C#中override关键字表示重写,被override关键字修饰的属性或函数将完全覆盖基类的同名虚属性或虚函数,使基类的虚属性和虚函数在整个继承链中都不可见(在子类中用base关键字调用除外)。
using System;
using System.Collections.Generic;
using System.Text;
namespace firstt
{
class parent {
public virtual void outPut() {
Console.WriteLine("i'm parent");
}
}
class child : parent{
public override void outPut() {
Console.WriteLine("i'm child");
}
}
class Program
{
static void Main(string[] args)
{
parent p = new child();
p.outPut();
Console.Read();
}
}
}
对于上面这个例子来说,假如运行 parent p = new child(); p.outPut();结果是 i'm child,因为child的outPut函数完全覆盖基类的同名虚函数outPut,
使整个继承链中看见的outPut函数都是child中的outPut,所以就算是以parent 角度来看child,parent 看到的outPut函数也是child中的outPut,
因为parent 中的outPut完全被child的覆盖了
virtual和override声明多态方法时必须按一定规则:1、不能使用virtual或override关键字声明一个私有方法,否则出现编译错误,2、子类方法和父类方法必须具有相同的访问行
如果父类方法没有使用virtual那么子类不能override父类的该方法,否则出现编译错误
但是如果要在child的对象中调用parent 的outPut函数还是有办法,就是在子类中使用base关键字来调用父类的同名方法,比如
using System;
using System.Collections.Generic;
using System.Text;
namespace firstt
{
class parent {
public virtual void outPut() {
Console.WriteLine("i'm parent");
}
}
class child : parent{
public override void outPut() {
base.outPut();
Console.WriteLine("i'm child");
}
}
class Program
{
static void Main(string[] args)
{
parent p = new child();
p.outPut();//result is i'm parent i'm child
Console.Read();
}
}
}
这样先调用了父类的outPut方法在调用子类的方法