I am having trouble understanding inheritance and implementing it in classes. I am trying to create a program with the Reptile class as the base.
What's the best way to do this with the following data?
There will also be a menu class using what I think should be a switch case to select the desired reptile and display the information.
Thanks in advance for any help.
Ok, so I understand that this is some kind of homework exercise, since in the real world you will not use inheritance for this at all.
using the the image you posted, let me try to explain inheritance in the simplest terms I can.
You can think of a base class for all reptiles - Let's call it Reptile.
This class contains all the different aspects shared by all reptiles - things like preferred food, feeding time, food to weight ratio etc'.
All of these aspects can be coded as properties of the Reptile class.
Please note that in the real world, the Species and ReptileType would also be properties of the Reptile class, making the use if inheritance completely redundant in this case - But then again, we are not talking about real world applications yet - so:
A Snake is a specific type of Reptile. A Lizard is another specific type of Reptile - so let's create classes for those two types.
So far, we have the Reptile, Snake and Lizard classes, where the last two inherits the first.
Moving on, a Cobra is a specific type of Snake, so is a Rattlesnake. So let's create classes for them inheriting from Snake. Much the same, a BeardedLizard is a specific type of Lizard, and so is a Chameleon - so here are another two classes to create.
So basically, I think your teacher is expecting to see the following:
class Reptile {/* implementation here */}
class Snake : Reptile {/* implementation here */}
class Cobra : Snake {/* implementation here */}
class Rattlesnake: Snake {/* implementation here */}
class Lizard: Reptile {/* implementation here */}
class BeardedLizard : Lizard {/* implementation here */}
class Chameleon : Lizard {/* implementation here */}
Now, the reason inheritance does not make sense in this situation, is that a Snake does not add any new capabilities to a Reptile, nor does a Chameleon to a Lizard. For inheritance to make sense, you will need to add new capabilities in the deriving types, that is specific to that class (and it's inheritors) and is not shared with the base class or any other inheritance chain of that class.
For instance, all snakes crawl, while all lizards walk. If you where to add a Crawl() method to the Snake class and a Walk() method to the Lizard class - Than it would make sense for a Snake and a Lizard class inheriting the Reptile class.
Related
This question already has answers here:
When to use an interface instead of an abstract class and vice versa?
(26 answers)
Closed 5 years ago.
I recently came across a problem related to class creation/modeling.
Model animal kingdom as classes. Use your classes to create various objects represented as a virtual zoo. Add 20 animals to this virtual zoo (in your main method of your program and make let each animal make a sound. This should not be 20 different species).
I thought about the problem and decided to go with an abstract class Animal rather than an interface. Then i added two classes Bird, Mammal as inherited them by Animal.
My implementation
public abstract class Animal{
abstract Sound MakeSound();
}
public class Bird : Animal
{
private Sound _sound;
public Bird(Sound sound){
_sound = sound;
}
public Sound MakeSound(){
return _sound;
}
}
//same as above with Mammals
public class Program
{
Animal crow = new Bird("Crow sound");
Console.WriteLine(crow.MakeSound());
Animal dog = new Mammal("Dog sound");
Console.WriteLine(dog.MakeSound());
// and so on with other animals
}
My questions are -
What is wrong with my implementation?
What would be the correct way to design the animal kingdom as per
oops concepts?
In what scenario do we use an interface over abstract class and vice versa. (with real world example)
Kindly suggest some bang on online material where i can improve on such problems.
Thanks.
First of all, it's important to realize that though "model the animal kingdom in a class hierarchy" is a common beginner exercise, and often used in examples -- I use Animal, Mammal, Giraffe, Tiger, and so on all the time in examples -- it is not a realistic problem to solve using OO techniques. It's simply intended to get you thinking about the concepts in OO programming by thinking about a domain that you already understand well.
Real zoos which have software to manage their animal inventory do not build class hierarchies like this because their concerns do not actually include what mammals have in common over what birds have in common. Though animal kingdom analogies are useful to get going with OO, it's important to not come away with the belief that every feature that exists in a real-world hierarchy has to be modeled in the class hierarchy.
So, that said, the rest of my critique will be assuming that you really do want to model the animal kingdom as an exercise.
Second, the fundamental problem with your implementation is that the hierarchy is either not deep enough or too deep. The problem is that mammal and bird should be abstract because there is no thing in the world that is just a mammal or just a bird. What you want is an abstract class bird that extends animal, and then a concrete (and probably sealed!) class Crow that extends Bird.
Then the question to ask is: do I really need the mammal and bird levels at all? Are they useful to my program? Am I ever going to have a method that can take any mammal but no lizard? If its not useful then eliminate it, and go straight from animal to crow.
Third, the sound a crow makes is "caw caw", not "crow sound". :-)
Fourth, to answer your best question: you typically use an interface when you have several unrelated things that "can do" the same thing but with different implementations and you use an abstract class to share implementation details amongst classes that have an "is a kind of" relationship.
Making a sound is a something that a lot of things can do that are unrelated to each other. A bird and a piano are not the same kind of thing and they have different mechanisms, but they both make sounds. So making sound should be represented by an interface. A bird is a kind of animal, and there might be functions common to all animals that are specialized by birds.
In short: a bird is a kind of animal, so it should be a subclass. A bird can make a sound, and lots of other things can also, so making a sound should be an interface.
one of the reasons you want to use Interface is that C# does not support multiple inheritance.
In general, I would like to think of interface as ability or feature instead of being a model.
Something like:
public interface ISwimable
{
int SwimmingSpeed { get; set; }
}
public interface IWalkable
{
int RunningSpeed { get; set; }
}
Now if I have an animal that lives in water I would like it to implement ISwimable, and if I have an animal that can walk, its class should implement IWalkable, and if it can do both, it will implement both.
according to Aamir in When to use an interface instead of an abstract class and vice versa?
When you derive an Abstract class, the relationship between the
derived class and the base class is 'is a' relationship. e.g., a Dog
is an Animal, a Sheep is an Animal which means that a Derived class is
inheriting some properties from the base class.
Whereas for implementation of interfaces, the relationship is "can
be". e.g., a Dog can be a spy dog. A dog can be a circus dog. A dog
can be a race dog. Which means that you implement certain methods to
acquire something.
But how about the abilities? Like, "A dog can bark", "a cat can jump", "a snake can slither", where will I put these, in an abstract or an interface?
If you have some common abilities, like move, you can have an interface of those and have the abstract class implement those methods (if animals are the only thing you'll work with, then you wouldn't really gain much by having that interface I believe). If you are having specific abilities that would apply only on certain derived classes, have them implement the interface.
Dog barking seems to be an ability only for a single derived class, why not leave it be implemented by that derived class? Having it in the abstract class would mean all animals would be able to bark, but then again having a dog class implement an interface that has bark in it seem a bit weird if dog is your only animal capable of barking.
Side note: interfaces don't necessarily have to be defined as "can be" relationship.
The ability to do something would probably be best suited to an interface, unless you are looking to provide some default behaviour if the method is not implemented.
Keep in mind that C# does not support inheriting from multiple classes, but does support implementing multiple interfaces. This allows for some flexibility. Such as this:
interface IBreathes()
{
void Breathe();
}
interface IMoveable()
{
void Move(int x, int y);
}
class Snake : Animal, IBreathes, IMoveable
{
void Breathe()
{
...
}
void Move(int x, int y)
{
...
}
}
For the above example use of abstract classes would be fine, but with large, complex projects it may become quite frustrating to work around the single-inheritance issue.
There's another thing to consider: Your implementation class can implement as many interfaces as you want but you can inherit from only one class directly, abstract or concrete.
To put things short: Use interfaces when you can and abstract classes when you have to.
Inspired by a great video on the topic "Favor object composition over inheritance" which used JavaScript examples; I wanted to try it out in C# to test my understanding of the concept, but it didn't go as well as I'd hoped.
/// PREMISE
// Animal base class, Animal can eat
public class Animal
{
public void Eat() { }
}
// Dog inherits from Animal and can eat and bark
public class Dog : Animal
{
public void Bark() { Console.WriteLine("Bark"); }
}
// Cat inherits from Animal and can eat and meow
public class Cat : Animal
{
public void Meow() { Console.WriteLine("Meow"); }
}
// Robot base class, Robot can drive
public class Robot
{
public void Drive() { }
}
The problem is that I want to add RobotDog class that can Bark and Drive, but not eat.
First solution was to create RobotDog as subclass of Robot,
public class RobotDog : Robot
{
public void Bark() { Console.WriteLine("Bark"); }
}
but to give it a Bark function we had to copy and paste the Dog's Bark function so now we have duplicate code.
The second solution was to create a common super class with a Bark method that then both the Animal and Robot classes inherited from
public class WorldObject
{
public void Bark() { Console.WriteLine("Bark"); }
}
public class Animal : WorldObject { ... }
public class Robot : WorldObject { ... }
But now EVERY animal and EVERY robot will have a Bark method, which most of them don't need. Continuing with this pattern, the sub-classes will be laden with methods they don't need.
The third solution was to create an IBarkable interface for classes that can Bark
public interface IBarkable
{
void Bark();
}
And implement it in the Dog and RobotDog classes
public class Dog : Animal, IBarkable
{
public void IBarkable.Bark() { Console.WriteLine("Bark"); }
}
public class RobotDog : Robot, IBarkable
{
public void IBarkable.Bark() { Console.WriteLine("Bark"); }
}
But once again we have duplicate code!
The fourth method was to once again use the IBarkable interface, but create a Bark helper class that then each of the Dog and RobotDog interface implementations call into.
This feels like the best method (and what the video seems to recommend), but I could also see a problem from the project getting cluttered with helpers.
A fifth suggested (hacky?) solution was to hang an extension method off an empty IBarkable interface, so that if you implement IBarkable, then you can Bark
public interface IBarker { }
public static class ExtensionMethods
{
public static void Bark(this IBarker barker) {
Console.WriteLine("Woof!");
}
}
A lot of similar answered questions on this site, as well as articles I've read, seem to recommend using abstract classes, however, wouldn't that have the same issues as solution 2?
What is the best object-oriented way to add the RobotDog class to this example?
At first if you want to follow "Composition over Inheritance" then more than half of your solutions don't fit because you still use inheritance in those.
Actually implementing it with "Composition over Inheritance" there exists multiple different ways, probably each one with there own advantage and disadvantage. At first one way that is possible but not in C# currently. At least not with some Extension that rewrites IL code. One idea is typically to use mixins. So you have interfaces and a Mixin class. A Mixin basically contains just methods that get "injected" into a class. They don't derive from it. So you could have a class like this (all code is in pseudo-code)
class RobotDog
implements interface IEat, IBark
implements mixin MEat, MBark
IEat and IBark provides the interfaces, while MEat and MBark would be the mixins with some default implementation that you could inject. A design like this is possible in JavaScript, but not currently in C#. It has the advantage that in the end you have a RobotDog class that has all methods of IEat and IBark with a shared implementation. And the this is also a disadvantage at the same time, because you create big classes with a lot of methods. On top of it there can be method conflicts. For example when you want to inject two different interfaces with the same name/signature. As good as such an approach looks first, i think the disadvantages are big and i wouldn't encourage such a design.
As C# doesn't support Mixins directly you could use Extension Methods to somehow rebuilt the design above. So you still have IEat and IBark interfaces. And you provide Extension Methods for the interfaces. But it has the same disadvantages as a mixin implementations. All methods appear on the object, problems with method names collision. Also on top, the idea of composition is also that you could provide different implementations. You also could have different Mixins for the same interface. And on top of it, mixins are just there for some kind of default implementation, the idea is still that you could overwrite or change a method.
Doing that kind of things with Extensions Method is possible but i wouldn't use such a design. You could theoretically create multiple different namespaces so depending on which namespace you load, you get different Extension Method with different implementation. But such a design feels more awkward to me. So i wouldn't use such a design.
The typical way how i would solve it, is by expecting fields for every behaviour you want. So your RobotDog looks like this
class RobotDog(ieat, ibark)
IEat Eat = ieat
IBark Bark = ibark
So this means. You have a class that contains two properties Eat and Bark. Those properties are of type IEat and IBark. If you want to create a RobotDog instance then you have to pass in a specific IEat and IBark implementation that you want to use.
let eat = new CatEat()
let bark = new DogBark()
let robotdog = new RobotDog(eat, bark)
Now RobotDog would Eat like a cat, and Bark like a Dog. You just can call what your RobotDog should do.
robotdog.Eat.Fruit()
robotdof.Eat.Drink()
robotdog.Bark.Loud()
Now the behaviour of your RobotDog completely depends on the injected objects that you provide while constructing your object. You also could switch the behaviour at runtime with another class. If your RobotDog is in a game and Barking gets upgraded you just could replace Bark at runtime with another object and the behaviour you want
robotdog.Bark <- new DeadlyScreamBarking()
Either way by mutating it, or creating a new object. You can use a mutable or immutable design, it is up to you. So you have code sharing. At least me i like the style a lot more, because instead of having a object with hundreds of methods you basically have a first layer with different objects that have each ability cleanly separated. If you for example add Moving to your RobotDog class you just could add a "IMovable" property and that interface could contain multiple methods like MoveTo, CalculatePath, Forward, SetSpeed and so on. They would be cleanly avaible under robotdog.Move.XYZ. You also have no problem with colliding methods. For example there could be methods with the same name on each class without any problem. And on top. You also can have multiple behaviours of the same type! For example Health and Shield could use the same type. For example a simple "MinMax" type that contains a min/max and current value and methods to operate on them. Health/Shield basically have the same behaviour, and you can easily use two of them in the same class with this approach because no method/property or event is colliding.
robotdog.Health.Increase(10)
robotdog.Shield.Increase(10)
The previous design could slightly be changed, but i don't think it makes it better. But a lot of people brainlessly adopt every design pattern or law with the hope it automatically makes everything better. What i want to refer here is the often called Law-of-Demeter that i think is awful, especially in this example. Actually there exists a lot of discussion of whether it is good or not. I think it is not a good rule to follow, and in that case it also becomes obvious. If you follow it you have to implement a method for every object that you have. So instead of
robotdog.Eat.Fruit()
robotdog.Eat.Drink()
you implement methods on RobotDog that calls some method on the Eat field, so with what did you end up?
robotdog.EatFruit()
robotdog.EatDrink()
You also need once again to solve collisions like
robotdog.IncreaseHealt(10)
robotdog.IncreaseShield(10)
Actually you just write a lot of methods that just delegates to some other methods on a field. But what did you won? Basically nothing at all. You just followed brainless a rule. You could theoretically say. But EatFruit() could do something different or do something additional before calling Eat.Fruit(). Weel yes that could be. But if you want other different Eat behaviour then you just create another class that implements IEat and you assign that class to the robotdog when you instantiate it.
In that sense, the Law of Demeter is not a dot counting Exercise.
http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx/
As a conclusion. If you follow that design i would consider using the third version. Use Properties that contain your Behaviour objects, and you can directly use those behaviours.
I think this is more of a conceptual dilemma rather than a composition issue.
When you say :
And implement it in the Dog and RobotDog classes
public class Dog : Animal, IBarkable
{
public void IBarkable.Bark() { Console.WriteLine("Bark"); }
}
public class RobotDog : Robot, IBarkable
{
public void IBarkable.Bark() { Console.WriteLine("Bark"); }
}
But once again we have duplicate code!
If Dog and RobotDog have the same Bark() implementation, they should inherit from the Animal class. But if their Bark() implementations are different, it makes sense to derive from IBarkable interface. Otherwise, where is the distinction between Dog and RobotDog?
I'm developing a reusable library and have been creating abstract classes, so the client can then extend from these.
QUESTION: Is there any reason in fact I should use an abstract class here as opposed to just a normal class?
Note - Have already decided I do not want to use interfaces as I want to include actual default methods in my library so the client using it doesn't have to write the code.
EDIT: So I'm fishing for any advantages I can't think of. For example when upgrading the library would use of an abstract class lessen impact on client code - I can't see it would in this case no?
Unless you want to force the end users to inherit from your classes, there should be no reason to use abstract.
If you want to make your classes inheritable and easily extensible, use virtual on your methods and make sure you have usable protected constructors.
The motivation for the abstract class is to require clients to override the class. Your decision on whether the class should be abstract or not depends primarily on whether the abstract is missing some fundamental behavior that only an user of the class can supply.
You can usually tell you need your class to be abstract if you use a template method of some sort, where "plug in the hole in this behavior" completes the logic of he class. If your class is useful without some user-supplied logic, you probably don't need the class to be abstract.
As an example, frameworks usually can't make decisions on behalf of their users in terms of things like object state validation, printing, display, and so on, and they would need to defer to concrete implementations by the clients.
The difference between an abstract class and a non-abstract one is that you can't instantiate the former and it MUST be overriden. It is really up to you to determine whether or not an instance of the base class makes sense on its own.
Let me show you two cases. One is where abstract class makes sense and one where it doesn't.
public abstract class Animal {
public string Name {get;set;}
}
public class Dog : Animal {
public Bark(){}
}
public class Cat : Animal {
public Meaow(){}
}
In this scenario we have a common base Animal that provides implementation for Name property. It makes no sense to instantiate Animal by itself as there are no animals in the world that are just animals, they are wither dogs or cats or something else.
Here is a case where it makes sense to have a non-abstract base.
class Path {
public Path(IList<Point> points) {
this.Points = new ReadOnlyCollection<Point>(points);
}
public ReadOnlyCollection<Point> Points {get;}
}
class RectanglePath : Path{
public SquarePath (Point origin, int height, int width) :
base(new List<Point>{origin, new Point(origin.X + width, point.Y}, ....){
}
}
Here Path that is not subclassed makes sense, we can create any arbitrary shape, but it might be more convenient to use a sublass for more specific shapes.
Sounds like you are a little confused about the difference between a virtual method and an abstract class. You don't need to mark your class as abstract unless you determine that it doesn't make sense on it's own. This is useful in areas where you might have shared behaviors between multiple classes.
Sounds to me like you just need a regular class and some methods that are virtual.
Here is the MSDN article on abstract classes, but I really don't get it...
When should I really use abstract classes? What are the advantages of using abstract classes?
Abstract classes are useful when you need a class for the purpose of inheritance and polymorphism, but it makes no sense to instantiate the class itself, only its subclasses. They are commonly used when you want to define a template for a group of subclasses that share some common implementation code, but you also want to guarantee that the objects of the superclass cannot be created.
For instance, let's say you need to create Dog, Cat, Hamster and Fish objects. They possess similar properties like color, size, and number of legs as well as behavior so you create an Animal superclass. However, what color is an Animal? How many legs does an Animal object have? In this case, it doesn't make much sense to instantiate an object of type Animal but rather only its subclasses.
Abstract classes also have the added benefit in polymorphism–allowing you to use the (abstract) superclass's type as a method argument or a return type. If for example you had a PetOwner class with a train() method you can define it as taking in an object of type Animal e.g. train(Animal a) as opposed to creating a method for every subtype of Animal.
By using abstract classes we are able to make the class more generic.
For example: if class A is an abstract class and there are classes class B, class C and class D extending abstract class A then these sub-classes will inherit a method which is already declared in abstract class A thereby making the method more generic.
You use them for classes which will never be created (so effectively don't exist), but you want to inherit from them for polymorphism reasons.
Richard has provided an example were an abstract class has advantages over non-abstract classes.
I would like to add a fact-table for choosing between an abstract class and an interface. The image can be found here.
Use abstract classes when you are defining behaviour for a class in your class heirarchy that is never going to be used to instantiate an object directly.
So, think of yourself as God for a moment. Your CBabyBoy and CBanyGirl classes wouldn't be abstract - as these are solid objects that do get created. On the other hand, your CPerson and CAnimal classes WOULD be abstract - they're useful from a type hierarchy point of view, but you won't ever be running CAnimal dingbat = new Animal();
Basically, you should use an abstract class, when some entity in your hierarchy logically will have method(s) it does not know how to implement, but it's descendants do. There are billions of 'real life' examples all over the web, really)