在我更多地了解多态性的过程中,我构建了一个小测试并且它返回了意想不到的结果。
所以我的想法是用虚拟/覆盖关键字覆盖基类方法,但似乎我不需要那些?
public class Employee
{
public Employee()
{
this.firstName = "Terry";
this.lastName = "Wingfield";
}
public string firstName { get; set; }
public string lastName { get; set; }
public void writeName()
{
Console.WriteLine(this.firstName + " " + this.lastName);
Console.ReadLine();
}
}
public class PartTimeEmployee : Employee
{
public void writeName()
{
Console.WriteLine("John" + " " + "Doe");
Console.ReadLine();
}
}
public class FullTimeEmployee : Employee
{
public void writeName()
{
Console.WriteLine("Jane" + " " + "Doe");
Console.ReadLine();
}
}
static void Main(string[] args)
{
Employee employee = new Employee();
PartTimeEmployee partTimeEmployee = new PartTimeEmployee();
FullTimeEmployee fullTimeEmployee = new FullTimeEmployee();
employee.writeName();
partTimeEmployee.writeName();
fullTimeEmployee.writeName();
}
}
使用上面的代码我期待结果如下:
但是下面的内容写入了控制台:
我认为后者不起作用,因为它需要ovrride关键字。
所以问题是为什么我没有适当的关键词看到后面的名字?
我希望这很清楚,可以阅读。
此致
答案 0 :(得分:5)
您展示的代码中没有多态性。
将其更改为:
Employee employee = new Employee();
Employee partTimeEmployee = new PartTimeEmployee();
Employee fullTimeEmployee = new FullTimeEmployee();
您将获得预期的结果。
更新
OOP中“多态”(多种形式)的概念意味着代码处理特定类型(基类或接口)的引用,而这些引用后面可能存在不同类型(后代,实现)的实例。对于“踢入”的多态,必须有继承和虚方法(在接口实现的情况下使用不同的术语,但让我们使用与您的代码示例相关的术语)。您有继承,但没有虚拟方法。对于常规(非虚拟)方法,方法调用在编译时根据调用方法的对象类型进行解析。
代码:
PartTimeEmployee partTimeEmployee = ...;
partTimeEmployee.writeName();
编译器清楚地知道调用哪个方法writeName
,它是PartTimeEmployee.writeName
。
同样,对于代码:
Employee partTimeEmployee = ...;
partTimeEmployee.writeName();
要调用的方法是Employee.writeName
。
答案 1 :(得分:4)
这称为方法隐藏。您只是在派生类中隐藏基类方法。您应该收到警告,但这完全合法。有关更多信息,请参阅documentation。您可能还想查看this问题
答案 2 :(得分:0)
对于多态行为,您override
和PartTimeEmployee
必须使用FullTimeEmployee
这些方法。你在那里做的是将方法隐藏在基类中。
public class Employee
{
public Employee()
{
this.firstName = "Terry";
this.lastName = "Wingfield";
}
public string firstName { get; set; }
public string lastName { get; set; }
public virtual void writeName()
{
Console.WriteLine(this.firstName + " " + this.lastName);
Console.ReadLine();
}
}
public class PartTimeEmployee : Employee
{
public override void writeName()
{
Console.WriteLine("John" + " " + "Doe");
Console.ReadLine();
}
}
public class FullTimeEmployee : Employee
{
public override void writeName()
{
Console.WriteLine("Jane" + " " + "Doe");
Console.ReadLine();
}
}
答案 3 :(得分:0)
使用C#,您可以使用“new”关键字重写基类的方法。如果省略此关键字,编译器将编译源代码,就像它存在一样。 所以我认为,问题是:新的和覆盖之间有什么区别?这是一个很大的不同。
“new”指示编译器使用您的实现而不是基类实现,但任何不直接引用您的类的代码都将使用基类实现。
“override”用于虚方法和抽象方法。这指示编译器使用方法的最后定义的实现。如果在对基类的引用上调用该方法,它将使用覆盖该对象的最后一个实现。
我希望我已经足够清楚了。