继承方法无法访问派生 class 中的新实现
Inherited method has no access to new implementation in derived class
在此 MSDN article 中引用:
derived class 的类型对象无法访问从 base class 继承的新的重新定义方法以及对 [=12] 的 derived class 对象的调用=]继承的方法DescribeCar()
里面的方法是对基础class.
的ShowDetails()
方法进行的
如果DescribeCar()
方法对ConvertibleCar
也可用class,怎么看不到所谓的new ShowDetails()
方法?
class Car
{
public void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
ShowDetails();
}
public virtual void ShowDetails()
{
System.Console.WriteLine("Standard transportation.");
}
}
// Define the derived classes.
// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails
// hides the base class method.
class ConvertibleCar : Car
{
public new void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
}
class Program
{
static void Main(string[] args)
{
ConvertibleCar car2 = new ConvertibleCar();
car2.DescribeCar();
}
}
//output
// Four wheels and an engine.
// Standard transportation.
new
隐藏旧方法,这意味着如果您直接在ConvertibleCar
上调用它例如,您将获得派生的 class 行为,但它不会被称为 多态性 。
当基础 class 调用它时,它正在调用虚拟方法,因为它没有被覆盖,所以调用基础 class 方法。不要使用方法隐藏(你几乎从来没有使用过),只需覆盖它:
class ConvertibleCar : Car
{
public override void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
}
好吧,当你考虑它时 - 想想 没有 继承 - 这就像问为什么 Car.DescribeCar
不能访问 ConvertibleCar.ShowDetails
。
ConvertibleCar.ShowDetails
本质上是一种方法,如果您愿意,它不是 Car
的成员 - 因为 new
关键字。 Car
然而有一个方法 ShowDetails
。
Car.DescribeCar
作为 Car
的成员方法,具有 Car.ShowDetails
而不是 ConvertibleCar.ShowDetails
的可见性,因此 Car.ShowDetails
被调用。
也许这样会更清楚。使用 new
关键字,这是另一种思考方式:
class Car
{
...
public virtual void ShowDetails(){..}
}
class ConvertibleCar : Car
{
public void new_ShowDetails(){}
}
Car
不了解 ConvertibleCar.new_ShowDetails
,因此无法调用该方法。
其他答案都是正确的,但我想举例说明 DescribeCar()
方法内部发生的情况。
public void DescribeCar()
{
Type t = this.GetType();
//bad hack
dynamic _this = Convert.ChangeType(this, t);
this.ShowDetails(); //Prints "Standard transportation."
_this.ShowDetails(); //Prints "A roof that opens up."
}
t
是 ConvertibleCar
因为它是对象的实际类型,但是 this
变量(实际上是编译器隐藏的每个非静态方法的参数) 的类型为 Car
.
virtual
方法的特殊之处在于,当它们被您的代码调用时,编译器会额外查找对象的实际类型(即调用 GetType()
)并检查是否层次结构中的任何类型都已覆盖该方法。然后它调用你的方法的最新实现。
但是,如果您使用 new
而不是 override
,则此查找不会产生任何结果,并且会使用基本实现。如果您使用 new
调用新实现的唯一方法是将您的变量转换为定义新实现的类型。
在此 MSDN article 中引用:
derived class 的类型对象无法访问从 base class 继承的新的重新定义方法以及对 [=12] 的 derived class 对象的调用=]继承的方法DescribeCar()
里面的方法是对基础class.
ShowDetails()
方法进行的
如果DescribeCar()
方法对ConvertibleCar
也可用class,怎么看不到所谓的new ShowDetails()
方法?
class Car
{
public void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
ShowDetails();
}
public virtual void ShowDetails()
{
System.Console.WriteLine("Standard transportation.");
}
}
// Define the derived classes.
// Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails
// hides the base class method.
class ConvertibleCar : Car
{
public new void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
}
class Program
{
static void Main(string[] args)
{
ConvertibleCar car2 = new ConvertibleCar();
car2.DescribeCar();
}
}
//output
// Four wheels and an engine.
// Standard transportation.
new
隐藏旧方法,这意味着如果您直接在ConvertibleCar
上调用它例如,您将获得派生的 class 行为,但它不会被称为 多态性 。
当基础 class 调用它时,它正在调用虚拟方法,因为它没有被覆盖,所以调用基础 class 方法。不要使用方法隐藏(你几乎从来没有使用过),只需覆盖它:
class ConvertibleCar : Car
{
public override void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
}
好吧,当你考虑它时 - 想想 没有 继承 - 这就像问为什么 Car.DescribeCar
不能访问 ConvertibleCar.ShowDetails
。
ConvertibleCar.ShowDetails
本质上是一种方法,如果您愿意,它不是 Car
的成员 - 因为 new
关键字。 Car
然而有一个方法 ShowDetails
。
Car.DescribeCar
作为 Car
的成员方法,具有 Car.ShowDetails
而不是 ConvertibleCar.ShowDetails
的可见性,因此 Car.ShowDetails
被调用。
也许这样会更清楚。使用 new
关键字,这是另一种思考方式:
class Car
{
...
public virtual void ShowDetails(){..}
}
class ConvertibleCar : Car
{
public void new_ShowDetails(){}
}
Car
不了解 ConvertibleCar.new_ShowDetails
,因此无法调用该方法。
其他答案都是正确的,但我想举例说明 DescribeCar()
方法内部发生的情况。
public void DescribeCar()
{
Type t = this.GetType();
//bad hack
dynamic _this = Convert.ChangeType(this, t);
this.ShowDetails(); //Prints "Standard transportation."
_this.ShowDetails(); //Prints "A roof that opens up."
}
t
是 ConvertibleCar
因为它是对象的实际类型,但是 this
变量(实际上是编译器隐藏的每个非静态方法的参数) 的类型为 Car
.
virtual
方法的特殊之处在于,当它们被您的代码调用时,编译器会额外查找对象的实际类型(即调用 GetType()
)并检查是否层次结构中的任何类型都已覆盖该方法。然后它调用你的方法的最新实现。
但是,如果您使用 new
而不是 override
,则此查找不会产生任何结果,并且会使用基本实现。如果您使用 new
调用新实现的唯一方法是将您的变量转换为定义新实现的类型。