aspose file tools*
The moose likes Java in General and the fly likes Interfaces Question(s) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Interfaces Question(s)" Watch "Interfaces Question(s)" New topic
Author

Interfaces Question(s)

Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15286
    
    6

Although I have been programming in Java for quite a while now, and although I have used Interfaces from current API's, I have never really programmed any Interfaces for any of my applications I have worked on. Mostly because of my lack of understanding..
Anyway, while working on some C++ code the other day, I made a connection that I would like to discuss and see what everyone else thinks.
In C++, when you create a class, you create 2 files. A header files which contains the Class Definition. Basically all the methods and class members you might use in the Class. And then you create a CPP file which is basically the Class Implementation. In this cpp file you would include the .h file. Simple enough. But this is pretty much done for every single C++ Class you create.
In Java, I create a class which is basically the class definition and implementation all in one.
So why is it not common practice to create class simply as a definition (Interface) and then implement that interface with another class. Here is an example


I hope you get the idea. Maybe my real question should be, why do we do it this way in C++, but I guess I am going to ask, why don't we do it like C++ in Java?
My other question is simply a matter of understanding the need for an interface. I'm still not clear on what purpose they serve.


GenRocket - A Test Data Generation Platform
Davy Kelly
Ranch Hand

Joined: Jan 12, 2004
Posts: 384
My understanding of Interfaces was that you use them so that you can use implement many so that you can have a sort of multi-inheritance thing happening.
knowing that if you need constants, you could declare them in the interface and then use an implementation of that in a class, or define a method which can be implemented within a class.
I guess what I am trying to say is that you can write interfaces for lots of different things, so that you can cut down on duplicate code or keep your coding to a minimum.
But that is just my idea of them, I have hardly used them myself
Davy


How simple does it have to be???
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

Originally posted by Gregg Bolinger:

So why is it not common practice to create class simply as a definition (Interface) and then implement that interface with another class.

It is somewhat common practice; it should be even more common. Think about how EJBs are defined, with the various interfaces; how RMI is done, with its remote interface; how JDBC is done, with its interfaces implemented by each driver.
Every time you can write a method that returns an interface type, or accepts an interface type as an argument, you win. You decrease coupling between different parts of your application, and increase reusability in a very real sense. A significant fraction -- 30% or so -- of the classes I write implement one or more interfaces. For public classes, the fraction is probably over 50%.
Note, though, that the analogy you've made here isn't really perfect. A Java interface is more like a C++ "protocol class" -- a class with only pure virtual methods, and no data members -- than it is like a header file. Remember that the header file contains some implementation details, of necessity -- the amount size, and layout of the class's data.


[Jess in Action][AskingGoodQuestions]
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15286
    
    6

Note, though, that the analogy you've made here isn't really perfect. A Java interface is more like a C++ "protocol class" -- a class with only pure virtual methods, and no data members -- than it is like a header file.
Ok, thanks. That is kind of what I was wondering. If my analogy was accurate or not. That helps.
how JDBC is done, with its interfaces implemented by each driver.
Of the 3 API's you mentioned, this is what I would be most familiar with. Problem is that I am notorious for not worrying about how things are working, as long as they are working. Bad developer I know. I picked up a few bad habits from the get-go that I need to break.
The problem is that once you have the Driver registered, you don't really care how the interface works. So I can't say that your statement helps me, although that is my own fault.
It's kind of like awt's ActionListener interface. I know how to use it. But I don't know how it works.
What I do know is that if I create an interface and then implement that in a class, I am required to override it's public methods. Fine and dandy. But what point does it server me to define that method in an interface. Especially if I am not developing a library, for example.
[ February 23, 2004: Message edited by: Gregg Bolinger ]
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30


What point does it server me to define that method in an interface. Especially if I am not developing a library, for example.
I'll take this last point as a challenge -- my answer can't have anything to do with developing a public API for reuse!
OK, one very popular answer right now would be about testing, and specifically about Mock Objects. If your classes are implementations of interfaces, then it it much easier to test each class in isolation, because during testing their collaborators can be replaced with "mocks" that simulate the behavior you want to occur. If they're not, then there's no way to do this kind of fine-grained testing. Go ask Lasse about this kind of testing if you're unconvinced.
Another answer just has to do with change over time. Imagine that you're writing a banking application, and you've got an Account object, and a Bank object, and a Money object, etc. Your Money object is fairly lightweight at first; let's say it just holds an int containing a number of pennies. You work for a small, local bank.
A little while down the road, the bank branches out. You need Money objects with a larger capacity. You need Money objects that represent foreign currencies. You've got hundreds or thousands of methods that work with Money objects as arguments or return values: what do you do?
Well, you could add all the capabilities to a single Money class. This is a mess, because many of the methods and much of the data won't be needed for many of the Money objects. Most Money objects will be in dollars, and most will be for small amounts, so why should they all carry currency and long-int magnitudes around?
You'd really like to have a hierarchy of Money objects. But even if you do, there's an issue with memory usage. Every object of a Money subclass inherits all the data members of the original Money class, even if a given subclass doesn't need them. This might waste lots of memory in a large application.
No problem -- you make Money into an abstract class, and you create a new RegularMoney subclass, along with the others. But now, you've got to find and fix every occurrence of a Money constructor. Yuk. (I promised I wouldn't mention reuse, but now imagine how much worse this is if you don't own all the code that would have to change!)
Imagine if Money had been an interface in the first placem abd PlainMoney had been the only implementation: adding the new implementations would have been trivial. Nothing changes anywhere. Everything automatically works with the new implementations.
So anyway, there's some answers. There are plenty more!
sever oon
Ranch Hand

Joined: Feb 08, 2004
Posts: 268
To add to what's already been said, interfaces in Java seem to me to be more about explicitly defining exact required behavior than anything else. In that sense, they capture only the design of your project. This is useful insofar as it allows you to separate your design from your implementation.
An example to point up the difference might be useful. You can have more than one top-level class in a single Java source file. The Java specification, though, does not mandate that compilers must allow more than one class per source file. In other words, I could, if I was so inclined, go off and write a compiler that limits the number of top-level classes per source file to one, and still be in compliance with the Java spec. On the other side of the same coin, as a developer you ought not write source files that contain more than one top-level class to ensure that your source would be portable to such compilers (of course, the compiled class files would remain portable regardless).
For this example, think of the Java spec as being like an interface and the compilers being like the code. With interfaces, you specify in your project key points of your design that you require of implementations (the "contract"). Classes may implement the contract of these interfaces--indeed, they may implement more capabilities than called for...even conventional additions (such as the convention that source files may include more than one top-level class--even Sun's reference compilers implement this).
One of the big advantages of OOP can only be realized with the complete abstraction that interfaces provide. Often I'll look at a software project and wonder if it would be useful to refactor an interface from a class or group of classes where a need didn't initially seem to exist. The criteria I use to decide whether an interface is needed is this: is there some part of the contract that these classes implement that should be imposed as part of the specification of this project?
Here's a great article on the idea of stability and abstraction that really nails down this discussion far more eloquently than I ever could. You might find it useful to poke around the published articles at Object Mentor...they address a lot of these kind of issues.
sev
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

Section 7.3 of the JLS very clearly states that a compilation unit can include zero or more class and interface declarations. Section 7.6 describes how, optionally, an implementation can choose to restrict compilation units to contain only one public type among this set of types, and only one type used outside of that compilation unit among the set, and require such a compilation unit to have a particular name in the filesystem. But these requirements are in fact implemented by every compiler I'm aware of.
Your analogy is essentially correct, but I did want to point out that you're basing your analogy on some false statements of fact!
[ February 24, 2004: Message edited by: Ernest Friedman-Hill ]
sever oon
Ranch Hand

Joined: Feb 08, 2004
Posts: 268
Thank you very much for pointing this out, sir! I admit I'm a bit flabbergasted, though, because it's the very first thing on page 4 of Complete Java 2 Certification, Study Guide, 4th Ed. by Heller and Roberts:
All java source files must end with the .java extension. A source file should generally contain, at most, one top-level public class definition; if a public class is present, the class name should match the unextended filename. For example, if a source file contains a public class called RayTraceApplet, then the file must be called RayTraceApplet.java. A source file may contain an unlimited number of non-public class definitions.
NOTE: This is not actually a language requirement, but it is an implementation requirement of many compilers, including the reference compilers from Sun. It is therefore unwise to ignore this convention, because doing so limits the portability of your source files (but not, of course, your compiled files).

Did I just totally misread their meaning here, or did they get it wrong?
Thanks!
sev
sever oon
Ranch Hand

Joined: Feb 08, 2004
Posts: 268
OhHhHhhHHhHHh.
I think I figured it out now. I'll chalk it up to my misreading coupled up with their unnecessarily ambiguous prose. When they say "this" is not actually a language requirement, "this" refers to the statement "a source file should generally contain, at most, one top-level public class definition", not, as I thought, "A source file may contain an unlimited number of non-public class definitions."
Thanks for clearing this up. My initial interpretation struck me as odd when I first read it, but possible. The clouds have parted.
sev
Eddie Vanda
Ranch Hand

Joined: Mar 18, 2003
Posts: 281
Hi Greg,

What I do know is that if I create an interface and then implement that in a class, I am required to override it's public methods. Fine and dandy. But what point does it server me to define that method in an interface. Especially if I am not developing a library, for example.

I am developing a client showing a number of different screens, each a different class, that all require refresh actions. Rather than compiling the specialised refreshing class to call each screen's class's timer handler separately, I get each screen class to register itself with the refresh handler class. The screen classes all implement the same interface for refresh but in completely different ways.
The refresh handler class has a queue of objects of the type named by the interface and knows from the method declaration in the interface what method to call in each screen class.
When I add another screen class I do not need to recompile the refresh handler class. The compiler reminds me if I have not implemented the method.
Not sure if I have explained this too well, but it works for me.
Ed


The nice thing about Standards is that there are so many to choose from!
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15286
    
    6

Originally posted by Eddie Vanda:
Hi Greg,
I am developing a client showing a number of different screens, each a different class, that all require refresh actions. Rather than compiling the specialised refreshing class to call each screen's class's timer handler separately, I get each screen class to register itself with the refresh handler class. The screen classes all implement the same interface for refresh but in completely different ways.
The refresh handler class has a queue of objects of the type named by the interface and knows from the method declaration in the interface what method to call in each screen class.
When I add another screen class I do not need to recompile the refresh handler class. The compiler reminds me if I have not implemented the method.
Not sure if I have explained this too well, but it works for me.
Ed

Yes, Eddie, that was a good explination. I am starting to understand all this a bit better. It probably won't sink in totally until I decide I need to write an interface or 2.
Thanks Ernest and Sever also for sharing.
And now some questions.
But even if you do, there's an issue with memory usage. Every object of a Money subclass inherits all the data members of the original Money class, even if a given subclass doesn't need them. This might waste lots of memory in a large application.
And this is not the case with an interface? Why would a class that implements an interface not inheret all the data members of the interface?
Imagine if Money had been an interface in the first placem abd PlainMoney had been the only implementation: adding the new implementations would have been trivial. Nothing changes anywhere. Everything automatically works with the new implementations.
But what if down the road you realize you have to add a method to the interface, then you would still have to go to all your classes implementing that interface and override that method, right? True, adding OTHER implementations of Money would have been no problem. I assume the answer to this is just "That's programming."
The problem I am having is the simple fact that just because you have an interface, you are still left with coding a lot of the same things over and over.
So to take your example, say you had an interface called Money. Your methods don't really do anything. That's what confuses me. They are just method declarations. I understand somewhat what Eddie said about the interface knowing which method to call to do the refresh each time. I mean, that is similar to a lot of awt.event classes and interfaces.
I am going to do some more reading and possibly write some interface and implementations to try and crack this down. The concept of an Interface seems solid to me. The practicality of it is where I am fuzzy.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15286
    
    6

Eddie,
It would be great if I could take a look at your refresh handler class and a small implementation of it. It might help me understand a bit better.
Greg Reinl
Ranch Hand

Joined: Feb 11, 2003
Posts: 45
Another practicle use for interfaces is to eliminate dependencies between stable components of an application and ones that will change over time (or even at run time).
I am currently working on a web app that uses several legacy, non-JAva back end systems to retrieve information and process transactions. Each has it's unique quirks regarding how to interact with it and even how it views business data and transactions. To isolate the web app from needing to know about the diverse needs of these legacy systems, I designed Java interfaces that define the services expected from any legacy back end system that wants provide services to the web app. It's up to each legacy system to implement those interfaces in Java classes that know how to provide those services in the context of the particular legacy system.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24166
    
  30

Originally posted by Gregg Bolinger:


And this is not the case with an interface? Why would a class that implements an interface not inheret all the data members of the interface?

Well, I suppose the class does inherit all the data members of the interface. It's just that interfaces don't have any member data! Interfaces can include final variables; these are implicitly static, though. Anyway, implementing an interface never adds anythign to the size of an object.

But what if down the road you realize you have to add a method to the interface, then you would still have to go to all your classes implementing that interface and override that method, right? True, adding OTHER implementations of Money would have been no problem. I assume the answer to this is just "That's programming."

This is indeed a problem -- some people have used this as a justification for using abstract base classes instead of interfaces. The only problem there is that having an ABC restricts you to extending that class -- and if you need to extend some other class, then you're out of luck, you can't do both.
This problem has come up in the Java APIs; they dealt with it by writing a subinterface and using "instanceof" internally to check for it. So there's a LayoutManager and LayoutManager2 interface. All the APIs work with LayoutManager objects, and they check to see if you've passed in a LayoutManager2 before using the new features of that interface. Implementing LayoutManager2 is optional.

The problem I am having is the simple fact that just because you have an interface, you are still left with coding a lot of the same things over and over.

Ah, but there's no rule that says you have to write each implementation from scratch; you just want to leave the option open. So that's why, for example, there's a java.awt.event.WindowAdapter class. You can write a WindowListener by extending WindowAdapter and overriding just a single method. There's nothing wrong with supplying a default implementation of an interface. But if you code to the interface, then the default impl is a convenience, not a requirement, which gives you a lot of flexibility. Note that the default implementation can simply throw NotImplementedException for every method, and have no data.

So to take your example, say you had an interface called Money. Your methods don't really do anything.

But you can't make an instance of an interface, only of a class. So for any object you call those methods on, they do do something; they implement that method in some way that's appropriate for that particular class. It's just like polymorphism with a base class, except there isn't necessarily a base class.
sever oon
Ranch Hand

Joined: Feb 08, 2004
Posts: 268
But what if down the road you realize you have to add a method to the interface, then you would still have to go to all your classes implementing that interface and override that method, right?

This is right, and it's as it should be. I think you're looking at an interface as sort of a riff on a class, and that's what's causing the confusion here because an interface serves a different purpose. A class' job is to provide a means of carrying out some kind of behavior, even an abstract class. When you write a class, you're not only saying to the teeming masses what this object does, but you're defining (in an internal, invisible way) *how* it does it. Now when a caller works with that class, they don't need to understand how a method works, only that it takes the specified arguments and returns the documented result. But the fact that the class is performing this task means that an implementation of that behavior is there, it's just not visible. So classes are about providing a caller with a *means* to perform some behavior. Even if you write a pure abstract class with no data and only abstract methods, the fact that it's an abstract class and not an interface means that, down the road, you might decide to crack open that code and add a concrete method later, after lots of other people have already extended it or have code that's using that level of abstraction polymorphically.
An interface is not about that. An interface is about *defining* behaviors for the caller (not the means of performing those behaviors. There's no implementation associated with an interface because its purpose is not to provide a method of performing some task--the purpose of the interface is to provide the agreement on what the exact nature of that behavior is. For example, think about the (factually flawed ) example I used earlier. As a developer, you want to have a working compiler that generates executable programs. But that's not what Sun delivered when they wrote the Java Language Specification...this spec only defines the Java language. If you're looking at this from the standpoint of a developer, you might say, well what use is that? You can't compile HelloWorld with a spec.
But clearly this is useful work because it defines the standard, and once the standard is defined everyone can agree on exactly how a compiler should treat the code. The agreement is in place. So, as a developer you can be assured that IBM's jikes, Sun's reference compiler, and any other Java compiler is living up to the same agreement, and won't start doing things you don't expect like forcing you to use a colon as a statement terminator instead of a semicolon.
This is what an interface does when used properly. It defines a bit of the specification of your project in a way that says, anything that implements this interface lives up to the agreement spelled out by this interface. This allows you to treat any implementing object "polymorphically"--in other words, if you want the functionality specified in that interface, you don't need to know anything about the implementing object (other than it implements that interface).
Take a look at the Collections API. Both LinkedList and ArrayList implement the List interface. This means that, as a developer, if you want to write a piece of code that takes a list and iterates through it and prints out the contents, you can treat both as a list. You don't need to write separate code that does it for an ArrayList, and then does it for a LinkedList...you can just deal with List and not care what kind of list is handed to your method.
The point you bring up, though, about the "drawback" of interfaces is that if I write an interface and 100 people each write 20 classes that implement it, and then I go back and add another method to that interface, there are now 2000 classes that those 100 people have to update. But if the software I've written, on which all these other people's code depends, is good OO software this shouldn't happen too frequently. Sure, it's going to happen sometimes because humans can only be so prescient, but the whole point of interfaces is to nail down in concrete the aspects of your system you do not expect to change, the things you do not want to change over time. You can only write a truly flexible, extensible system by setting up some rules that do not change over time...you can't write a system that can be extensible or flexible in any meaningful way if you don't set up some rules that define solid, stable points. The game with OO is not, "You can extend anything in any direction you want in the future." It is: "If you carefully follow a set of rules I've carefully prescribed, then parts of the system I've set up for extension and flexibility can be extended and flexed." But you do have to set up and identify those parts of the system that are stable, that set the rules, in order for this to work.
Keep in mind, interfaces are easy to misuse and you'll see a lot of violations of these principles if you look for it. Many people will create an interface without considering: do I really want to cast this behavior in stone? But they should...any time you are encapsulating behavior in an interface you are saying that these behaviors, no more and no less, are a corner of the specification for my project that I feel are very unlikely to change as the project evolves. If you make the wrong call, and you put behaviors into an interface that are likely to change, that part of your project is likely going to have to be rewritten wholesale or hacked around at some point in the future (not very OO, writing non-reusable code).
I really think you can solidify your understanding by reading the aforementioned article I linked in my previous response. It's a wonderful piece by Robert Martin that really delves into the heart of how to use interfaces as a powerful tool to create extensible systems. Scroll up and do yourself a favor and read it--I guarantee you'll be scrolling around the Object Mentor list of published articles looking for other stuff by him.
sev
___
Should Square extend Rectangle? Find out why not over at Object Mentor...
[ February 25, 2004: Message edited by: sever oon ]
Eddie Vanda
Ranch Hand

Joined: Mar 18, 2003
Posts: 281
Hi Greg,
This is an application I have been working on for a couple of years and is about 20,000 lines in about 60 files (classes). Extracting this code has been an interesting exercise and indeed I think I solved some problems by re-examining around these areas.

The interface is very simple:

This is the class that handles the screen classes but is not written with any knowledge of them. As far as this class is concerned they are all typed as ActionRefresh.




I've compiled these in different files, but I see no reason why they would not work in one file.
Ed
[ February 25, 2004: Message edited by: Eddie Vanda ]
Eddie Vanda
Ranch Hand

Joined: Mar 18, 2003
Posts: 281
Originally posted by sever oon:


The point you bring up, though, about the "drawback" of interfaces is that if I write an interface and 100 people each write 20 classes that implement it, and then I go back and add another method to that interface, there are now 2000 classes that those 100 people have to update.



My point about this would be that, without the interface, those 100 people would probably miss on at least 10 classes that need to be updated and only 1990 classes would be updated properly. The other 10 will require another 100 programmers another two years to find as part of a debug process. My experience is that off line documentation (or even on line) is never quite in step with the software reality.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Interfaces Question(s)
 
Similar Threads
q on interfaces
simple c++ question
problem in native calling
Problem with Interface return type
how to use c/cpp code in java??