views:

565

answers:

9

Can you give me an almost overly simplistic understanding of abstract class vs inheritance use and help me so I can truly understand the concept and how to implement? I have a project I'm trying to complete, and am lost on how to implement. I've been chatting with my professor and been told off pretty much, saying that if I can't figure it out, I'm probably not ready for the course. I have OVERCOVERED the prerequestite courses, and still have trouble understanding these concepts.

To clarify, the project as I've done so far is below. I don't have the dog/cat classes etc filled out yet. Can you give me a pointer. I'm not asking for anyone to give me the "answers." I just am lost on where to go with this. I take online courses and his communication efforts with me have been troubling. I just finished with 4.0 with all my other courses, so I'm willing to put the effort in, but I'm lost in the comprehension of these concepts and how to PRACTICALLY apply them.

Any comments or help that will let me progress further in this project?

The description of what I'm to implement is as follows:

Overview:

The purpose of this exercise is to demonstrate the use of Interfaces, Inheritance, Abstract classes, and Polymorphism. Your task is to take the supplied program shell and ADD the appropriate classes and corresponding class members/methods to get this program to function correctly. You may not make changes to any of the code supplied, you may only add the classes you write. Although there are numerous ways to get the program working, you must use techniques that demonstrate the use of Interfaces,
Inheritance, Abstract classes, and Polymorphism. Again, to make clear, you can add to the supplied code but you cannot change or delete any of it. The code that is supplied will work with very little additional code and will satisfy the requirements of the exercise.

If you successfully complete the assignment, your program should output the following statements when run:

My name is Spot, I am a Dog

My name is Felix, I am a Cat

Requirements:

1) You must have an abstract base class called 'Animal' from which the Dog and Cat classes derive.

2) The Animal base class must derive from the Interface 'IAnimal', it is the only class that should derive from IAnimal.

3) Since all animals have a name and a name is not an attribute that is specific to a dog or a cat, the Animal

base class should be where the name is stored and where the WhatIsMyName get-property is implemented.

4) You will need to create a Dog and a Cat class that will derive only from the Animal base class.

5) The Dog and Cat classes should implement the WhatAmI get-property and return the appropriate string value.

Code you can't change:

using System;

namespace IT274_U2
{
    public interface IAnimal
    {
        string WhatAmI { get; }
        string WhatIsMyName { get; }
    }

    public class TesterClass
    {
        public static void DescribeAnimal(IAnimal animal)
        {
            Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI);
        }

        static void Main(string[] args)
        {
            Dog mydog = new Dog("Spot");
            Cat mycat = new Cat("Felix");
            DescribeAnimal(mydog);
            DescribeAnimal(mycat);
        }
    }
}

///////////////////////

Code I've written so far:

using System;

namespace IT274_U2
{
    public interface IAnimal
    {
        string WhatAmI { get; }
        string WhatIsMyName { get; }
    }


    public class Dog
    {
        public abstract string WhatAmI
        {
            get;
            set;
        }
    }//end public class Dog

    public class Cat
    {
    public abstract string WhatIsMyName  
    {
        get;
        set;
    }
    }//end public class Cat

    public abstract class Animal : IAnimal
    {
    // fields
    protected string Dog;
    protected string Cat;

                  // implement WhatIsMyName 

    //properties
    public abstract String Dog
    {
        get;  
        set;
    }
    public abstract String Cat
    {
        get;
        set;
    }
    public abstract string WhatIsMyName();

    } //end public abstract class Animal


    public class TesterClass
    {
        public static void DescribeAnimal(IAnimal animal)
        {
            Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI);
        }

        static void Main(string[] args)
        {

            Dog mydog = new Dog("Spot");
            Cat mycat = new Cat("Felix");
            DescribeAnimal(mydog);
            DescribeAnimal(mycat);
        }
    }
}
+6  A: 

The main difference between an interface and an abstract class is that in the interface you only define what should be the public methods and properties of the object that implements this interface. An abstract class provides some base implementation, but has some "gaps" - abstract methods that the inheritor needs to implement.

I am not going to do your homework for you, but a hint: the Animal class should NOT contain anything specific for dogs and cats.

Grzenio
A: 

Abstract Classes: Establish a base for derived classes they provide a contract for all derived classes. It enforces heirarchies

Interfaces:

An interface is not a class, its a definition of methods.

A class can inheirt multiple interfaces but only one abstract class.

I hope that helps

CodeMonkey
"An interface is not a class, its a definition of methods" OH... i thought it was a type of a class?? you're saying it isn't? That does help a lot!
Sheldon
"an interface is a special kind of C# class that supports polymorphic stustituion and latebinding without inheritance." Modern Software Design - RIchard Weiner This supposedly contradicts the statement that an interface isn't a class, any comment?
Sheldon
@Sheldon I stand by my comment that an interface is not a class it is a contract
CodeMonkey
+3  A: 

You're close, but making this tougher than it needs to be.

I don't want to give you the answer ;) but here are a few pointers.

First, you're creating 3 classes and 1 interface. However, the one thing I believe you may be missing is that you need 3 different types of objects here (from "least defined" to "most defined"):

1) Interface
This is IAnimal - and can be implemented by anything that can act like an animal

2) Abstract Base Class This is the Animal calss - anything that IS an animal should derive from Animal, but these aren't creatable directly. If you pretend you're God, you don't make an Animal, you make a Dog, Cat, Squirrel, or FuzzyBunny

3) Concrete Implementation of Animal These are the actual classes themselves. This is what you create. Dog or Cat in your case.

The trick here is that you can only create concrete classes, but you can use IAnimal or Animal (interfaces or abstract base classes) to manipulate and work with any animal (or, in the case of interfaces, anything that acts like an animal)

Reed Copsey
thanks very much for the thorough answer. I need the pointers, not the answers. I'm just confused, so this kind of help will greatly speed me along instead of giving up! Lunch times a coming and I'll be reading all answers and working through my project to finish today. REALLY appreciate the help
Sheldon
Reread what I posted, and take a look at your Dog and Cat classes - Any use of "abstract" on a single property makes the class an abstract class, so you're forcing Dog and Cat to be my category 2.Take a look at the "override" keyword in C# - it may help get you a little further.
Reed Copsey
+1  A: 
  1. An interface is a contract. This is the place where you want to describe the functionalities you'll provide, without any implementation details

  2. An abstract class is a class whose purpose is to share implementation details between its sub-classes. Since it's here only for code sharing/factorisation purposes, it cannot be instantiated

  3. your actual class will inherit from your abstract class, and implement its class-specific functionalities while using the code shared in the abstract class if needed.

Brann
A: 

Basically, an interface defines a 'contract' (i.e. a set of operations/properties) that all implementers must provide. In this case the IAnimal interface requires the WhatAmI and WhatIsMyName properties. Abstract classes may provide certain functionality, yet will also leave some operations which must be implemented by their subclasses.

In the case of your example, the Animal base class is able to provide the WhatIsMyName functionality since 'Name' is a property of all animals. However, it cannot provide the 'WhatAmI' property, since only specific subclasses know what 'type' they are.

The problem with the sample code you posted, is that thet Animal class has knowledge of it's subclasses, which it should not have

Lee
I don't want to downvote because this is a technically correct answer, but given that it's clear the poster is trying to understand this for a homework assignment, I find the fact that you've given him most of the answer disappointing.
Mike Powell
good point... i'm not one to copy and paste abuse though, so it shouldn't be an issue. I do feel like i got maybe a little TOO much help though. I'll take what I can get though, I've spent almost 2 weeks stuck not understanding.
Sheldon
A: 

Another suggestion - (slightly off topic, but still related)

I recommend, for learning purposes, to avoid automatic properties. It will help you understand what's happening if you implement them explicitly.

For example, instead of doing:

class SomeClass { public string MyProperty { get; set; } }

Try implementing this yourself:

class SomeClass
{
    public string MyProperty
    {
        get
        {
             return "MyValue"; // Probably a private field
        }
        set
        {
             // myField = value; or something like that
        }
}

I mention this because it will help you in this specific case. Since you're using automatic properties, the compiler is "filling in the blanks" for you, and in your case, I think it's preventing you from getting some very useful compiler errors. When trying to understand how these concepts work, doing the work yourself usually makes it easier, not harder.

Reed Copsey
+3  A: 

EDIT:

I have taken the body of code for each class out - If you want to see my answer, have a look at the edit revisions :)

First off we define the interface

public interface IAnimal
{
    string WhatAmI { get; }
    string WhatIsMyName { get; }
}

Any class that implements this interface must implement these properties. An interface is like a contract; a class implementing an interface agrees to provide an implementation of the interface's methods, properties events or indexers.

Next, we need to define your abstract Animal class

public abstract class Animal : IAnimal
{
    //Removed for Training, See Edit for the code
}

The fact that the class is abstract indicates that the class is intended only to be a base class for other classes. We have implemented both properties of the interface and also have a private field to store the animal name. In addition, we have made the WhatAmI property accessor abstract so that we can implement our own specific property accessor logic in each derived class and have also defined a constructor that accepts a string argument and assigns the value to the _name private field.

Now, let's define our Cat and Dog classes

public class Dog : Animal
{
    //Removed for Training, See Edit for the code
}

public class Cat : Animal
{
    //Removed for Training, See Edit for the code
}

Both classes inherit from Animal and each has a constructor that defines a string argument and passes that argument as a parameter to the base constructor. In addition, each class implements it's own property accessor for WhatAmI, returning a string of their type, respectively.

For the rest of the code

public class Program
{
    public static void DescribeAnimal(IAnimal animal)
    {
        Console.WriteLine("My name is {0}, I am a {1}", animal.WhatIsMyName, animal.WhatAmI);
    }

    static void Main(string[] args)
    {
        Dog mydog = new Dog("Spot");
        Cat mycat = new Cat("Felix");
        DescribeAnimal(mydog);
        DescribeAnimal(mycat);
        Console.ReadKey();
    }
}

the static method DescribeAnimal accepts an IAnimal as an argument and writes out the values returned by the WhatIsMyName and WhatAmI property accessors for the passed in IAnimal.

Since Animal implements IAnimal and both Dog and Cat inherit from Animal, any Cat or Dog object can be passed as a parameter to the DescribeAnimal method.

I hope that I have explained this clearly, If anyone feels my choice of words needs tightening up, please comment and I will be happy to edit my answer.

Russ Cam
honestly, I've been avoiding reading all your commentary in full since I don't like "reading" the answer to my project, but fyi the link you gave to MSDN gave "sample" code that has helped me move my project along thanks for the help there!
Sheldon
good stuff :) Let me know if you want me to delete my answer, or leave it to come back to once you've got your solution
Russ Cam
no, i appreciate the help, i'll review it after i'm done on my side to see if i've got the idea right. this has actually been much harder for me to understand than most concepts... the textbook really sucks, i have a high reading level, but its so dry, i get 1-2 paragraphs before losing focus
Sheldon
btw thanks for taking out all the extra code, that helps, i'll be reading it through since i've spent this whole last hour still frustrated and trying to go through all these answers and understand without just "taking" the answer from code.
Sheldon
I second my recommendation for Head First Design Patterns, or Head First C#. Both books are well written and break each topic down into easily digestible chunks, with memorable examples.
Russ Cam
Head First Design Patterns is written for Java but the differences are minimal
Russ Cam
thanks you guys submitted project, russ's answer gave me the most useful info and breakdown to understand, i typically am not this lost, first time ever, but your breakdown and explanation helped me with my course, thanks.
Sheldon
+1  A: 

To be honest it scares me the amount of people in the industry that don't know this regardless of whether it is a homework question or not. Therefore I will answer.

Interfaces abstract implementation and so do abstract classes. There is no "vs" because you can create an abstract class that implements an interface too. So don't think they're at war with one another.

Therefore EITHER can be used when you don't want the consumer to know too much about the implementation. An interface is a bit better at this job because it has no implementation, it just states what buttons the consumer can press the values they get back and send where an abstract class may state a bit more than this (or even a lot more!). So if you just take this point onboard you only really need interfaces. Ergo, point two:

As abstract class is used when you want to share common code between two different implementations of an interface. In this scenario two concrete implementations both inherit from the abstract class which implements the interface.

Simple example is IDataStore. SavingToATextFile datastore is just a class that implements IDataStore. However MsSqlDataStore and MySqlDataStore will share common code. They will both inherit from the abstract class SqlDataStore which implements IDataStore.

Quibblesome
+1  A: 

Generally speaking:

  • An interfaces describe the methods an object will respond to. It is a contract the object commits to satisfy.

  • Abstract classes describes basic functionality and let specialized functionality to a subclass.

So, basically you use an interface when you want that objects different in nature, respond to the same specific method.

And you use an abstract class when you need to have specialized versions of some class.

Let's say you want to create a system where any kind of object may be identified by an unique id, and you don't care the class they belong to.

You may have:

  • Animals

  • Transport

  • Computer gadgets.

  • Whatever.

Since they are unrelated topics, you may choose to implement and interface, let's say:

public interface IIdentifiable 
{ 

      public long GetUniqueId();
}

And all the classes that want to satisfy this contract will implement that interface.

public class IPod: IIdentifiable 
{
      public long GetUniqueId() 
      {
           return this.serialNum + this.otherId;
      }
}

public class Cat: IIdentifiable 
{
      public long GetUniqueId()
      { 
           return this.....
      }
}

Both, and IPod and a Cat, have very different natures, but they both may respond to the "GetUniqueId()" method, that will be used in the catalog system.

Then it may be used like this:

    ...

    IIdentifiable ipod = new IPod(); 
    IIdentifiable gardfield = new Cat();

    store( ipod );
    store( gardfield );


    ....
    public void store( IIdentifiable object )  
    {

         long uniqueId = object.GetUniqueId();
        // save it to db or whatever.
    }

On the other hand, you may have an abstract class defining all common behavior the object may have, and let the subclass define specialized versions.

  public abstract class Car 
  {
       // Common attributes between different cars
       private Tires[] tires; // 4 tires for most of them 
       private Wheel wheel; // 1 wheel for most of them.

        // this may be different depending on the car implementation.
       public abstract void move(); 
  }


  class ElectricCar: Car 
  {
      public void move()
      {
         startElectricEngine();
         connectBattery();
         deploySolarShields();
         trasnformEnertyToMovemetInWheels();
      }
  }

  class SteamCar: Car 
  {     
       public void move() 
       {
          fillWithWather();
          boilWater();
          waitForCorrectTemperature();
          keepWaiting();
          releasePreasure....
        }
   }

Here, two kinds of cars, implements the "move" method in different ways, still they share common things in the base class.

To make things more interesting, these two cars may implement also de IIdentifiable interface, but by doing so, they are just commiting to respond to the GetUniqueId method, and not by the nature of being cars. That's why the Car it self may not implement that interface.

Of course, if the identification may be based on the common attributes the cars may have, the GetIdentifiableId may be implemented by the base class and the subclasses will inherit that method.

// case 1 ... each subclass implements the interface

   public class ElectricCar: Car, IIdentifiable 
   {
       public void move()
       {
         .....
       }
       public long GetUniqueId() 
       { 
         ....
       }
   }

   public class SteamCar: Car, IIdentifiable 
   {
       public void move()
       {
         .....
       }
       public long GetUniqueId() 
       { 
         ....
       }
  }

Case 2, the base class implements the interface and the subclass benefit from it.

   public abstract class Car: IIdentifiable 
   {
       // common attributes here
       ...
       ...
       ...



       public abstract void move();
       public long GetUniqueId()
       {
          // compute the tires, wheel, and any other attribute 
          // and generate an unique id here.
       }
   }

   public class ElectricCar: Car
   {
       public void move()
       {
         .....
       }
   }

   public class SteamCar: Car
   {
       public void move()
       {
         .....
       }
  }

I hope this helps.

OscarRyz