0

所以我目前有一个地址簿程序(目的是基本的,因为不想写任何更花哨的东西)所以正在完成一个评估模块(这不是学校作业)。

我必须在这个模块中演示多态性、封装和继承。

我想知道实现 IEnumerable 是否算作如下所示的多态性?

public class AddressBookEnumerator : IEnumerator
{
    #region IEnumerable Implementation
    public Person[] Contacts;
    int Position = -1;

    public AddressBookEnumerator(Person[] ContactList)
    {
        Contacts = ContactList;
    }

    public bool MoveNext()
    {
        Position++;
        return (Position < Contacts.Length);
    }

    public void Reset()
    {
        Position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public Person Current
    {
        get
        {
            try
            {
                return Contacts[Position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
    #endregion
}

我只是想知道是不是因为继承了 IEnumerator 类,然后为我的特定类创建了具有不同行为的新方法?或者我只是误解了 IEnumerator 的工作原理。

4

3 回答 3

1

多态性是一个

允许使用统一接口处理不同数据类型的值的编程语言功能。

在提供的当前代码中,我只看到您操作的一种数据类型。

实现IEnumerable是关于订阅给定接口的合同,因此您的类型可能会像该接口一样受到威胁。我个人不会像示例那样演示代码。polymorphism

于 2012-10-05T10:07:07.900 回答
1

我会尝试快速分解它,

interface IOrganism
{
    string GetSpecies();
}

abstract class Animal : IOrganism
{
    abstract string GetSpecies();
}

class Rat : Animal
{
   public virtual string GetSpecies()
   {
      return "Ratus";
   }
}

sealed class BlackRat : Rat
{
    public override string GetSpecies()
    {
       return string.Format("{0} Ratus", base.GetSpecies()));
    }
}

Animal,Rat并且BlackRat都是多态的IOrganismRat并且与BlackRat是多态的Animal。最后,BlackRat是多态的Rat


这意味着,我可以写一个函数,

void OutputSpecies(IOrganism organism)
{
    Console.WriteLine(organism.GetSpecies());
}

它可以接受 的任何实现者IOrganism,无论是 是RatBlackRat还是未来的某个实现者,因为它们都是多态的IOrganism


因此,要回答最初的问题,实现一个接口,例如IEnumerable并将其用作函数的参数,就是使用多态性。但是,您的代码只是实现了IEnumerator,所以是一半。它显示了多态性的潜力,但在实践中没有多态性。

此外,IEnumerator用作示例可能会分散您对所需任务的注意力,您可能最好让您的示例更加抽象。

于 2012-10-05T10:22:18.390 回答
1

虽然您可以考虑将接口级别的类型视为多态性,但对于更学术的方法,他们可能更多地沿着这种思路思考?

在这里我们看到:

  • 从抽象基类继承Employee
  • 当我们提到GetBonusMultiplier方法时,封装/多态。我们能够从抽象基类中引用该方法,并且我们也不知道每种类型如何确定基乘数的内部结构。我们所知道/关心的是,当我们调用该方法时,我们会返回一个 int 值。

如果您想将 Employee 更改为接口IEmployee,那将很简单。不过,我可能仍然有某种抽象基础来捕获公共字段,因此您不必在每个实现的类中重新实现IEmployee.

class Program
{
    static void Main(string[] args)
    {
        var employees = new List<Employee>
        {
            new Manager(1, "Dave Smith"),
            new Director(2, "Peter Thompson")
        };

        foreach (Employee employee in employees)
        {
            Console.WriteLine(string.Format("Employee ID: {0}. Employee Name: {1}. Bonus Multiplier: {2}.", employee.Id, employee.Name, employee.GetBonusMultiplier()));
        }
        Console.ReadKey();
    }
}

abstract class Employee
{
    public int Id { get; protected set; }
    public string Name { get; protected set; }

    public abstract int GetBonusMultiplier();
}

class Director : Employee
{
    public Director(int employeeId, string name)
    {
        Id = employeeId;
        Name = name;
    }

    public override int GetBonusMultiplier()
    {
        return 3;
    }
}

class Manager : Employee
{
    public Manager(int employeeId, string name)
    {
        Id = employeeId;
        Name = name;
    }

    public override int GetBonusMultiplier()
    {
        return 2;
    }
}
于 2012-10-05T10:32:06.140 回答