C# 为什么可以';编译器解析方法是否重写?
在下面的C#代码段中 要调用的方法在运行时确定。为什么编译器不知道调用哪个方法 为什么编译器没有看到C# 为什么可以';编译器解析方法是否重写?,c#,polymorphism,C#,Polymorphism,在下面的C#代码段中 要调用的方法在运行时确定。为什么编译器不知道调用哪个方法 为什么编译器没有看到a引用了Dog对象,然后从该类中选择方法 运行时如何确定要调用哪个方法?您告诉编译器该变量属于Animal类型。它只查看声明,而您希望它执行您的代码来理解您的意思。这不是它的工作原理。您告诉编译器该变量属于Animal类型。它只查看声明,而您希望它执行您的代码来理解您的意思。这不是它的工作原理。这听起来很像一个考试/家庭作业问题。但让我用另一个问题来回答你的问题。 考虑下面的代码: static
a
引用了Dog
对象,然后从该类中选择方法
运行时如何确定要调用哪个方法?您告诉编译器该变量属于Animal类型。它只查看声明,而您希望它执行您的代码来理解您的意思。这不是它的工作原理。您告诉编译器该变量属于Animal类型。它只查看声明,而您希望它执行您的代码来理解您的意思。这不是它的工作原理。这听起来很像一个考试/家庭作业问题。但让我用另一个问题来回答你的问题。 考虑下面的代码:
static void Main(string[] args)
{
var random = new Random();
Animal an = null;
if (random.NextDouble() < 0.5) {
an = new Dog();
} else {
an = new Cat();
}
an.MakeSound();
Console.ReadLine();
}
class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
MakeSoundAbstract(dog);
Animal an = new Animal();
MakeSoundAbstract(an);
Console.ReadLine();
}
static void MakeSoundAbstract(Animal animal)
{
animal.MakeSound();
}
}
static void Main(字符串[]args)
{
var random=新的random();
动物an=null;
if(random.NextDouble()<0.5){
安=新狗();
}否则{
an=新的Cat();
}
a.MakeSound();
Console.ReadLine();
}
编译器如何在编译时知道调用哪个方法?不能,只有在运行时才知道具体类型。这听起来很像考试/作业问题。但让我用另一个问题来回答你的问题。 考虑下面的代码:
static void Main(string[] args)
{
var random = new Random();
Animal an = null;
if (random.NextDouble() < 0.5) {
an = new Dog();
} else {
an = new Cat();
}
an.MakeSound();
Console.ReadLine();
}
class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
MakeSoundAbstract(dog);
Animal an = new Animal();
MakeSoundAbstract(an);
Console.ReadLine();
}
static void MakeSoundAbstract(Animal animal)
{
animal.MakeSound();
}
}
static void Main(字符串[]args)
{
var random=新的random();
动物an=null;
if(random.NextDouble()<0.5){
安=新狗();
}否则{
an=新的Cat();
}
a.MakeSound();
Console.ReadLine();
}
编译器如何在编译时知道调用哪个方法?不能,只有在运行时才知道具体类型。考虑以下代码:
static void Main(string[] args)
{
var random = new Random();
Animal an = null;
if (random.NextDouble() < 0.5) {
an = new Dog();
} else {
an = new Cat();
}
an.MakeSound();
Console.ReadLine();
}
class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
MakeSoundAbstract(dog);
Animal an = new Animal();
MakeSoundAbstract(an);
Console.ReadLine();
}
static void MakeSoundAbstract(Animal animal)
{
animal.MakeSound();
}
}
如果编译器将在编译期间而不是在运行时确定虚拟调用,则
MakeSoundAbstract
方法将始终执行MakeSound
类动物的方法,因此我们在这里失去了。考虑以下代码:
static void Main(string[] args)
{
var random = new Random();
Animal an = null;
if (random.NextDouble() < 0.5) {
an = new Dog();
} else {
an = new Cat();
}
an.MakeSound();
Console.ReadLine();
}
class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
MakeSoundAbstract(dog);
Animal an = new Animal();
MakeSoundAbstract(an);
Console.ReadLine();
}
static void MakeSoundAbstract(Animal animal)
{
animal.MakeSound();
}
}
如果编译器将在编译期间而不是在运行时确定虚拟调用,则MakeSoundAbstract
方法将始终执行MakeSound
类动物的方法,因此我们在这里失去了的功能。请考虑对代码的此更改:
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Purrrrrrrrrrrrrr");
}
}
class Program
{
static void Main(string[] args)
{
Animal an = GetAnimal(DateTime.Now);
an.MakeSound();
Console.ReadLine();
}
private Animal GetAnimal(DateTime dateTime)
{
if (dateTime.DayOfWeek == DayOfWeek.Monday)
{
return new Dog();
}
else
{
return new Cat();
}
}
}
现在不可能知道在编译时创建什么类型的动物,因为这取决于代码实际运行的日期。星期一你会得到一只狗,但在其他任何时候你都会得到一只猫。这是多态性的一个决定性优势——类型不是由编译器烘焙的,而是在代码执行时动态派生的。多态性允许您使用这些派生类型,即使您不知道在编写代码时它们将是什么(但您知道它们都是动物类型) 考虑一下对代码的这种更改:
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Purrrrrrrrrrrrrr");
}
}
class Program
{
static void Main(string[] args)
{
Animal an = GetAnimal(DateTime.Now);
an.MakeSound();
Console.ReadLine();
}
private Animal GetAnimal(DateTime dateTime)
{
if (dateTime.DayOfWeek == DayOfWeek.Monday)
{
return new Dog();
}
else
{
return new Cat();
}
}
}
现在不可能知道在编译时创建什么类型的动物,因为这取决于代码实际运行的日期。星期一你会得到一只狗,但在其他任何时候你都会得到一只猫。这是多态性的一个决定性优势——类型不是由编译器烘焙的,而是在代码执行时动态派生的。多态性允许您使用这些派生类型,即使您不知道在编写代码时它们将是什么(但您知道它们都是动物类型) 你听说过抽象吗?我的回答是“狗的声音”,如果我把它编译起来,我会觉得很好。他们没有问运行时的输出是什么。事实上,他们在实际问题中非常清楚地表明,他们知道在运行时发生了什么。问题是,为什么编译器在编译时不知道an
是Dog
。你听说过抽象吗?我的回答是,如果我编译这个,我觉得很好。他们没有问运行时的输出是什么。事实上,他们在实际问题中非常清楚地表明,他们知道在运行时发生了什么。问题是为什么编译器在编译时不知道an
是Dog
。