Can you help me understand in a practical example

2019-01-31 15:21发布

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);
        }
    }
}

9条回答
Deceive 欺骗
2楼-- · 2019-01-31 15:47

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.

查看更多
3楼-- · 2019-01-31 15:49

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

查看更多
混吃等死
4楼-- · 2019-01-31 15:51

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.

查看更多
Root(大扎)
5楼-- · 2019-01-31 15:57
  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.

查看更多
爷的心禁止访问
6楼-- · 2019-01-31 15:58

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

查看更多
我只想做你的唯一
7楼-- · 2019-01-31 16:00

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.

查看更多
登录 后发表回答