17

The java code I'm working on at the moment has often a structure like

file Controller.java:

interface Controller {...}

file ControllerImpl.java:

class ControllerImpl implements Controller {...}

But for every interface there is only one implementation. Isn't that the same as using header files in C/C++ where I have the code split into files like

Controller.hpp
Controller.cpp

From what I know, header files in C/C++ have been introduced to help the compiler, which is not necessary anymore in Java. Also header files should help with the readability of the code, but having a modern IDE with folding and outline view this is also not a necessity anymore.

So why do people again introduce header files in Java through the back door by programming against interfaces?

asmaier
  • 11,132
  • 11
  • 76
  • 103
  • 2
    "for every interface there is only one implementation" - that just means they haven't written their unit tests yet ;-) – Steve Jessop Feb 18 '11 at 10:46
  • @Steve Jessop: But instead of using an interface and a dummy implementation for unit testing couldn't they simply implement a class and use a mocking framework for their unit tests? – asmaier Feb 18 '11 at 11:01
  • yes, because mocking frameworks "cheat", in the sense that they abstract an interface out of a class without formally declaring it. Defining an interface for *every* concrete class, and never using interfaces for any other purpose, so that there literally is only one class per interface and only ever will be no matter how the code is developed in future, could be considered premature and unused flexibility and is probably misguided. – Steve Jessop Feb 18 '11 at 13:49
  • "Premature Flexibilization Is The Root of Whatever Evil Is Left!" http://dev.hubspot.com/bid/7271/Premature-Flexibilization-Is-The-Root-of-Whatever-Evil-Is-Left – asmaier Feb 18 '11 at 16:15

7 Answers7

10

No. In C++, files (headers) are not the same as classes.

Programming against interfaces as in Java can be done in C++, too, by programming against abstract base classes.

However, the Java term of "interface" is quite restricted. Basically, any function declaration is an interface:

void call_me(int times); 

As are, of course, classes and other types.

In C++, you group such things in headers, so an interface can consist of one header. However, it might just as well consist of multiple headers.

Community
  • 1
  • 1
sbi
  • 219,715
  • 46
  • 258
  • 445
  • But in Java we could also program against abstract base classes. So then why would we need interfaces in Java? – asmaier Feb 18 '11 at 10:20
  • @sbi Well it all depends on what you put in a header file. In my opinion though Java interfaces and header in C++ have nothing in common since Java Interfaces can be assimilated to abstract classes in C++. What can be said about headers which can be comparable with Interfaces ? – lollancf37 Feb 18 '11 at 10:23
  • @asmaier interfaces can used for polymorphism by example. – lollancf37 Feb 18 '11 at 10:27
  • An interface can be implemented by many classes without having to inherit from it. Implementing an abstract class requires inheritance which can make class herarchy very complex. – David Mårtensson Feb 18 '11 at 10:36
  • 1
    @asmaier: In C++ a class can have multiple independent abstract base classes. In Java it can't, but it can implement multiple independent interfaces. So you can't just use abstract base classes in Java the way you can in C++. As David says, the *reason* that Java doesn't have multiple inheritance is that it's complex and difficult. Interfaces in Java are basically the same as having a coding style rule in C++ that says, "you can only use multiple inheritance if at most one of the direct base classes has any data members or non-pure-virtual member functions", avoiding those difficulties. – Steve Jessop Feb 18 '11 at 10:40
  • @David: Except for the syntax, what is the difference between inheritance and interface implementation in Java? – sbi Feb 18 '11 at 11:14
  • @sbi, unfortunately I have done almost none programming in Java so I cannot say but I have been programming C# and a fellow worker tells me its almost identical to Java conceptually in that both use interface instead of multiple inheritance. But In C# at least, for an inheritance you have to explicitly override all methods you need to change, in an interface you can use a helper to "implement interface" creating stubs for all methods in the interface in one go. – David Mårtensson Feb 18 '11 at 11:49
  • @David: Are you saying in C# the main difference between interface implementation and inheritance is that the IDE will create stubs for you when you implement an interface?? – sbi Feb 18 '11 at 11:56
  • @sbi, The most important is that you can implement many interfaces in a class but only inherit from one other class. – David Mårtensson Feb 18 '11 at 11:58
  • @sbi, another thing, with interface you can implement the same method differently depending on the cast, you can have one implementation for each interface. For abstract inheritance you only have one implementation. – David Mårtensson Feb 18 '11 at 12:09
  • @David: Ok, the many vs. one is bogus, because C++ shows that real MI is possible and not all that hard. That other point is interesting, though, but I'm not sure I understand it. What do you mean when you say "implement the same method differently depending on the cast"? – sbi Feb 18 '11 at 13:39
  • @sbi: the principle difference in Java between inheritance and interface implementation is that interfaces are restricted - they can't contain data members and they can't contain method implementations (well, they can have static methods), so there's nothing to "inherit" other than a tag. It formalizes in the language something that the Java designers considered to be a good self-discipline in C++. It also allows them to remove any (other) form of MI, which they don't agree is "not all that hard". I don't find MI in general easy either, although unlike Gosling my response isn't to ban it. – Steve Jessop Feb 18 '11 at 13:59
  • @sbi: IIRC in Java when you invoke a method via an interface, the bytecode specifies two things - the name of the method and the name of the interface it's invoked through. AFAIK, though, the language doesn't actually make use of this. If `IFoo` and `IBar` both have a `baz` function with the same signature but conflicting semantics, then a class can't validly implement both interfaces because it can only provide one `baz()` method implementation. From what David is saying, sounds like in C# you can implement `IFoo.baz` and `IBar.baz` as distinct methods in your class. – Steve Jessop Feb 18 '11 at 14:05
  • @Steve: @David wrote: "An interface can be implemented by many classes without having to inherit from it." Heck, what's the difference? I think that an abstract class in C++ that has only pure virtuals and no data members is what an interface is in Jave/C#. What I'm asking for is: _Is there any fundamental, underlying, core difference between "implementing an interface" and "deriving from an abstract class"?_ From what I know it seems Java's and C#'s interfaces are just restricted abstract base classes, and "implementing an interface" isn't any less complex as deriving from a base. – sbi Feb 18 '11 at 14:07
  • The issue is rarely a problem in Java, but when it is it's a PITA, because for example sometimes you want one object to implement multiple listener/visitor interfaces, and if those interfaces weren't designed together they they might end up conflicting. The fix usually is to implement the interfaces using inner classes rather than your actual class. – Steve Jessop Feb 18 '11 at 14:09
  • @Steve: Yes, I think C# allows that. If so, then that's indeed an important difference to multiple inheritance of abstract base classes. – sbi Feb 18 '11 at 14:09
  • @sbi: no, there's no difference from the POV of a C++ programmer looking in on Java. It's just than in Java terminology, implementing an interface isn't *called* "inheritance". It's less complex at the VM level because (for example) an interface doesn't need to be initialized, nor does it need to be searched for methods when making virtual calls. It's less complex for programmers in the same way that keeping data members out of abstract classes simplifies things for C++ programmers. But if you're implementing Java's `instanceof` operator, parent classes and interfaces are the same. – Steve Jessop Feb 18 '11 at 14:10
  • @sbi. In C# I can have the same method in multiple interfaces, for example `.Report()` but I can implement one version of the report method for each interface so if I store the object in a pointer to interface1 report will call one method and if I store the object in a pointer of type interface2 I will call another method. If you like the same implementation use in internal private method that both implementations call. – David Mårtensson Feb 18 '11 at 15:33
5

Interfaces doesn't come from a desire to keep header files.

Interfaces the closest Java comes to supporting http://en.wikipedia.org/wiki/Design_by_contract

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Why does Java not use abstract classes to implement Design by contract? – asmaier Feb 18 '11 at 10:22
  • Because abstract class have implementations and encapsulated values/methods/constructors which are not part of the contract. – Peter Lawrey Feb 18 '11 at 10:29
  • 1
    In Java you can extend only one class but any number of interfaces. You cannot extends two abstract classes for example. – Peter Lawrey Feb 18 '11 at 10:30
  • @Peter: "abstract class __can__ have implementations and..." – sbi Feb 18 '11 at 13:40
  • @Peter Lawrey So the reason to use interfaces instead of abstract base classes is that a class can implement multiple interfaces, but cannot inherit from multiple abstract classes? – asmaier Feb 18 '11 at 13:44
  • That is one reason. My approach is that interfaces are simpler and if you can do what you need with a interface, otherwise use an abstract class. – Peter Lawrey Feb 18 '11 at 15:26
  • @NateC-K You are right they are not the same thing. I have changed the wording. – Peter Lawrey Apr 04 '12 at 16:25
4

interfaces are more like abstract base classes in c++.

the reason they are often used in java is that multiple inheritance does not exist in java (both were design decisions). c++ supports multiple inheritance, so... it can accomplish the problem that way (and via a few others).

once a class implements an interface in java, then it can be passed as the type. the same principle in c++, although the written implementation is slightly different.

so, the interface simplifies the programming process, since arbitrary objects may be passed, as long as they implement the interface (or in c++ are derived from a specific class). with an interface, you do not need to derive from a common base class -- it's a very simple, and usable design. multiple inheritance in c++ is a pitfall for many developers.

justin
  • 104,054
  • 14
  • 179
  • 226
  • 1
    Or in other words, interfaces in Java (or abstract base classes) allow Objects to have more than one "type" without having to deal with multiple inheritance. Header files separate actual code of something from the method/function signatures - that way the compiler knows how the methods are called, even it doesn't have the actual code to execute. – averell Feb 18 '11 at 10:17
  • @averell +1 thanks for the clarification/simplification -- i tend to write a bit rushed at times: "the compiler's almost done, gotta go!!!" =) – justin Feb 18 '11 at 10:38
3

In Java, an interface defines a contract, while a class provides an implementation of a contract.

Most contracts have only one meaningful or relevant implementation; some even assume a specific implementation and do not allow any other. Those contracts and their implementations are defined together in classes, without any interfaces. Example: java.lang.String.

On the other hand, some contracts do not make any assumption on the possible implementations. Those are defined in interfaces. Partial implementations can be defined in abstract classes, and typical complete implementations can be defined in classes, but the fact that the contract is defined in an interface allows you to write your own implementation of that contract and use it wherever an instance of the contract is expected.

At the file level, both an interface and a class are compilation units and deserve their own file.

As you now hopefully understand, the distinction between header files and implementation files in C++ is very different.

Laurent Pireyn
  • 6,735
  • 1
  • 29
  • 39
1

No, programming against interfaces has nothing to do with whether or not you use header files.

Defining an interface explicitly will allow evolving the program on both sides independently. The 'interface' of a code body denotes the contract to which it obeys.

Programming languages never fully support interface definitions, they merely have some syntactic sugar to handle the type-correctness aspect. Performance aspects, for one, are most of the time unspecificable, just like complexity rules etc... (C++ standard defines some complexity requirements for the containers and algorithms).

This limited support has left Java with the keyword interface: since object orientation is about grouping functionality into classes, it made sense to couple the concept of an 'interface' to something that groups member function definitions. Several classes can implement a given interface, and a class can implement many interfaces as well.

In C++, they didn't even bother to explicitly add 'interface' to the language. The thing that comes closest to the 'class interface' of Java is a pure abtract class: a class with only pure virtual member functions. Since C++ supports multiple inheritance, classes can implement multiple of these 'interfaces'.

When it comes to the separation of your code into headers and source files, that's totally irrelevant to the interface concept. But indeed: in C++, the 'calling contract' is mostly specified in a header file. And indeed, that makes for shorter compilation times (less IO). But that's a compiler-technical aspect.

xtofl
  • 40,723
  • 12
  • 105
  • 192
1

Header files in C/C++ has nothing to do with classes or interfaces at all.

A header file is more like the reference you add to your project, or the using statement.

It's an instruction to the compiler that the object (class) and function declarations in the header file exist so that the compiler can compile the file without having to look through the whole project.

A header file in C++ can contain classes or function definitions, or macros, or enums... or many other things, but is conceptually very different from classes or interfaces.

You can use interfaces in C++, as shown here: How do you declare an interface in C++?.

...and those definitions are placed in header files, but the header file itself is something else.

The reason to use interfaces instead of inheritance is that many classes can implement an interface or many interfaces but you can only inherit from one class.

So if you have many objects, that is, to be interchangeable, you would end up with a very complex class hierarchy - while with interfaces, the classes can be built completely separately with only the interface linking them.

Yun
  • 3,056
  • 6
  • 9
  • 28
David Mårtensson
  • 7,550
  • 4
  • 31
  • 47
1

The question is good, there is a connection between header files and classes/interfaces/OO programming, beyond the raw syntax of the languages.

Proper C++ program design:

  • Put one class declaration, and one only, in a h-file.
  • Give said h-file the same name as the class declared.
  • Put the class definition in a cpp-file with the same name as the h-file.

Proper Java program design:

  • Same as for C++, though also put interfaces in files of their own.

Proper C design:

  • In the h-file, declare functions belonging to a particular "code module".
  • Put the function definitions in a c-file with the same name as the h-file.
  • All variables you would have declared as private/protected if writing C++/Java should either be truly private through the concept of "opaque type/pointers", or be placed at file scope and declared static, so that they can be shared between functions within the "code module" (though that makes the code non-reentrant).

If you don't use the above intimate connection between classes and h-files, there is a fine chance that your program is an unreadable mess, no matter how elegant your OO design is.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I'm not sure I understand your point about Java -- "Same for C++" which to me reads that you have to follow the same rules as above. Except, there are no h-files in Java. It makes no sense to me. – Fuhrmanator Jan 26 '16 at 19:50