可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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);
}
}
}
回答1:
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.
回答2:
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.
回答3:
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)
回答4:
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.
回答5:
An interface is a contract. This is the place where you want to describe the functionalities you'll provide, without any implementation details
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
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:
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.
回答7:
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
回答8:
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
回答9:
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.