new
和virtual
/之间有区别override
。
你可以想象,一个类在实例化时只不过是一个指针表,指向其方法的实际实现。下图应该可以很好地可视化这一点:
现在有不同的方法,可以定义一个方法。当与继承一起使用时,每个行为都不同。标准方式始终如上图所示。如果您想更改此行为,您可以将不同的关键字附加到您的方法中。
1.抽象类
第一个是abstract
。abstract
方法只是指向无处:
如果你的类包含抽象成员,它也需要标记为abstract
,否则编译器不会编译你的应用程序。您不能创建abstract
类的实例,但可以从它们继承并创建继承类的实例并使用基类定义访问它们。在您的示例中,这看起来像:
public abstract class Person
{
public abstract void ShowInfo();
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}
如果调用, 的行为会ShowInfo
因实现而异:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
Student
s 和Teacher
s 都是s Person
,但是当他们被要求提示有关自己的信息时,它们的行为不同。但是,要求他们提示信息的方式是一样的:使用Person
类接口。
那么,当您从 继承时,幕后会发生什么Person
?在实现ShowInfo
时,指针不再指向任何地方,它现在指向实际的实现!创建Student
实例时,它指向Student
s ShowInfo
:
2.虚拟方法
第二种方法是使用virtual
方法。行为是相同的,只是您在基类中提供了一个可选的默认实现。virtual
可以实例化具有成员的类,但是继承的类可以提供不同的实现。以下是您的代码实际应该如何工作的样子:
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
关键区别在于,基础成员Person.ShowInfo
不再指向任何地方。这也是为什么您可以创建以下实例的原因Person
(因此不再需要将其标记为abstract
):
您应该注意到,这看起来与现在的第一张图像没有什么不同。这是因为该virtual
方法指向一个实现“标准方式”。使用virtual
,您可以看出Persons
,它们可以(不是必须)为ShowInfo
. 如果您提供不同的实现(使用override
),就像我在Teacher
上面所做的那样,图像看起来与abstract
. 想象一下,我们没有为Student
s 提供自定义实现:
public class Student : Person
{
}
代码会这样调用:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
图像Student
看起来像这样:
3.神奇的`new`关键字又名“Shadowing”
new
更多的是解决这个问题。您可以在通用类中提供与基类/接口中的方法同名的方法。两者都指向他们自己的自定义实现:
实现看起来像您提供的那个。行为会有所不同,具体取决于您访问该方法的方式:
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
可能需要这种行为,但在您的情况下,它具有误导性。
我希望这能让你更清楚地理解事情!