我正在努力通过“Sams在21天内自学C#”,显然,这使我成为一名新手程序员。请不要太苛刻。到目前为止,客观,我觉得我已经很好地理解了这些主题。我不是在寻找答案,但希望能指出正确的方向。 :)
无论如何,我有这段代码:
// EXERCISE 11.4
using System;
public class Person
{
public string Name;
public Person()
{
}
public Person( string nm )
{
Name = nm;
}
public virtual void displayFullName()
{
Console.WriteLine( "Person {0}", Name );
}
}
class Employee : Person
{
//public ushort hireYear;
public Employee()
: base()
{
}
public Employee( string nm )
: base( nm )
{
}
public override void displayFullName()
{
Console.WriteLine( "Employee: {0}", Name );
}
}
class Contractor : Person
{
//public string Company;
public Contractor()
: base()
{
}
public Contractor( string nm )
: base( nm )
{
}
public override void displayFullName()
{
Console.WriteLine( "Contractor: {0}", Name );
}
public void DisplayCompany()
{
Console.WriteLine( "Company: {0}", Company );
}
}
class MyApplication
{
public static void Main()
{
Person [ ] myCompany = new Person[5];
int Counter = 0;
string Buffer, Buffer2;
do
{
do
{
Console.Write( "\nEnter \'c\' for Contractor, \'e\' for Employee then press ENTER: " );
Buffer = Console.ReadLine();
} while( Buffer == "" );
if( Buffer[0] == 'c' || Buffer[0] == 'C' )
{
Console.Write( "\nEnter the contractor\'s name: " );
Buffer = Console.ReadLine();
// DO OTHER CONTRACTOR STUFF
Contractor Contr = new Contractor( Buffer );
myCompany[Counter] = Contr as Person;
}
else if( Buffer[0] == 'e' || Buffer[0] == 'E' )
{
Console.Write( "\nEnter the employee\'s name: " );
Buffer = Console.ReadLine();
// DO OTHER EMPLOYEE STUFF
Employee emp = new Employee( Buffer );
myCompany[Counter] = emp as Person;
}
else
{
Person pers = new Person( "Not an Employee or Contractor" );
myCompany[Counter] = pers;
}
Counter++;
} while( Counter < 5 );
Console.WriteLine( "\n\n\n===========================" );
for( Counter = 0; Counter < 5; Counter++ )
{
if( myCompany[Counter] is Employee )
{
Console.WriteLine( "Employee: {0}", myCompany[Counter].Name );
}
else if( myCompany[Counter] is Contractor )
{
Console.WriteLine( "Contractor: {0}.", myCompany[Counter].Name );
}
else
{
Console.WriteLine( "Person: {0}", myCompany[Counter].Name );
}
}
Console.WriteLine( "===========================" );
Console.Read();
}
}
在练习中,我要修改Contractor或Employee类,并分别添加hireYear或Company数据成员。
看起来像这样:
class Employee : Person
{
public ushort hireYear;
public Employee()
: base()
{
}
public Employee( string nm )
: base( nm )
{
}
public Employee( string nm, ushort hy )
: base( nm )
{
hireYear = hy;
}
public override void displayFullName()
{
Console.WriteLine( "Employee: {0}", Name );
}
}
OR
class Contractor : Person
{
public string Company;
public Contractor()
: base()
{
}
public Contractor( string nm )
: base( nm )
{
}
public Contractor( string nm, string c )
: base( nm )
{
Company = c;
}
public override void displayFullName()
{
Console.WriteLine( "Contractor: {0}", Name );
}
public void DisplayCompany()
{
Console.WriteLine( "Company: {0}", Company );
}
}
对MainApplication的更改将是:
if( Buffer[0] == 'c' || Buffer[0] == 'C' )
{
string Buffer2;
Console.Write( "\nEnter the contractor\'s name: " );
Buffer = Console.ReadLine();
Console.Write( "\nEnter the contractor\'s company: " );
Buffer2 = Console.ReadLine();
Contractor Contr = new Contractor( Buffer, Buffer2 );
myCompany[Counter] = Contr as Person;
}
OR
else if( Buffer[0] == 'e' || Buffer[0] == 'E' )
{
string BufferHireYear;
Console.Write( "\nEnter the employee\'s name: " );
Buffer = Console.ReadLine();
Console.Write( "\nEnter the year employee was hired: " );
BufferHireYear = Console.ReadLine();
Employee emp = new Employee( Buffer, BufferHireYear );
myCompany[Counter] = emp as Person;
}
我认为,直到这一点,我都很开心。当我需要打印出结果时,我的困惑就开始了。我的想法是,当对象被“强制转换”回myCompany数组时,它们被添加为person类型的对象。 Person的类不包含数据成员Company或HireYear,那么如何访问这些数据成员呢?
感谢您阅读此帖,我相信有人可以提供帮助。
我必须学习。
马特
答案 0 :(得分:2)
您需要将对象强制转换回Employee
,以便您可以使用Employee
定义的成员。
Employee emp = (Employee)myCompany[Counter];
如果myCompany[Counter]
实际上不是Employee
,则会抛出InvalidCastException
。
将Employee
放入数组时,您无需强制转换,因为Employee
始终可以转换为Person
。
如果有可能无效,你只需要明确施放。
答案 1 :(得分:0)
如果您需要对每个子类型特殊的打印/处理,您可以在输出代码中处理每个子类型。
foreach (Person person in myCompany)
{
if (person is Employee)
{
Employee e = (Employee)person;
Console.WriteLine("HireYear: {0}", e.HireYear);
// etc..
另一种选择是Person基类提供抽象描述属性,每个子类都可以覆盖,然后输出函数可以在打印时调用描述。
答案 2 :(得分:0)
我可能会在这里跳过,但您可能会对“polymorphism”主题感兴趣。利用这里的多态性,而不是让调用代码根据Person的类型检索和打印各个细节,您只需告诉该人根据他们的类型打印或检索自己的详细信息。所以在这种情况下,如果你创建一个虚拟函数(类似于displayFullName)打印出这个实例的完整细节,你可以在该人身上调用它,它将根据Person的实际类型执行相应的版本。它被调用了。
但是,您可以将实例转换为特定类型并访问其成员,如其他答案中所述。