When to use interfaces from an oop pov [duplicate] - java

This question already has answers here:
When to use an interface instead of an abstract class and vice versa?
(26 answers)
Closed 8 years ago.
I have been taught many things about how to structure code. For instance, nouns translate to classes (Eg, class Dog, class Banana). Something that objects have translate to variables inside the class. (Eg, a dog has a name so name would be a variable inside the Dog class.) I've also been taught that abstract nouns translate to abstract classes, eg, ChessPiece would be an abstract class and king, pawn etc would inherit from it.
How do interfaces work like this? I never find myself using interfaces and I want to because I heard that you should design towards an interface.

Interfaces "work like this" such that they enforce a contract to be met amongst its implementer. IOW, the interface says = "you shall do this". So, keeping with your example you might think even "lower" by observing that a ChessPiece is actually a GamePiece in that it inherits a certain amount of behavior that all game pieces have. It may be as simple as...
public interface GamePiece {
void move(int x, int y);
// more behaviors here
}
And you have your abstract class of ChessPiece...
public abstract class ChessPiece implements GamePiece {
// could add more shared stuff here
public abstract void move(int x, int y);
// other stuff can be implemented if needed
}
which the King would extend...
public class King extends ChessPiece {
#Override
public void move(int x, int y) {
// move as the King does
}
}
BUT you can also apply that contract to other game pieces as well. Perhaps you want a CandyLand piece...
public class CandyLandPiece implements GamePiece {
#Override
public void move(int x, int y) {
// move as these pieces do
}
}

I would generally agree with the first paragraph.
On
How do interfaces work like this? I never find myself using interfaces and I want to because I heard that you should design towards an interface.
You probably haven't dealt with large projects in java.
Interfaces are exactly what they sound - definition of a contract with which two java modules can communicate. Abstract classes are interfaces + definition of functionality.
I use interfaces when I think of communication with external module. It should be able to see and use your interface and (probably) nothing else.
Abstract classes are there to avoid repetition in their subclasses, but, as you know, cannot be instantiated, ergo they lack some functionality to be a complete object of the type.
Maybe you should provide a code snippet that can be discussed here.

Think of Interfaces as agreements. A cricket ball and a football for instance can be considered classes. But they follow a common agreement say "Bouncable". Interfaces logically combine classes of different class hierarchies together.
Modified answer as per comment: Bounceable Interface can have a method "bounce". This would in turn imply that all classes that implement Bounceable Interface would definately have to implement "bounce". Logically this sounds correct as well that every Bouncable ball (be it a cricket ball or a football) must be able to bounce.

On the surface, interfaces are very much like classes, except they can't define the methods inside them. It is left upto the implementing class to define the method as they seem fit. Since Java quite sensibly does not allow one class to inherit from multiple classes (multiple inheritance), one class can still implement multiple interfaces to achieve this goal and avoid the pitfalls that come with multiple inheritance.
So you could have a method sound within the interface animal, and every class implementing this interface will have to define method sound in their own custom way. Here's an example,
Suppose you have an interface Animal which has a makesSound method.
class Dog implementing Animal will also have to define makeSound(){//bark}
class Cow implementing Animal will also have to define makeSound(){//Moo}
If you are going to be implementing same functionality for all classes, good idea to extend a class and if you want custom functionality with same name for all classes, good idea to go with an interface. Generally, lean towards an interface as it will allow you the option to extend a class to your current class in the future.

Related

Why shouldn't these interfaces inherit from each other?

I posted a question about interfaces and advice I read about in Effective Java. I got the answer I wanted, and all was good, until this afternoon when I signed into SO, and a comment was left saying
These interfaces should not inherit from each other.
I asked why, but still haven't received an answer. Can someone explain why you wouldn't allow these interfaces to inherit? How would you fix it, and still keep the same functionality provided in the answer?
public interface GameObject {
void viewDetails();
}
public interface Weapon extends GameObject {
void attack();
}
//A weapon is not the only item reloadable. A container could be refilled.
public interface Reloadable extends GameObject {
void replenish (final int amount);
}
The only reason I see for these interfaces not to inherit, is the simplicity of the GameObject interface. It isn't providing any functionality that toString can't accomplish. However, it's only the beginning stages of my game, and GameObject will of course expand.
I think you are worried too much about the purity of your design, to the point where you are concerned with trifling details instead of spending your time productively, that is, writing your game.
Either way does not make much of a difference.
Usually, a "GameObject" (and anything whose name ends with "Object") is a class, abstract if need be, but not an interface. The only reason for naming an interface "SomethingObject" is if the interface also extends (or exposes by aggregation) the Closeable (AutoCloseable) interface, meaning that anyone who has a reference to it may destroy it. So, if you take this route, the rest of your questions are answered trivially: interface Weapon may not extend GameObject, because interfaces may not extend classes, and the same goes for Reloadable, and we are done.
Now, if you insist on having a "GameObject" interface, you still have the option of either extending it for every single additional characteristic, or keeping each additional characteristic separate, without extending "GameObject". Both approaches will work.
If you promise, if you swear in the name of everything that is dear to you, that there will never be a Reloadable which is not also a GameObject, then you can go ahead and have Reloadable extend GameObject. But do you really need that? The common practice is that we prefer using interfaces to increase the degree of branching of our inheritance tree, not to turn our inheritance tree into a graph. (Not that it never happens, but it happens very rarely.) So, we usually do not do that. But if you do that, it is not the end of the world.
Also note that when we extend one interface from another, we (not always, but) usually extend the names. So, your Weapon would be WeaponGameObject and your Reloadable would be ReloadableGameObject.
Also note that interface inheritance is rarely, if ever, necessary; you can make Reloadable a free-standing interface (that does not extend GameObject) and you can have Reloadable include a GameObject getGameObject() method, thus essentially linking the two entities together. Then, your BFG9000ReloadableGameObject class may implement both Reloadable and GameObject and implement getGameObject() as return this;
Do a real domain analysis. You'll find that something with replenish behavior, a Replenishable, needn't be a Weapon and may not care while replenishing that it's a GameItem. A Vehicle might also need replenishment. Perhaps something like
public interface Weapon extends GameItem {
public class ChargeGun
implements Replenishable, Weapon {...
public class FlyingCarpet extends GameItem
implements Replenishable, Vehicle {...
It's usually better to have a class do interface mixins than interfaces inherit them. It depends on the domain and how you model it. As much as feasible you want
gun.replenish();
not
replenish(Replenishable Replenishable);
YMMV.
Agreeing with Mike here: Probably not the stage you should be worried about this.
For game development modeling the 'world' using object-oriented principles is often avoided. This is due strong coupling of objects and performance reasons. Very advanced game engines don't create specific classes for entities in the world.
If you are interested in the finer details,
check this out:
http://entity-systems-wiki.t-machine.org/

Difference between abstract class with all method abstract and interface?

I had an interview where interviewer asked me first what is the difference between abstract class with all the methods abstract and an interface.
I replied that if it is required to inherit something in the future you will not be able to do it if you have already extended a class.
Then, he stated that it was a situation where one would never have to extend any other class and you have to implement a contract. In this circumstance, which would be better, an abstract class or an interface?
I told him you can use either of them but he was not satisfied. I could not understand why - I believe that is a developer/design choice.
The answer stating that an interface represents a contract is not acceptable.
That's the answer we give to Junior since it may be too complex to clearly figure out the difference between the essence of an abstract class and the essence of an interface without much architecture experience and without reading a lot of classic books about.
Any abstract class with public methods acts as a contract, as well as an interface.
An abstract class that doesn't provide any implementation is in 99% of cases a representation of an object's Role.
An interface represents a Role.
Each object might have several different roles that shouldn't be tied together but composed by the concerned object.
I'm explaining this with this example:
Your interviewer could say:
I have a Robot that can walk and a Human that can walk too.
So based on this case, he asks you: should I extract the walking feature in an abstract base class or in an interface, knowing that the implementations have nothing in common?
You think..."oh I know so: in this case, having one abstract class with an abstract method walk(), then is clearly the same than declaring an interface with the walk() method."
So your answer would surely be: "it's the choice of the developer !".
And it's really not an always valid answer.
Why? Let's see the next expectation:
A Human can eat, but obviously the Robot cannot and even doesn't need.
What if you implemented the walking feature with an abstract class? You would end up with:
public abstract class Biped {
public void abstract walk();
}
public Robot extends Biped {
public void walk() {
//walk at 10km/h speed
}
}
public Human extends Biped {
public void walk() {
//walk at 5km/h speed
}
}
How could you plug the eating feature? You're stuck because you can't implement it in the Biped base class since it would break Liskov Substitution Principle, since a Robot doesn't eat!
And you can't expect Human extending another base class due to the known Java rule.
Of course, you could add a specific Feedable interface only dedicated to Human:
public interface Feedable {
void eat();
}
Signature becomes: public Human extends Biped implements Feedable {
Clearly, it makes no sense and confusing to have one role implemented through a class and the other through an interface.
That's why starting with interface is really preferred whenever we have the choice.
With an interface, we can model Roles easily by composing.
So the final solution would then be:
public interface Walkable {
void abstract walk();
}
public interface Feedable {
void eat();
}
public Robot implements Walkable {
public void walk() {
//walk at 10km/h speed
}
}
public Human implements Walkable, Feedable {
public void walk() {
//walk at 5km/h speed
}
public void eat(){
//...
}
}
Doesn't it remind you the Interface Segregation Principle? ;)
To sum up, if you specify an IS-A relationship, uses an abstract class.
If you realize that you are about to model a Role (let's say a IS-CAPABLE-OF relationship), go with interface.
Here are the differences:
A class can extend exactly abstract class, but can implement any number of interfaces.
An abstract class can have protected, private (does not apply to your question), package, and public methods, but an interface can only have public methods.
An abstract class can have instance variables (often called data members or properties) while an interface can only have static variables.
The answer to the question: "blah never extend blah implement contract blah" is this: "I would use an abstract class if I did needed instance variables and/or non-public methods and otherwise I would use an interface".
Interfaces are the natural way of creating a contract because they force you to implement the methods they define.
Besides that, you can implement as many as you want in the case you want to add new interfaces to your class.
I can't say what your interviewer had in mind, but an interface is more of a "contract" whereas an abstract base class, while it can play that role too, is more geared towards hierarchies or IS-A relationships. E.g. an Apple IS-A Fruit, a Pear IS-A Fruit, etc. But you're right, they could well be used interchangeably for practical purposes in that context, but an OO purist might not want to use an abstract class unless they were expressing IS-A relationship(s).
One thing to keep in mind is be the ability to have diamond inheritance for interfaces.
Consider this interface hierarchy:
interface Base{}
interface Sub1 extends Base{}
interface Sub2 extends Base{}
interface SubSub extends Sub1, Sub2{}
The same wouldn't be possible with abstract classes:
abstract class Base{}
abstract class Sub1 extends Base{}
abstract class Sub2 extends Base{}
// NOT ALLOWED! can only extend one class
// abstract class SubSub extends Sub1, Sub2{}
This is something that would be allowed in C++ (although tricky to get right). I think he might have been fishing for this. In general, this is the ultimate reason why I always try to write interface hierarchies instead of class hierarchies.
For the first situation i'd chose interface over abstract class with all methods abstract as having interface leaves me with option in future for my implementing class to extend some other (abstract) class.
For second scenario, if you really don't want your concrete class to extend any other class and also want to "implement" contract, you can have abstract class with all methods abstract.
I can see such question was already answered. BTW, I would like to share what I consider the best explanation I have read so far.
The bellow text was copied and pasted from Deshmukh, Hanumant. OCP Oracle Certified Professional Java SE 11 Programmer I Exam Fundamentals 1Z0-815: Study guide for passing the OCP Java 11 Developer Certification Part 1 Exam 1Z0-815 (p. 319). Enthuware. Edição do Kindle.
13.2 Distinguish class inheritance from interface inheritance including abstract classes 13.2.1 Difference between Interface and Abstract Class ☝
"What is the difference between an interface and an abstract class" is usually the first question that is asked in a Java "tech-check". While being a simple ice breaker, it also an excellent question to judge a candidate's understanding of OOP. Candidates usually start parroting the technical differences such as an interface cannot have method implementations (which it can, since Java 8), while abstract class can. An interface cannot have static methods (which it can, since Java 8) or instance fields while an abstract class can and so on. All that is correct, but is not really impressive. The fundamental difference between an interface and an abstract class is that an interface defines just the behavior. An interface tells you nothing about the actual object other than how it behaves. An abstract class, on the other hand, defines an object, which in turn, drives the behavior. If you understand this concept everything else about them will fall in place. For example, "movement" is a behavior that is displayed by various kinds of objects such as a Car, a Cat, or a StockPrice. These objects have no commonality except that they move. Saying it the other way round, if you get an object that "moves", you don't get any idea about what kind of an object are you going to deal with. It could be a Car, a Cat, or a StockPrice. If you were to capture this behavior in Java, you would use an interface named Movable with a method named move(). On the other hand, if you talk about Automobile, a picture of an object starts forming in your head immediately. You can sense that an Automobile would be something that would have an engine, would have wheels, and would move. You intuitively know that a StockPrice or a Cat cannot be an Automobile even though they both do move. An abstract class is meant exactly for this purpose, when, once you identify a conceptual object, you do not need to worry about its behavior. The behavior kind of flows automatically. If you create an abstract class named Automobile, you are almost certain that it would have methods such a move, turn, accelerate, or brake. It would have fields for capturing inner details such Engine, Wheels, and Gears. You get all that just by saying the word Automobile. From the above discussion, it should be clear that interfaces and abstract classes are not interchangeable. Even though an abstract class with no non-abstract method looks functionally similar to an interface, both are fundamentally different. If you are capturing a behavior, you must use an interface. If you are capturing a conceptual object, you must use an abstract class.

Achieving multiple inheritance via interface

I am a beginner in interface concept.
when I surfing for the information about "Achieving multiple inheritance via interface", I came across this link.. Multiple inheritance
I have a same doubt as the programstudent had.
hi, Good Explanation very much helpful In the uml diagram for java
there is no connection to Animal from Bird and horse why? Is it
necessary to use the implement the same method in the derived class
and why
void birdNoise();
void horseNoise();
why in the Peagus class
public void horseNoise()
{
System.out.println("Horse Noise!");
}
public void birdNoise()
{
System.out.println("Bird Noise!");
}
why this must be there? Why "Remember, we must write each class's own implementation for each method in the interface. reason? Thank for this good explanation Thank you
In that post, they have used multiple inheritance in c++ and converted to interfaces in java.
1.what I thought about inheritance is having some methods in parent class, and whenever the same methods are needed in other class(es) too, then those class(es) will inherit the parent class and use it.
But in interface concept if each derived class(es) has to define its own implementation then what is the use of inheriting it?
2.If we have to provide own implementation then why not we define that method in the derived class(es) itself. What is the use of inheriting it?
Someone please explain.
Thanks in advance.
When I switched from c++ to java I had this same feeling but now that I been working with java for a while it all kinda makes sense.
1.what I thought about inheritance is having some methods in parent
class, and whenever the same methods are needed in other class(es)
too, then those class(es) will inherit the parent class and use it.
Like the original author did, you can still do multiple inheritance in java you just must use interfaces. Interfaces are like pure virtual classes in c++.
But in interface concept if each derived class(es) has to define its
own implementation then what is the use of inheriting it?
The reason you implement an interface in java is so that you guarantee that class has those methods. That way you can have a specific class implement a generic interface and then treat every specific class that implements that generic interface the same.
Java Design is a bit different then c++ design but after doing several java program's you will become just as good at using multiple interfaces as you are at using multiple inheritance.
Each subclass has to define it's own implementation because each subclass may perform the operation slightly differently. Consider the following example:
public interface animal {
//All implementers must define this method
void speak();
}
This interface states that any Animal MUST have a way to speak. Basically, any type of animal is going to be able to make a noise. We then have 2 subclass, or 2 different types of animals that we create.
public class Dog implements animal {
//Define how a Dog speaks
public void speak() {
System.out.println( "woof" );
}
}
We then define another animal, cat
public class Cat implements animal {
//Define how a Cat speaks
public void speak() {
System.out.println( "meow" );
}
}
In this example, both Cat and Dog are animals, and therefore must be able to speak due to our interface. However, everybody knows that cats and dogs make different sounds. By allowing each subclass to define how it 'speaks', we can give Dog and Cat their own respective sound when the speak() method is called, while ensuring they are both Animals.
In answer to your question more specifically, inheritance forces it's subclasses to have a specific method. In other words, an interface states that "all my subclasses will define each of these methods". What this allows us to do is to write code that deals with the methods in an interface without knowing the specific subclass. We can safely do that because we know that each subclass MUST have defined the method in the interface class. If only the subclasses that use the method defined it, then we would have no way of knowing for sure whether it is safe to call the method on all subclasses.
Just a note: If you do not want a subclass to define the method, you can simply define an empty method like this:
public class MuteAnimal implements animal {
//A MuteAnimal can't speak!
public void speak() { }
}
Inheritance is often useless without polymorphism. It is really not easy to explain it all just in few sentences. My advices would be to look at interfaces for defining behavior (something like can-do relationship), and concrete inheritence for is-a relationships.
In the center of everything as you may learn is something called Single Responsibility Principle. This means that one class has one responsibility, if you are having more of them, you separate the class.
If you take your example, even the Pegasus isn't both horse and bird at the same time 100% percent. It would inherit the horse, but implement specific characteristics of the birds, which would be defined in interfaces, like Flyable for instance. You can say that birds have one way of flying common to them all, so inherit them from Bird. Pegasus is a little different, so that custom logic can be defined after you implement the Flyable interface with method Fly.
Also, the example with horseNoise and birdNoise is little unrealistic, you want one method speak() which will due to internal class alhorithm perform certain action. What if that pegasus could talk? Would you have a method for each word?
Back to Flyable example, say you now have a video-game. Now you can have polimorphism for this: Lets say that in game earthquake happens. You want for each animal that can fly to go and fly. You have a collection of animals currently in game, so you write this:
foreach(Flyable flyableAnimal in animals)
flyableAnimal.Fly();
You just rely on polimorphism ...
These were just some random thoughts, you can find far better examples online, hope this helps ...
If class A inherits from class B, that effectively means two things:
Class A can implicitly use all methods and properties of class B, and need only define that functionality which is in fact unique to class A.
Code which expects an object of type B will accept an object of type A.
Those two features of inheritance are in some sense orthogonal; one can imagine places where either could be useful without the other. Although derived classes can only have one parent class from which they gain implicit access to methods and properties, they may define an arbitrary number of interfaces for which they are substitutable.
Note that while some people insist that interfaces form a "has-a" rather than "is-a" relationship, I think it's better to think of them as saying something "is __able" or "is a __er", the point being that interfaces don't just define abilities, but define substitutability (i.e. "is a") in terms of ability.

what is the advantage of interface over abstract classes?

In Java, abstract classes give the ability to define both concrete and abstract methods whereas interfaces only give the ability to implement abstract methods.
I believe overriding methods in subclasses/implementations is possible in both cases, therefore, what is the real advantage of one over the other (interfaces vs abstract classes in Java)?
Interfaces are for when you want to say "I don't care how you do it, but here's what you need to get done."
Abstract classes are for when you want to say "I know what you should do, and I know how you should do it in some/many of the cases."
Abstract classes have some serious drawbacks. For example:
class House {
}
class Boat {
}
class HouseBoat extends /* Uh oh!! */ {
// don't get me started on Farmer's Insurance "Autoboathome" which is also a helicopter
}
You can get through via an interface:
interface Liveable {
}
interface Floatable {
}
class HouseBoat implements Liveable, Floatable {
}
Now, abstract classes are also very useful. For example, consider the AbstractCollection class. It defines the default behavior for very common methods to all Collections, like isEmpty() and contains(Object). You can override these behaviors if you want to, but... is the behavior for determining if a collection is empty really likely to change? Typically it's going to be size == 0. (But it can make a big difference! Sometimes size is expensive to calculate, but determining whether something is empty or not is as easy as looking at the first element.)
And since it won't change often, is it really worth the developer's time to implement that method every... single... time... for every method in that "solved" category? Not to mention when you need to make a change to it, you're going to have code duplication and missed bugs if you had to re-implement it everywhere.
Interfaces are useful because Java doesn't have multiple inheritance (but you can implement as many interfaces as you like).
Abstract classes are useful when you need concrete behaviour from the base class.
The facts are-
Java doesn't support multiple inheritance
Multiple interfaces can be implemented
Few methods in an abstract class may be implemented
These facts can be used to tilt the advantage in favor of interfaces or abstract classes.
If there are more than one behavior that a class must share with other classes, interfaces win.
If a method definition has to be shared/ overridden with other classes, abstract classes win.
An class may implement several interfaces, whereas it may only extend one class (abstract or concrete), because Java does not support multiple inheritance.
In OOP (mostly independent of a concrete language) abstract classes are a re-use mechanism for the class hierarchy for behaviour and structure which isn't complete on its own.
Interfaces are mechanism for specification of requirements on a module (e.g. class) independently of the concrete implementation.
All other differences are technical details, important is different usage.
You dont override an interface. You implement it.
Writing an interface gives implementors the ability to implement your interface and also other interfaces in addition to inheriting from a base class.
Abstract classes can be partially or fully implemented.Marking a class abstract just prevents you from instantiating an object of that type.
-Method without any implementation is abstract method,whenever a class contains one or more abstract method,then it must be declared as a abstract class
-Interface is fully abstract which cannot have constructor,instance and static blocks,and it contains only two types of members
1.public abstract method
2.public-static-final variable
*Both cannot be instantiated but reference can be created.
*Which one suits better depends on the application
-Interfaces are useful because Java classes will not support multiple inheritance but interfaces do.
-Abstract classes are useful when you need concrete behavior from the base class.
The main advantages of interface over abstract class is to overcome the occurrence of diamond
problem and achieve multiple inheritance.
In java there is no solution provided for diamond problem using classes.For this reason multiple inheritance is block using classes in java.
So to achieve multiple inheritance we use interface .
class Animal
{ void move(){} }
class Bird
{ void move(){fly} }
class Fish
{ void move(){swim} }
Now, if class Animal is abstract class like
Animal a;
a= new Bird(); or a = new Fish()
Here, abstraction works well, but if there are 100 objects like Animal a[100];
You can not write new Bird().move or new Fish().move 100 times
Use interface and write a[i].move. It will differentiate as bird or fish and that move() will be invoked
Second it supports multiple inheritance as class A can implements as many interfaces.
Amazing answers!!
I too want to put my opinion on Interface.
As the name says it is interface which means it will provide interface between two classes.
It help a class or interface hold multiple behavior at the same time.
Who ever having the interface can access the behavior of the class agreed with the interface.
interface teacher
{
//methods related to teacher
}
interface student
{
//methods related to student
}
interface employee
{
//methods related to employee
}
class Person:teacher,student,employee
{
//definition of all the methods in teacher,student, employee interface
//and method for person
}
Now here which ever class is having teacher interface will have access to only teacher behavior of Person.
Similarly the class or module having student interface will have access to only student behavior of person.
Using abstract class, it is not at all possible.
Hope this will add some additional points. :)
Happy coding!!.

Abstract Base Class or Class?

For my semester project, my team and I are supposed to make a .jar file (library, not runnable) that contains a game development framework and demonstrate the concepts of OOP. Its supposed to be a FRAMEWORK and another team is supposed to use our framework and vice-versa. So I want to know how we should start. We thought of several approaches:
1. Start with a plain class
public class Enemy {
public Enemy(int x, int y, int health, int attack, ...) {
...
}
...
}
public class UserDefinedClass extends Enemy {
...
}
2. Start with an abstract class that user-defined enemies have to inherit abstract members
public abstract class Enemy {
public Enemy(int x, int y, int health, int attack, ...) {
...
}
public abstract void draw();
public abstract void destroy();
...
}
public class UserDefinedClass extends Enemy {
...
public void draw() {
...
}
public void destroy() {
...
}
}
3. Create a super ABC (Abstract Base Class) that ALL inherit from
public abstract class VectorEntity {
...
}
public abstract class Enemy extends VectorEntity {
...
}
public class Player extends VectorEntity {
...
}
public class UserDefinedClass extends Enemy {
...
}
Which should I use? Or is there a better way?
Well, it's a bit hard to say for sure without knowing in depth what you're doing, and even then it's rather subjective. However, there are some things to consider which could tell you.
Are they going to actually instantiate an Enemy, or do all enemies really need to be of a derived type? If you're not actually going to be instantiating Enemies rather than derived types, then it should likely be either an interface or an abstract class.
If you're looking to provide actual behavior in your base class, then obviously it needs to be a class rather than an interface.
Methods which need to be there for the API but don't make any sense for you to be providing any implementations for should be abstract.
Methods where it makes good sense to have implementations for them in the base class should have implementations in the base class. And if it doesn't make good sense for them to be overridden, then make them final.
Making classes share a common base class really only makes sense if they're really sharing behavior or you need to be able to treat them all the same somewhere in your code. If they're not really all that similar, then they probably shouldn't share a base class. For instance, if both Enemy and Player are supposed to be displayable, it may make sense to have a common base class which handles their display functionality. But if Enemy were something that was displayable, and Player was a more abstract concept - like the controller of the game - and wasn't displayable, then it probably wouldn't make sense for them to share a base class. In general, it's better to prefer composition rather than inheritance when building classes, so if the classes in question aren't really going to be sharing behavior and don't really have an "is-a" relationship with a common base class, then they shouldn't share a common base class.
Prefer to have your base classes only share methods, not data. In other words, in an inheritance tree, it's best that only the leaves be instantiable. There are various things like equals() which break down when you have base classes with actual data in them. That's not to say that you can't do that - people do it all the time - but it can cause problems and is best avoided if it isn't needed.
Prefer to override abstract methods. Otherwise, in derived classes, you risk not calling the base class' method or totally changing what the method does.
I'm sure that I could come up with more, but without really being familiar with your project, it's bound to be rather generic. Out of the 3 options that you gave, I'd probably go with 2. 3 seems like you'd probably be creating a base class for unrelated classes, and 1 would result in Enemy being instantiatable, which you probably don't need and would definitely make it so that more than the leaves in your inheritance hierarchy would be instantiatable. You'll probably still end up with data in base classes with 2, but you're more likely to only be overriding abstract methods, and you'll have fewer problems with altered behavior in derived classes.
A fourth option would be to use interfaces.
interface Enemy {
public void draw();
. . .
}
If you're just starting out, I would avoid your third option. Let the framework develop a little and see if there's a need for it.
My rule of conduct is that a long as there are more than one class that share the same operations/data/methods/functionality, they should be extensions of the same abstract class.
So, if it was me doing it:
If ALL classes have something in common, have an top-level abstract class that gathers this functionality/fields/data in one place.
If they don't, only those classes that actually have something in common should extend a lower-level abstract class.
If only methods are what the classes will have in common, interfaces can be used as well. However, I always find that sooner or later I see that the classes that implement the interface have the same private fields. At this point, I transform the interface to an abstract class that holds these private fields (to save on lines of code if nothing else).
Just a small answer out of the book "More effective c++" page 271:
"Make base classes abstract that are not at the end of a hierachy". I'm too lazy to give you the whole chapert, but the autor lists some good reasons for that.

Categories