Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

According to Herb Sutter one should prefer abstract interfaces (all pure virtual functions) to abstract classes in C++ to decouple the implementation as far as possible. While I personally find this rule very useful, I have recently joined a team with many Java programmers and in the Java code this guideline does not seem to exist. Functions and their implementations are very frequently located in abstract classes. So did I get Herb Sutter all wrong even for C++ or is there a general difference in the usage of abstract functions in C++ compared to Java. Are abstract classes with implementation code more sensible in Java than in C++ and if yes why ?

share|improve this question

migrated from stackoverflow.com Aug 8 '12 at 1:43

This question came from our site for professional and enthusiast programmers.

1  
I had some doubts and finally put it here because it could be due to some design principles that I'm missing about the java oo. So then it is not about a general advice but more about the right and the wrong to use the language –  Martin Aug 7 '12 at 20:54
    
Interfaces are meant to be purely virtual. The idea of abstract classes is that they are partially implemented, and it's up to the implementation to fill in the gaps without repeating code unnecessarily (for example, why have write(byte) and write(int) in every subclass when you can have the abstract class call write(byte) from write(int)) –  Ryan Amos Aug 7 '12 at 20:57
1  
Possibly related: stackoverflow.com/q/1231985/484230 gives a reason the prefer abstract classes in java. For C++ this reason does not seem to hold true due to the existance of free functions that can add functionality at the interface level –  Martin Aug 7 '12 at 21:09
1  
I think the Golden Rule is to "make non-leaf classes abstract", but that doesn't make any "only pure" or "empty" requirements. –  Kerrek SB Aug 7 '12 at 21:13
1  
If it works for you it works for you. I really don't see why people panic once their code no longer adheres to the latest opinions. –  James Aug 8 '12 at 15:19
add comment

4 Answers 4

up vote 5 down vote accepted

OOP has composition and substitution.

C++ has multiple inheritance, template specialisation, embedding and value/move/pointer semantics.

Java has single inheritance and interfaces, embedding and reference semantics.

The common way the OOP school uses these languages is to employ inheritance for object substitution and embedding for composition. But you also need a common ancestor and a way to runtime-cast (in C++ is called dynamic_cast, in Java is just asking an interface from another).

Java does all this by its own java.lang.Object rooted hierachy. C++ doesn't have a predefined common root, so you should at least define it, to come to a same "picture" (but this is limiting some C++ possibilities...).

After that, the possibility to have compile-time polymorphism (think to CRTP) and value semantic can offer also other alternatives to the way the concept of "OOP object" can be ported into a C++ program.

You can even imagine the heresy to use embedding and implicit conversion to manage substitution and private inheritance to manage composition, in fact inverting the traditional school paradigm. (Of course, this way is 20 years younger than the other, so don't expect a wide community support in doing that)

Or you can imagine a virtual common base to all classes, form interface (no implementation) to final classes (fully implemented) going through partially implemented interfaces an even interface clusters, using "dominance" as dispatching from interface to implementations through a "multi stacked-parallelogram" inheritance scheme.

Comparing OOP to java to C++ assuming there is just one and only OOP way is limiting the capabilities of both the languages.

Forcing C++ to strictly adhere to Java coding idioms is denaturating C++ as forcing Java to behave as a C++-like language is denaturating Java.

Is not a matter of "sensibility" but of different "aggregation mechanisms" the two languages have and different way to combine them that makes some idiom more profitable in one language than the other and vice versa.

share|improve this answer
1  
I think this answer is very interesting, since it succintly describes language features as a tool for oo and design principles only as a help and not a doctrine. However you do not need a common root if you want to do oo in c++. This is simply wrong, also for the fact that you have operators and templates (which are a very powerful alternative to the main tree design of java as you also pointed out). Apart from that your points are the most worthwhile in all answers –  Martin Aug 9 '12 at 21:31
1  
@Martin: In "technical sense" you're right, but if you need runtime polymorophism (because the actual type of the instantiated objects depends on program input) a "root" ('a' is an article, not a shortcut for "one and only") is what makes all object "cousins", and the hierarchy run-time-walkable. Different roots originate different ancestries not each-other related. Whether this is "good" or "bad" is a matter of context, not idiom. –  Emilio Garavaglia Aug 10 '12 at 6:44
    
That's true. I thought you were referring to artificially porviding one general root for an entire c++ program and saw it as defect that it is not present, compared to java. But after your edit you make the point quite clear. Thanks again –  Martin Aug 10 '12 at 8:33
add comment

The principle holds for both languages, but you're not doing a fair comparison. You should compare C++ pure abstract classes with Java interfaces.

Even in C++, you can have abstract classes that have some of the functions implemented, but derive from a pure abstract class (no implementations). In Java, you'd have the same abstract classes (with some implementations), that can derive from interfaces (no implementations).

share|improve this answer
    
So when would you prefer an abstract class over an interface class in c++. I always opted for interface plus non-member functions in c++. –  Martin Aug 7 '12 at 20:57
1  
@Martin that depends on the design. Basically, always prefer an interface. But "always" rules have exceptions... –  Luchian Grigore Aug 7 '12 at 20:59
    
True enough but in the Java Code I'm seeing abstract classes largely representing the majority. Could this be due to the fact that free functions working on interfaces are not possible in java ? –  Martin Aug 7 '12 at 21:01
3  
@Martin well free functions are not at all possible in Java, so that might be a reason, yes. Good spot! Answered your own question! You can add an answer yourself, I think that's it. –  Luchian Grigore Aug 7 '12 at 21:03
add comment

Sometimes it makes sense to have some default implementation. For example a generic PrintError(string msg) method that is applicable to all sub classes.

virtual PrintError(string msg) { cout << msg; }

It can still be overridden if really required, but you can save the client some hassle by allowing them just call the generic version.

share|improve this answer
add comment

Generally the same OO principles hold true for Java and C++. However, one big difference is that C++ supports multiple-inheritance while in Java you can only inherit from one class. This is the main reason why Java has interfaces I believe, to supplement for the lack of multiple inheritance and probably to restrict what you can do with it (since there is a lot of criticism over the abuse of multiple inheritance). So, probably in a Java programmers mind, there is a stronger distinction between abstract classes and interfaces. Abstract classes are used to share and inherit behavior while interfaces are simply used to add extra functionality. Remember, in Java you can inherit from only one class, but you can have many interfaces. In C++ however, pure abstract classes (i.e. a "C++ interface") are used to share and inherit behavior unlike the purpose of a Java interface (although you are still required to implement the functions), hence the usage is different from Java interfaces.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.