I am little confused about abstraction in java.
I have checked many pages stating that abstraction is data hiding(Hiding the implementation).
What I understand about abstraction is it is 'partial implementation'. Just define what you are going to need in an abstract class/interface and afterwards extend/implement them and add your own functionality.
What I don't understand is how this is a data hiding? You are going to get access to the code once you implement the class/interface and you will modify it according to your need.
I have checked many questions, articles on this but still confused about this.
Any help is appreciated.
Thanks.
Maybe an example help you better. Suppose you want to implement a Graph class which may be have adjacency list or adjacency matrix to represent its nodes. So in abstract you want to "addNode" "addEdge" to this graph at least:
public abstract class Graph
{
public abstract int addNode();
public abstract void addEdge(int from, int to);
}
Now you can extend two classes:
public class GraphAdjList extends Graph
{
private Map<Integer,ArrayList<Integer>> adjListsMap;
public int addNode()
{
//list based implementation
}
public void addEdge(int from, int to)
{
//list based implementation
}
}
public class GraphAdjMatrix extends Graph
{
private int[][] adjMatrix;
public int addNode()
{
//matrix based implementation
}
public void addEdge(int from, int to)
{
//matrix based implementation
}
}
when you call either of addEdge from these two classes you don't have to worry about the data structure behind it, you just know that you get the result you needed so for example:
Graph g1,g2;
g1 = new GraphAdjList();
g2 = new GraphAdjMatrix();
g1.addEdge(1,2);
g2.addEdge(1,2);
through polymorphism you call two different functions but get the same result as client of the Graph.
Another real life example would be car brakes. As a car client, the manufacturer gives you a pedal to push without knowing what is the implementation of the brake in the back-end. It can be a drum-brake or disc-brake implementation in the back. All you need is to push the brake!
You are confusing abstraction (the programming pattern) with the abstract keyword of the Java language. Despite the similitude, they are only very lightly related semantically.
Abstraction means that you hide the implementation details from the code that uses a class or method. The code using your method does not need to know that you are implementing say, a List, using arrays or dynamic pointers or an embedded database or files in a filesystem.
abstract is used to mark classes that have methods that are only declared and not implemented. It is "abstract" in the sense that they cannot be instantiated, you cannot create any instances out of these classes (but you can create them out of their concrete subclasses).
I'm not sure if this answers your question but if you're talking about abstract classes in general, they are there to provide functionality to a child class that extends it without the child class having to know or deal with all the details of the implementation (it's hidden from the user of the child class).
Let's take a car for example:
public abstract class Vehicle {
protected int _numberOfWheels;
public Vehicle() {
this._numberOfWheels = 4;
}
}
public class Truck extends Vehicle {
public int carryingLoad;
public Truck() {
this.carryingLoad = 4000; // kg or something
}
}
So vehicle is an abstract instance of a vehicle object and already has some functionality associated with it, such as the number of wheels. It's a protected method, so if I create a new instance of truck:
// Inside main
Truck truck = new Truck();
I cannot change the number of wheels, however, if I were to write a function for truck within the class like:
// Inside the Truck class
public void addSpareTire() {
this._numberOfWheels++;
}
So that I could call it like:
// Inside main
truck.addSpareTire();
I could still interact with some variables, but only thorough the functions in the class that extends the abstract class. I can add one tire at a time by calling addSpareTire(), but I could never interact directly with _numberOfWheels from the main function where I am using the Truck object, but I can from inside the Truck class declaration. From the user of the truck object, that information is hidden.
I don't know if this is what you're asking for. Hope this helps.
In Object oriented programming Abstraction is a process of hiding the implementation details from the user, only the functionality will be provided to the user. In other words user will have the information on what the object does instead of how it does it.
check the following link for more details:
http://www.visionsdeveloper.com/tutorial/java/java-abstraction.jsp
You are going to get access to the code once you implement the class/interface and you will modify it according to your need.
I guess you are little confused about the concepts which language gives you like Abstraction here. You always have access to your own code but the things like Abstraction OR Polymorphism gives you the ideal ways which things must be. So in Abstraction you are just saying I know there will be a behavior having name someThing as abstract method but right now you dont know how it will behave, The implementer will tell us how this will be. See following code.
abstract class Game{
public abstract void play();
}
class Football extends Game{
#Override
public abstract void play(){
// write how football play
}
}
class Cricket extends Game{
#Override
public abstract void play(){
// write how Cricket play
}
}
I am here leaving a question for you.
Why you are making class level attributes public/protected/private although you have access to the code when you implement?
I think you are confused about two things
Abstract concept in OOPs and its implementation in Java
abstract class in java
Abstract : There is OOPs concept called Abstract. Here, user can capture necessary features of an object. This abstract concept implemented as class and object in java. So, coming to you question, data hiding, when you capture important features of an object in the form of class those features are accessible only to their own class's object. Here, you are hiding all features of a class from outside the class/world. So, it is called as data hiding
abstract class : This is the feature of the Java implementation. If you don't know complete implementation then you can go for abstract class of java.
Hope this helps you to understand a little
Thanks
Data hiding is when you cannot understand how to work API internally (for example, ArrayList) without reading the documentation. API creators don't provide any access to the array that underlies there.
You hide API implementation from users that will be used it. They shouldn't worry about how it works internally, they are only interested in the functionality which is provided to them.
There is a good article about that.
It is not hiding the information from you, but from the client of your abstraction. Take a look at this example.
public class Demo {
Client client = new Client(new Implementation());
}
public interface Abtraction {
void doWork();
}
public class Implementation implements Abtraction{
#Override
public void doWork() {
//doingTheWork
}
}
public class Client{
private Abtraction theAbstraction;
public Client(Abstraction theAbstraction){
this.theAbstraction = theAbstraction;
}
}
The class Client is unaware of the implementation of Abstraction, this means that the Demo class can provide different implementations of Abstraction without messing up the Client.
Data Hiding is basically hiding details about internal Data Members of a class and only exclusively giving the concerned class access to it.
Thus it avoids unnecessary penetration from other classes in the application or from any other application, meaning other classes cannot access private member variables directly.
Thus in this way you abstract internal details of the concerned class.
Related
I have an interface with a lot of methods. (which i cannot split into different interfaces)
When i create a class that implements the interface i get a lot of methods in 1 class file.
Things get worst when the body of all these methods get larger -> the class file becomes huge and quite difficult to navigate.
Even with ide's like eclipse because the Outline window containing all classes get a vertical scrollbar because not all methods can fit in the outline.
Is there a pattern that prevents this from happening?
No there is no way to split the implementation in many classes.
But you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of methods stay the same.
I am posting this reply after an answer is accepted, hoping that future comers might find it useful.
As simas_ch said:
No there is no way to split the implementation in many classes. But
you can delegate from the implementing class to any other classes.
This will reduce the code in the implementation but the number of
methods stay the same.
Once I worked on a rather huge application in which I had to define a Lifecycle interface, which contained many states and many functions that could create a hassle, so I came around with something like this:
You can create a class and make it abstract and implement most of the common functions.
public interface TheBigFunctional {
public void functionalA();
public void functionalB();
public void functionalC();
//....
public void functionalZ();
}
public abstract class FunctionalBase implements TheBigFunctional {
public void functionalA() {
aInternal();
}
protected abstract void aInternal();
// Rest of methods implementations.
// You may choose to skip those if you want child classes to implement them.
}
public class FunctionalTypeFoo extends FunctionalBase {
// Implementations.
}
public class FunctionalTypeBar extends FunctionalBase {
// Implementations.
}
There are many (good) ways to come around the sitation, but I am sharing what I did.
I do not quite understand why you cannot split the interface into multiple ones...
I surely would try to use inheritance, like:
First interface:
public interface FatherInterface {
String methodOne(String var);
String methodTwo(String var);
String methodThree(String var);
}
Second interface:
public interface SonInterface extends FatherInterface {
String methodFour(String var);
String methodFive(String var);
}
Third interface:
public interface SecondSonInterface extends SonInterface {
String methodSix(String var);
String methodSeven(String var);
}
And so on... Each interface inheriting from the preceding one.
As for class files becoming large, go with inheritance too.
Father class:
public class Father implements FatherInterface
Son class:
public class Son extends Father implements SonInterface
And so on...
Edit
If you cannot split the interface (as when given by third party), I would do the implementations of the methods by parts. That is, only some of them implemented in each class. Using abstract classes if needed (or leaving blank methods). Each class inheriting from the above and implementing some of the remaining methods.
Perhaps you could employ the strategy pattern on the big interface by implementing some of those methods from different classes. Then, when you wish to use any of those methods, simply call it from the class that implements your 'large' interface.
More on strategy pattern here: https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
In this case i would consider whether all methods in your class are well designed. Probably they do not have clear purpose and should be splitted per few.
You have to define clear purpose of some particular interface.
Besides, if you are using Java 8, consider ability to provide some default implementation for some methods.
Is there a pattern that prevents this from happening?
In Java:
Subtyping: If you can group sets of methods into different interfaces such that a clear hierarchical relation makes sense. This is what the accepted answer is assuming.
Interface Segregation: If you can group sets of methods into different sibling "domains" or "categories". Take a look at this example from jcabi-github. See how Github is this API's entrypoint, while exposing different sets of functionalities via successive "grouping" interfaces.
It seems that an abstract class means the definition of the class is not complete and hence cannot be instantiated.
And I saw some simple Java code which has an abstract class with all of the methods defined. Then I was wondering, why do they make it as an abstract class instead of a real class? Are they doing this so we cannot instantiate from this abstract class? Or they are getting other benefits from making an abstract class with everything defined?
It is possible that even though all the methods had a default implementations, these implementations weren't actually meaningful in the context of the application. The methods might only do internal bookkeeping while the actually useful implementation must be provided by a derived class which does what it needs to do and then calls the superclass method.
However, this is just speculation. You would have to show an actual example to tell what could be the reason for this design.
As an example, let's take a simple game engine. I have lot's of different GameObjects in my game.
Some are visible, so my basic class gets a draw() method. But there might be invisible objects like trigger areas which don't show up at all, so I implement it as a no-op in the base class.
Some do something when they collide with something, so each one gets a collide(other) method. But some don't do anything when they collide like a purely visual particle effect, so I also provide a no-op in the base class.
Some do something every game tick, so they get a update() method. But some objects, like a wall, might not do anything at all on their own. So I also provide a no-op for this.
So what do I do when I have an object which is invisible, doesn't do anything on its own and doesn't interact with anything? There is no reason to have this in the game. So I make this basic class abstract. Theoretically you could instance it because all methods have an implementation, but practically you have no reason to ever do this, and when you try, you misunderstood how my game engine works.
One typical use case is the creation of an adapter class. Think of a callback interface where you could be notified of 10 different events but are normally only interested in some of them. With an adapter class, you can provide empty implementations such that an actual callback only needs to implement those methods that are of interest after extending the adapter. By making the adapter abstract, you express the fact that it makes no sense to instantiate the adapter itself as it does nothing useful.
Since Java 8, you would not longer implement such an adapter but use default methods for the interface.
Yes, there is. Sometimes you know you're creating an abstract class - one that will have to be derived from to make any actual sense, but you want to provide a default implementation to all the methods. This doesn't happen a lot, but it does happen.
UPDATE:
I just had a case like this. I'm recording various user generated events. Each event has a TimeSpan and a Description, and they all have other things as well. I've created a base event class:
public abstract class BaseEvent
{
public TimeSpan EventTime {get; private set;}
public string Description {get; protected set;}
public BaseEvent(TimeSpan time, string desc) ...
}
Granted, this is C# and not Java, but had I written this in Java, I would have done exactly the same thing)
You can have an abstract class that implements several interfaces. You need not implement these methods in an abstract class, but you do need to implement them in a subclass of your abstract class.
E.g.
public interface MyInterface{
void hello();
}
public abstract class Clazzy implements MyInterface {
//I need not have the interface method.
}
public class MySubclass extends Clazzy {
#Override
public void hello() {
// I need to be here
}
}
If a Java class is declared abstract yet has all of its methods declared, then they are doing it so it cannot be instantiated, though it may be subclassed.
"Abstract classes cannot be instantiated, but they can be subclassed."
See here: https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
You might have some classes that don't make sense in the context of your application but they do in the design.
A silly example:
Abstract class animal, implement born and die. You don't want an "animal". You want a Dog.
This way you don't have to repeat the code each class you add. Now you can have Dog, Cat or whatever you want, this would be a good reason, anyway it's hard to find.
I see this question is already marked answered, but I'd like to provide another alternative explanation.
Another reason for this kind of code would be to provide a base implementation for all derived classes of that abstract class.
Then when implementing new derived classes you have a runable implementation that you can then choose to override the methods of in order to customize behavior for that derived instance.
Take the case of an BaseItemBuilder which is abstract and provides data access logic based on a common argument, such as ItemNumber.
(Sorry for the C# code but this question is pretty much just programming theory more than it's about a specific language)
public abstract class BaseItemBuilder { /*I don't want anyone using this directly but I do want the base specification*/
public virtual void GetInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetItemInfo(itemNumber);
//project values on to internal representation of item
}
public virtual void GetMoreInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetMoreItemInfo(itemNumber);
//project values on to internal representation of item
}
public virtual void GetEvenMoreInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetEvenMoreItemInfo(itemNumber);
//project values on to internal representation of item
}
public virtual void GetYetMoreInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetYetMoreItemInfo(itemNumber);
//project values on to internal representation of item
}
}
You could then derive a NormalItemBuilder which uses the base implementation. This accounts for 80% of the items that you are tracking.
public class BaseItemBuilder {
/*I use the base implementation!*/
}
Then you derive a SpecialType1ItemBuilder that goes to a couple of different data services to acquire information about that particular item type, but still uses some of the base implementation defaults. This covers the next 10%.
public class SpecialType1ItemBuilder { /*I don't want anyone using this directly but I do want the base specification*/
public override void GetInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetType1ItemInfo(itemNumber);
//project values on to internal representation of item
}
public override void GetYetMoreInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetYetMoreType1ItemInfo(itemNumber);
//project values on to internal representation of item
}
}
Then you derive a `SpecialType2ItemBuilder' that goes to yet another set of sporadic dataservices to complete a picture of that item. This one goes overrides another set of methods that are different from Type2ItemBuilder. This covers your last 10%.
public class SpecialType2ItemBuilder { /*I don't want anyone using this directly but I do want the base specification*/
public override void GetInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetType2ItemInfo(itemNumber);
//project values on to internal representation of item
}
public override void GetMoreInfoAboutItem(int itemNumber){
var infoModel = _infoDataService.GetMoreType2ItemInfo(itemNumber);
//project values on to internal representation of item
}
}
As I looked at many of the interface answers from questions here, and on Google and on this video class tutorial I am looking at I have a question. I am asking here because I can't comment if my reputation is not high so hopefully this is not to redundant. I am understanding that interfaces is like psuedocode but with more of an actual way to implement your psuedocode into the program. I undertsand
public Interface someInterface{
public void doSomething();
}
is like saying we need that function in our program so lets make this interface so when we do this
public class imDoingSomething implements someInterface{ // looking at the implements someInterface
#Override // optional
public void doSomething(){
System.out.println("Doing Something");
}
}
it makes sure as I write my program I don't forget to write this function for it is vital to my program. Is this correct?
In your example you have correctly implemented an interface. An interface can be viewed as a contract that a class must fulfill. Knowing that the class has met the requirements specified by an interface allows the object to used as the interfaces type by client code and guarantees particular methods will exist with a specified signature. This can make code more abstract and reusable for a variety of types.
So if we have an interface Playable:
public interface Play{
public void play();
}
And two classes implementing Playable:
public class Record implements Playable{
public void play(){
System.out.println("Playing Record");
}
}
public class MP3 implements Playable{
public void play(){
System.out.println("Playing MP3");
}
}
They can be used in an abstract manner by a client because it knows all classes implementing Playable have a play method:
public class Application{
List<Playable> audioFiles = new ArrayList<Playable>();
public static void main(String[] args){
audioFiles.add(new Record());
audioFiles.add(new MP3());
for(Playable p: audioFiles){
play(p);
}
}
public static void play(Playable playable){
playable.play();
}
}
On a side note
Follow Java naming standards when creating classes or interfaces. In Java these types use a capital letter for each word in the name. So your example would have a SomeInterface interface and a ImDoingSomething class.
It's more easy if you see interfaces from a consumer perspective - when you have a class which uses other objects and does not care about how these objects are concretely defined but only how these objects should behave, one creates an interface providing the methods and using it internally - and everyone which wants to use this certain class has to provide access to his data through implementing the interface so that the class knows how access everything on a code level.
An interface is a collection of abstract methods[No defination]. A class implements an interface, thereby inheriting the abstract methods of the interface.With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public.
You can not instantiate an interface - you can instantiate one of their subclasses/implementers.
Examples of such a thing are typical in the use of Java Collections.
List<String> stringList = new ArrayList<String>();
List is interface but the instance itself is an ArrayList
Interfaces are a way of enforcing design restrictions. By declaring the type of a variable or parameter as an interface, you're sure that the instance referenced by that variable or parameter is going to have an implementation for every method of the interface. That's the basis of polymorphism.
First of all... Sorry for this post. I know that there are many many posts on stackoverflow which are discussing multiple inheritance. But I already know that Java does not support multiple inheritance and I know that using interfaces should be an alternative. But I don't get it and see my dilemma:
I have to make changes on a very very large and complex tool written in Java. In this tool there is a data structure built with many different class objects with a linked member hierarchy. Anyway...
I have one class Tagged which has multiple methods and returns an object tag depending on the object's class. It needs members and static variables.
And a second class called XMLElement allows to link objects and in the end generate a XML file. I also need member and static variables here.
Finally, I have these many many data classes which nearly all should extend XMLElement and some of them Tagged.
Ok ok, this won't work since it's only possible to extend just one class. I read very often that everything with Java is ok and there is no need for having multiple inheritance. I believe, but I don't see how an interface should replace inheritance.
It makes no sense to put the real implementation in all data classes since it is the same every time but this would be necessary with interfaces (I think).
I don't see how I could change one of my inheritance classes to an interface. I have variables in here and they have to be exactly there.
I really don't get it so please can somebody explain me how to handle this?
Actually, I have no good answer other than Java SHOULD have Multiple Inheritance. The whole point that interfaces should be able to replace the need for Multiple Inheritance is like the big lie that when repeated enough times becomes true.
The argument is that Multiple Inheritance causes all these problems (la-di-dah), yet I keep hearing those arguments from Java developers who have never used C++. I also don't EVER remember C++ programmers saying "Gee, I love C++, but if they would only get rid of Multiple Inheritance, it would become a great language". People used it when it was practical and didn't when it wasn't.
Your problem is a classic case of where Multiple Inheritance would be appropriate. Any suggestion to refactor the code is really telling you how to work around the PROBLEM that Java has no Multiple Inheritance.
Also all the discussion that "oh, delegation is better, la-di-dah" is confusing religion with design. There is no right way. Things are either more useful or less useful and that is all.
In your case Multiple Inheritance would be more useful and a more elegant solution.
As far as refactoring your code into a less useful form to satisfy all the religious people who have never used Multiple Inheritance and believe "Multiple Inheritance is bad", I guess you will have to downgrade your code because I don't see Java "improving" in that way any time soon. There are too many people repeating the religious mantra to the point of stupidity that I can't see it ever being added to the language.
Actually, my solution for you would be "x extends Tagged, XMLElement" and that would be all.
...but as you can see from the solutions provided above, most people think that such a solution would be WAY TOO COMPLEX AND CONFUSING!
I would prefer to venture into the "x extends a,b" territory myself, even if it is a very frightening solution that might overwhelm the abilities of most Java programmers.
What is even more amazing about the solutions suggested above is that everyone here who suggested that you refactor your code into "delegation" because Multiple Inheritance is bad, would, if they were confronted with the very same problem, would solve the problem by simply doing: "x extends a,b" and be done with it, and all their religious arguments about "delegation vs inheritance" would disappear. The whole debate is stupid, and it only being advanced by clueless programmers who only demonstrate how well they can recite out of a book and how little they can think for themselves.
You are 100% correct that Multiple Inheritance would help, and no, you are doing anything wrong in your code if you think Java should have it.
You should probably favor composition (and delegation) over inheritance :
public interface TaggedInterface {
void foo();
}
public interface XMLElementInterface {
void bar();
}
public class Tagged implements TaggedInterface {
// ...
}
public class XMLElement implements XMLElementInterface {
// ...
}
public class TaggedXmlElement implements TaggedInterface, XMLElementInterface {
private TaggedInterface tagged;
private XMLElementInterface xmlElement;
public TaggedXmlElement(TaggedInterface tagged, XMLElementInterface xmlElement) {
this.tagged = tagged;
this.xmlElement = xmlElement;
}
public void foo() {
this.tagged.foo();
}
public void bar() {
this.xmlElement.bar();
}
public static void main(String[] args) {
TaggedXmlElement t = new TaggedXmlElement(new Tagged(), new XMLElement());
t.foo();
t.bar();
}
}
Similar to what Andreas_D suggested but with the use of inner classes. This way you indeed extend each class and can override it in your own code if desired.
interface IBird {
public void layEgg();
}
interface IMammal {
public void giveMilk();
}
class Bird implements IBird {
public void layEgg() {
System.out.println("Laying eggs...");
}
}
class Mammal implements IMammal {
public void giveMilk() {
System.out.println("Giving milk...");
}
}
class Platypus implements IMammal, IBird {
private class LayingEggAnimal extends Bird {}
private class GivingMilkAnimal extends Mammal {}
private LayingEggAnimal layingEggAnimal = new LayingEggAnimal();
private GivingMilkAnimal givingMilkAnimal = new GivingMilkAnimal();
#Override
public void layEgg() {
layingEggAnimal.layEgg();
}
#Override
public void giveMilk() {
givingMilkAnimal.giveMilk();
}
}
First it makes no sense to put the real implementation in all data classes since it is the same every time but this would be necessary with interfaces (I think).
How about using aggregation for the tags?
Rename your Tagged class to Tags.
Create a Tagged interface:
interface Tagged {
Tags getTags();
}
Let each class that needs to be "tagged", implement Tagged and let it have a tags field, which is returned from getTags.
Second I don't see how I could change one of my inheritance classes to an interface. I have variables in here and they have to be exactly there.
That's right, interfaces can't have instance variables. The data structures storing the tags however, shouldn't necessarily IMO be part of the classes that are tagged. Factor out the tags in a separate data structure.
I'd solve it that way: extract interfaces for the Tagged and XMLElement class (maybe you don't need all methods in the public interface). Then, implement both interfaces and the implementing class has a Tagged (your actual concrete Tagged class) and an XMLElement (your actual concrete XMLElement class):
public class MyClass implements Tagged, XMLElement {
private Tagged tagged;
private XMLElement xmlElement;
public MyClass(/*...*/) {
tagged = new TaggedImpl();
xmlElement = new XMLElementImpl();
}
#Override
public void someTaggedMethod() {
tagged.someTaggedMethod();
}
}
public class TaggedImpl implements Tagged {
#Override
public void someTaggedMethod() {
// so what has to be done
}
}
public interface Tagged {
public void someTaggedMethod();
}
(and the same for XMLElement)
one possible way;
1- You can create base class(es) for common functionality, make it abstract if you dont need to instantiate it.
2- Create interfaces and implement those interfaces in those base class(es). If specific implementation is needed, make the method abstract. each concrete class can have its own impl.
3- extend the abstract base class for in concrete class(es) and implement specific interfaces at this level as well
Just wondering if one could not simply use inner (member) classes (LRM 5.3.7)?
E.g. like this (based on the first answer above):
// original classes:
public class Tagged {
// ...
}
public class XMLElement {
// ...
}
public class TaggedXmlElement {
public/protected/private (static?) class InnerTagged extends Tagged {
// ...
}
public/protected/private (static?) class InnerXmlElement extends XMLElement {
// ...
}
}
This way you have a class TaggedXmlElement which actually contains all elements from the two original classes and within TaggedXmlElement you have access to non-private members of the member classes. Of course one would not use "super", but call member class methods.
Alternatively one could extend one of the classes and make the other a member class.
There are some restrictions, but I think they can all be worked around.
Well using Interface and single base class you are simply stating:
A) One object can be of only one type (Which is true in real life if you think ,
A pigeon is a bird, a toyota is a car , etc .. A pigeon is also an animal but every bird is animal anyway, so its hierarchically above the bird type -And in your OOP design Animal class should be base of Bird class in case you need to represent it -)
and
B) can do many different things (A bird can sing, can fly . A car can run , can stop ,etc..) which also fits the real life objects.
In a world where objects can be of multiple types (horizontally)
Let's say a a dolphin is a mammal and also a sea animal, in this case multiple inheritance would make more sense. It would be easier to represent it using multiple inheritance.
Using composition would be the way to go as another developer suggested. The main argument against multiple inheritance is the ambiguity created when you're extending from two classes with the same method declaration (same method name & parameters). Personally, however, I think that's a load of crap. A compilation error could easily be thrown in this situation, which wouldn't be much different from defining multiple methods of the same name in a single class. Something like the following code snippet could easily solve this dilema:
public MyExtendedClass extends ClassA, ClassB {
public duplicateMethodName() {
return ClassA.duplicateMethodName();
}
}
Another argument against multiple inheritance is that Java was trying to keep things simple so that amateur developers don't create a web of interdependent classes that could create a messy, confusing software system. But as you see in your case, it also complicates and confuses things when it's not available. Plus, that argument could be used for a 100 other things in coding, which is why development teams have code reviews, style checking software, and nightly builds.
In your particular situation though, you'll have to settle with composition (see Shojaei Baghini's answer). It adds a bit of boiler plate code, but it emulates the same behavior as multiple inheritance.
I run in a similar problem on Android. I needed to extend a Button and a TextView (both inheriting from View) with additional functions. Due to not having access to their super class, I needed to find another solution. I´ve written a new class which encapsulates all the implementations:
class YourButton extends Button implements YourFunctionSet {
private Modifier modifier;
public YourButton(Context context) {
super(context);
modifier = new Modifier(this);
}
public YourButton(Context context, AttributeSet attrs) {
super(context, attrs);
modifier = new Modifier(this);
}
public YourButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
modifier = new Modifier(this);
}
#Override
public void generateRandomBackgroundColor() {
modifier.generateRandomBackgroundColor();
}
}
class Modifier implements YourFunctionSet {
private View view;
public Modifier(View view) {
this.view = view;
}
#Override
public void generateRandomBackgroundColor() {
/**
* Your shared code
*
* ......
*
* view.setBackgroundColor(randomColor);
*/
}
}
interface YourFunctionSet {
void generateRandomBackgroundColor();
}
The problem here is, your classes need the same super class. You can also try to use different classes, but check which type it is from, for example
public class Modifier{
private View view;
private AnotherClass anotherClass;
public Modifier(Object object) {
if (object instanceof View) {
this.view = (View) object;
} else if (object instanceof AnotherClass) {
this.anotherClass = (AnotherClass) object;
}
}
public void generateRandomBackgroundColor(){
if(view!=null){
//...do
}else if(anotherClass!=null){
//...do
}
}
}
So here is basically my Modifier class the class which encapsulates all implementations.
Hope this helps someone.
For example suppose I have a class Vehicle and I wish for a subclass ConvertibleVehicle which has extra methods such as foldRoof(), turboMode(), foldFrontSeats() etc. I wish to instantiate as follows
Vehicle convertible = new ConvertibleVehicle()
so I still have access to common method such as openDoor(), startEngine() etc. How do I designed such a solution?
To clarify my two initial solutions, neither of which I am happy with are:
Have dummy methods foldRoof(), turboMode(), foldFrontSeats() which I override in ConvertibleVehicle only, leaving them to do nothing in other subclasses
Have abstract methods foldRoof(), turboMode(), foldFrontSeats() and force each subclass to provide an implementation even if it will be blank in all instances other than ConvertibleVehicle
The above seem slightly convoluted since they both pollute the base class as I add an increasing number of subclasses each with their own unique functions
After reading some of the responses perhaps there is some type of fundamental flaw in my design. Suppose I have a class VehicleFleet which takes vehicles and instructs them to drive as follows:
public VehicleFleet(Vehicle[] myVehicles) {
for (int i=0; i < myVehicles.length; i++) {
myVehicles[i].drive();
}
}
Suppose this works for dozens of subclasses of Vehicle but for ConvertibleVehicle I also want to fold the roof before driving. To do so I subclass VehicleFleet as follows:
public ConvertibleVehicleFleet(Vehicle[] myVehicles) {
for (int i=0; i < myVehicles.length; i++) {
myVehicles[i].foldRoof();
myVehicles[i].drive();
}
}
This leaves me with a messy function foldRoof() stuck in the base class where it doesn't really belong which is overridden only in the case of ConvertibleVehicle and does nothing in all the other cases. The solution works but seems very inelegant. Does this problem lend itself to a better architecture?
I'm using Java although I would hope that a general solution could be found that will work in any object oriented language and that I will not need to rely upon language specific quirks
Any objects that use Vehicle shouldn't know about ConvertibleVehicle and its specialized methods. In proper loosely coupled object-oriented design Driver would only know about the Vehicle interface. Driver might call startEngine() on a Vehicle, but it's up to subclasses of Vehicle to override startEngine() to handle varying implementations such as turning a key versus pushing a button.
Consider reviewing the following two links which should help to explain this concept:
http://en.wikipedia.org/wiki/Liskov_substitution_principle
http://en.wikipedia.org/wiki/Open/closed_principle
Consider posting a real world problem that you feel leads to the dilemma you describe here and someone will be more than happy to demonstrate a better approach.
I've done this in similar situations.
Option A)
If the specialized operations are part of the same sequence as a base operation ( e.g. ConvertibleVehicle needs to be foldRoof before it can drive ) then just put the specialized operation inside the base operation.
class Vehicle {
public abstract void drive();
}
class ConvertibleVehicle {
public void drive() {
this.foldRoof();
.... // drive
}
private void foldRoof() {
....
}
}
So the effect of driving a fleet will be some of them will fold their roof before being driven.
for( Vehicle v : vehicleFleet ) {
v.drive();
}
The specialized method is not exposed in the object public interface but is called when needed.
Option B)
If the specialized operation are not part of the same sequence and must be called under certain "special" circumstances then let a specialized version of a client call those specialized operations. Warning, this is not so pure nor low coupling but when both objects ( the client and the service ) are created by the same "condition" or builder then most of the times is ok.
class Vehicle {
public void drive() {
....
}
}
class ConvertibleVehicle extends Vehicle {
// specialized version may override base operation or may not.
public void drive() {
...
}
public void foldRoof() { // specialized operation
...
}
}
Almost the same as the previous example, only in this case foldRoof is public also.
The difference is that I need an specialized client:
// Client ( base handler )
public class FleetHandler {
public void handle( Vehicle [] fleet ) {
for( Vehicle v : fleet ) {
v.drive();
}
}
}
// Specialized client ( sophisticate handler that is )
public class RoofAwareFleetHandler extends FleetHandler {
public void handle( Vehicle [] fleet ) {
for( Vehicle v : fleet ) {
// there are two options.
// either all vehicles are ConvertibleVehicles (risky) then
((ConvertibleVehicles)v).foldRoof();
v.drive();
// Or.. only some of them are ( safer ) .
if( v instenceOf ConvertibleVehicle ) {
((ConvertibleVehicles)v).foldRoof();
}
v.drive();
}
}
}
That instaceof look kind of ugly there, but it may be inlined by modern vm.
The point here is that only the specialized client knows and can invoke the specialized methods. That is, only RoofAwareFleetHandler can invoke foldRoof() on ** ConvertibleVehicle**
The final code doesn't change ...
public class Main {
public static void main( String [] args ) {
FleetHandler fleetHandler = .....
Vehicles [] fleet = ....
fleetHandler.handle( fleet );
}
}
Of course, I always make sure the fleethandler and the array of Vehicles are compatible ( probably using abstrac factory or builder )
I hope this helps.
This is a good question. What it implies is that you have (or expect to have) code that asks a Vehicle to (for instance) foldRoof(). And that's a problem, because most vehicles shouldn't fold their roofs. Only code that knows it's dealing with a ConvertibleVehicle should call that method, which means it is a method that should be only in the ConvertibleVehicle class. It's better this way; as soon as you try to call Vehicle.foldRoof(), your editor will tell you it can't be done. Which means you either need to arrange your code so that you know you're dealing with a ConvertibleVehicle, or cancel the foldRoof() call.
I think most people are missing the point of Delta's question. It looks to me like he/she isn't asking about what inheritance is. He/She is asking about subclasses implementing functionality that is not a natural fit for a base class, and the resulting mess that can ensue. I.e. the pushing of specific methods / functionality up the hierarchy chain, or requiring that subclasses implement a contract for functionality that isn't a natural fit.
There is also the matter of whether it is valuable to be able to treat a base class like the subclass in every case (to avoid casting and use them interchangeably). *edit -- this is called the Liskov substitution principle (thanks for reminding me, Kyle).
This is just what subclassing does: adds functionality not present in a base class.
class MyVehicle : public Vehicle {
public:
void MyNewFunction()
...
There are two (really just) different flavors of inheritance: public and private, reflecting the Is-A and Has-A relationships respectively. With public inheritance, you're directly adding stuff to a class. If I have class Animal with methods Eat() and Walk(), I may make a subclass called Cat which has the method Purr(). A Cat then has public methods Eat, Walk, and Purr.
In the case of a Stack based on a LinkedList however, I may say that a Stack HAS-A LinkedList internally. As such, I do not expose any features of the base class publically, I retain them as private and have to explicitly offer whatever I choose as public. A list may have a method Insert(), but for the Stack, I restrict the implementation and rexpose it as Push(). No previous public methods are exposed.
In C++, this is defined by the access modifier given before the base class. Above, I'm using public inheritance. Here, I use private inheritance:
class MyVehicle : private Engine {
This reflects that MyVehicle HAS-An Engine.
Ultimately, subclassing takes everything available in the base class and adds new stuff to it.
EDIT:
With this new information it seems that you're really looking for, it seems, is interfaces as stated by an earlier (voted down) comment. This is one of the big problems with inheritance - granularity. One of C++'s big complaints is its implementation of multiple inheritance (an option to accomplish this.) Can you state specifically what language you're using so we can advise properly?
To add on to Kyle W. Cartmell's excellent answer, and to perhaps simplify Oscar Reyes's answer a tad...
You might want to consider having the base class define a method called prepareToDrive() where inherited classes could put any setup tasks that need to be done before starting up. Calling drive() would be the way to start everything up from the user's perspective, so we would need to refactor drive into a "setup" phase and a "go" phase.
public class Vehicle {
protected void prepareToDrive() {
// no-op in the base class
}
protected abstract void go();
public final void drive() {
prepareToDrive();
go();
}
}
Now, subclasses must implement the protected method go() (really bad method name, but you get the idea), which is where they do their class-specific handling of driving.
Now, your inherited class could look like this:
public class ConvertableVehicle extends Vehicle {
// override setup method
protected void prepareToDrive() {
foldRoof();
}
protected void go() {
// however this works
}
protected void foldRoof() {
// ... whatever ...
}
}
This structure would also help when you run into class TractorTrailerRig that needs to make sure the trailer is loaded and correctly attached before it can drive.
How does the user of Vehicle know its a ConvertibleVehicle? Either they need to dynamic cast to ensure it is correct, or you've provided a method in Vehicle to get the objects real type.
In the first case the user already has a ConvertibleVehicle as part of dynamic cast. They can just use the new pointer/reference to access ConvertiblVehicle's methods
In the second case where the user verifies the objects type with one of Vehicles methods they can just cast the Vehicle to ConvertibleVehicle and use it.
Generally, casting is a bad idea. Try to do everything with the base class pointer. Your car example doesn't work well because the methods are too low level, build higher level virtual functions.
All that said. I have needed to all a derived classes methods from the base class. I could have cast to the derived class but it was involved in a framework and would have required much more effort. The old adage "all problems can be solved with one more layer of indirection" is how I solved this. I called a virtual method in the base class with the 'name' of the function I wanted to call. 'Name' can be a string or an integer depending on your needs. It's slower, but you should only need to do it rarely, if you class hierarchy is expressive enough.
Having ConvertibleVehicle subclass Vehicle and add its own methods as you describe is perfectly fine. That part of the design is OK. The trouble you have is with fleet. ConvertibleFleet should not be a subclass of VehicleFleet. An example will show you why. Let's say VehicleFleet is like this:
public class VehicleFleet {
// other stuff...
public void add(Vehicle vehicle) {
// adds to collection...
}
}
This is perfectly fine and sensible, you can add any Vehicle or subclass of it to a VehicleFleet. Now, let's say we also have another kind of vehicle:
public class TruckVehicle extends Vehicle {
// truck-specific methods...
}
We can also add this to a VehicleFleet since it's a vehicle. The problem is this: if ConvertibleFleet is a subclass of VehicleFleet, that means we can also add trucks to ConvertibleFleet. That's wrong. A ConvertibleFleet is not a proper subclass, since an operation that's valid for its parent (adding a truck) is not valid for the child.
The typical solution is to use a type parameter:
public class VehicleFleet<T extends Vehicle> {
void add(T vehicle) {
// add to collection...
}
}
This will let you define fleets specific to certain vehicle types. Note that this also means there is no "base" VehicleFleet class that you can pass to functions that don't care what kind of vehicle the fleet has. This can be remedied using another layer of base class (or interface):
public interface VehicleFleetBase {
Vehicle find(String name);
// note that 'add' methods or methods that pass in vehicles to the fleet
// should *not* be in here
}
public class VehicleFleet<T extends Vehicle> {
void add(T vehicle) {
// add to collection...
}
Vehicle find(String name) {
// look up vehicle...
}
}
For methods that are pulling vehicles out of fleets and don't care what kind they are, you can pass around VehicleFleetBase. Methods that need to insert vehicles use VehicleFleet<T> which is safely strongly-typed.