0

So I currently have an address book program (purposely basic as didn't fancy writing anything more fancy) so a module of an assessment being done (this is not school work).

I have to demonstrate polymorphism, encapsulation and inheritance in this module.

I was wondering if implementing IEnumerable counts as polymorphism as shown below?

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
}

I only wonder if it is because of inheriting the IEnumerator class and then creating new methods with different behaviour in for my specific class? Or am I just misunderstanding how IEnumerator works.

sehe
  • 374,641
  • 47
  • 450
  • 633
Mike
  • 618
  • 2
  • 8
  • 27
  • 2
    Doesn't this really just come down to "define polymorphism" ? Also: it is **really** rare that you should write your own `IEnumerator` implementation - iterator blocks (`yield return`) are usually preferable. – Marc Gravell Oct 05 '12 at 10:06
  • You haven't inherited `IEnumerator`, its an interface so has no implementation to inherit. – Jodrell Oct 05 '12 at 10:07
  • Yes it is going to require a definition of polymorphism but also an explanation of how implementing this interface is or is not an example of polymorphism. – Mr. Mr. Oct 05 '12 at 10:08
  • Wasn't aware of the iterator blocks until you mentioned, had an issue with the code requiring the above to for-each through a list of the class People and so found this on MSDN and went with it. Thank you for the advice though it is noted. – Mike Oct 05 '12 at 10:10
  • However, every implementor of `IWhatever` is a polymorph of that interface and, therefore polymorphic with `IWhatever`. That would be polymorphism. By the same token, every inheritor od a base class is polymorphic with that base class. – Jodrell Oct 05 '12 at 10:10
  • I'm intrigued why you are having to demonstrate polymorphism if not for some kind of homework... – Chris Oct 05 '12 at 10:32
  • @Chris, I associate homework with college/school. It is for a work-based assessment run by the QA apprenticeship provider who hosted a 10 week course I went on through my current employer, sadly it is below the skill level I work on and I've viewed it as a time waste but need to do it. – Mike Oct 05 '12 at 10:33
  • Ah, makes sense. I'd probably call that homework in the spirit of how it is used on SO (I take it to mean in a question that its more about hints and explanations than just an answer). Then again I still refer to a night before work as a school night so I might not be normal in this regard. :) – Chris Oct 05 '12 at 11:15
  • Yeah your questioning of it was completely logical. Especially when I'm making an address book >.< In terms of calling it a school night I dont see why that isnt normal :) Is just the association of school with a night before where you dont want to be up till 4am :) I'd think along similar lines myself. – Mike Oct 05 '12 at 11:24

3 Answers3

1

Polymorphism is a

a programming language feature that allows values of different data types to be handled using a uniform interface.

In current code provided I see only one datatype you operate on.

Implementing IEnumerable is about subscribing to contract of a given interface, so your type can be threat like that interface. I, personally, would not dimonstrate this code like polymorphism example.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • Well, wikipedia [also says](http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming) "In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type C implements an interface that represents type B" - you could argue that implementing an interface is inherently polymorphic, i.e. the caller knows about the abstract type, but the code that executes is from the concrete type. – Marc Gravell Oct 05 '12 at 10:08
  • A previous question relating to his: http://stackoverflow.com/questions/6147658/are-interfaces-compatible-with-polymorphism – Mr. Mr. Oct 05 '12 at 10:09
  • @MarcGravell: yes I saw it, but I want to *manifest* a fact that to describe a polymorphism, it's not a good idea to show interface subscription. There are other much better, much more clear ways to show it. – Tigran Oct 05 '12 at 10:34
1

I'll try to break it down quickly,

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 and BlackRat are all polymorphic with IOrganism. Rat and BlackRat are polymorphic with Animal. Lastly, BlackRat is polymorphic with Rat.


This means, I can write a function,

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

It can accept any implementor of IOrganism, whether that be Rat, BlackRat or some future implementor, becuase they are all polymorphic with IOrganism.


So, to answer the original question, implementing an interface, like IEnumerable and using it as an argument to a function is using polymorphism. However, your code just implements IEnumerator, so is kind of half way there. It shows the potential for polymorphism but not polymorphism in practice.

Additionally, using IEnumerator as an example may distract from the desired task and you might be better to keep your example more abstract.

Jodrell
  • 34,946
  • 5
  • 87
  • 124
  • So following the comments about the original question, where does this leave the answer? With it is technically or? – Mike Oct 05 '12 at 10:24
  • Thankyou, the explanations have cleared my understanding around this area. – Mike Oct 05 '12 at 10:41
1

Whilst you can consider treating types at interface level as polymorphism, for the more academic approach, they are probably thinking more along these kind of lines?

Here we see:

  • Inheritance from the abstract base class Employee
  • Encapsulation / Polymorphism when we refer to the GetBonusMultiplier method. We are able to refer to the method from the abstract base class and we are also unaware of the internals of how each type determines the base multiplier. All we know / care is that when we call the method, we get an int value back.

If you wanted to change Employee to an interface IEmployee it would be simple. I would probably still have some kind of abstract base to capture the common fields though so you don't have to reimplement in each class that implements 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;
    }
}
Mike
  • 6,149
  • 5
  • 34
  • 45