C#'as'关键字和派生类

时间:2011-09-25 13:10:03

标签: c#

我正在努力通过“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,那么如何访问这些数据成员呢?

感谢您阅读此帖,我相信有人可以提供帮助。

我必须学习。

马特

3 个答案:

答案 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的实际类型执行相应的版本。它被调用了。

但是,您可以将实例转换为特定类型并访问其成员,如其他答案中所述。