This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
The advantage isn't evident in the code you've supplied, but in a more complete example, say, you would also implement a Circle class extending Shape, and maybe a Triangle class, etc.
All of these shapes are easy to create with the appropriate info. You give the diameter of the circle, and you can draw it. You give the side length of a square. Or the 3 side lengths of a triangle.
But how about shape. How do you construct a "Shape"? What does a "Shape" look like? What information should you be able to find out about your "Shape"? What are the practical uses of s "Shape"?
A Shape is an abstract concept that we use to categorize useful concepts, but on its own, it really has no specific meaning. The importance of declaring the class abstract is that, otherwise, an implicit constructor can be called, like so:
Shape myShape = new Shape();
And now you have an instance of shape that is totally meaningless, not just because you don't know what the shape is, but you can't do anything effective with it.
Well, then you could argue that nobody in their right mind would ever try to execute that code anyway, because it's useless, so what's the deal? Well, the deal is this: Not only is it meaningless, but it has no defined semantics for its abstract methods. So not only is it useless, but now the run time environment (or the compiler) must figure out what do do with those methods should the possibility ever occur, and that's not an easy problem to solve.
Next question, of course, is why should the methods be abstract. It's hard for the run-time environment or compiler to decide the semantics of those methods for the "Shape" class, but not so much for the programmer who writes the Shape class. The answer: it's more convenient and sensible to prevent the situation from ever occurring than to design for the case when it could, if the class is never intended to be used in that manner. It's like designing a car to cook dinner. It just doesn't make sense and was never intended for that use. So why would we ever design a class that is capable of doing things it was never intended to do, just in case somebody might accidentally request for it to do.
The other important reason that we name a class as abstract is as a marker to other designers. When somebody looks at a class and sees that it is abstract, they know for sure that it isn't intended to be used directly, and doesn't represent a concrete object, but rather, is a placeholder for an object that can be classified by that class. It makes code more readable and understandable.
Joined: Jan 10, 2007
Thank you Adam that was helpful.
So what about interface, its seems very similar to abstract
In Java there is very little difference between an abstract class with no concrete methods, and an interface. The dogmatic differences which I'm sure you've encountered in a number of sources, are that an implementing class may only inherit concrete behavior (read: extends) from a single base class, but it may implement an arbitrary number of interfaces.
However an abstract class does not have to contain all (or any) abstract methods. It can contain concrete implementations of instance methods, and it can contain static methods.
Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Note that an abstract class can help get you part way (sometimes a long ways) towards implementating an interface.
For example, consider the abstract class AbstractList, which implements the interface List. As the API explains, "This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface..."
Indeed, the List interface declares 25 methods, and AbstractList implements most of these, which saves a lot of work. For example, "To implement an unmodifiable list, the programmer needs only to extend this class and provide implementations for the get(int index) and size() methods."
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
Joined: Jul 17, 2006
Originally posted by umut uzumcu: So what about interface, its seems very similar to abstract
How very true. On a language specification level, there are two important differences between interfaces and abstract classes:
1) An interface CANNOT contain ANY implementation at all, whereas an abstract class may partially or totally implement any or all of its methods. For example, in your shape class, you could, if you chose, add a UID (unique identifier) field that discriminates between all shapes of any class. You would probably want to implement that method in the Shape class (and make it final) in order to prevent the possibility of a subclass producing shapes with the same IDs, making them no longer unique. This is something you could NOT do with an interface, because it is an implementation detail.
2) In java, a class can extend only ONE class (abstract or not). However, it can implement any number of interfaces. This prevents clashes of implementation of methods with the same name / parameters / return types. For example, say, for some strange reason, you decided you wanted to extend both JButton, and StringBuffer (I can't think why you would, but just humor me). They both have an implementation for toString(). Which one do you use. However, if you implement two interfaces that define the same method, the contract for implementing an interface requires that you supply your own implementation for all methods ANYWAY, so you don't get this sort of clashing.
Therefore, interfaces are the only way you can "simulate" multiple inheritance (I'm not interested in getting into a theoretical argument on whether this truly is MI, but this is, to some degree, support for MI of interfaces, at least).
Now, if you go further and look at object oriented programming ideals and concepts (stepping away from java for a minute), you begin to understand the value of the Interface in a different light.
One of the most important concepts of OO programming is the idea of encapsulating business logic and hiding it behind a public interface. It means that I can write an interface called TransportationVessel with a method travelTo(String destination), and it doesn't matter if that Transportation vessel drives to the destination, sails to the destination, flies to the destination, digs to the destination, runs to the destination, canoes to the destination, or teleports to the destination, so long as it "travels" to the destination. The interface (small 'i') provides the clients ALL of the methods required to do what needs to be done, and HIDES ALL of the methods NOT required for the client to request the task to be done. For example, if the TransportationVessel is a car, there are things like starting the ignition, putting the transmission into gear, releasing the clutch, flooring the accelerator, turning the steering wheel, ect. that need to happen for that car to drive. But just as a Taxi driver will take care of all of that for you, the public interface of TransportationVessel allows you to just say where you are going, and it gets you there.
So, now we come to the value of the java Interface (capital 'I'). The java Interface is designed to supply ONLY public methods and static final public fields. The intended use of the Interface is to provide EXACTLY the methods required to get request that the job get done, and NOTHING ELSE. Then, the contract for implementing an Interface is that every implementing class MUST implement all of the Interface's methods. Why? Because, as I already said, all of the methods are always required to get the job done correctly. The end result is, I can call the same methods in the same order on ANY object that implements an interface, and I expect the same end result (possibly with different side effects).
For example, it doesn't matter whether the transportation vessel is a boat, car, bus, train, airplane, or the Starship Enterprise. I call travelTo("Hawaii"), and I expect, when everything is said and done, that I get to Hawaii. I expect that there is NO TransportationVessel on which I can call travelTo("Hawaii") and have it do nothing, because that transportation vessel is not meant to use the travelTo method, or because I need to call some other method FIRST. It is possible to write classes like that, but that theoretically defeats the purpose of implementing an interface, and is REALLY BAD programming practice.
So, if you use interfaces in the way they are intended, they 1) help you enforce the implementation of the contract specified when the Interface was written, 2) document your intent to your clients that EVERYTHING they ever want to do with these classes can be done using the methods specified by the interface, and 3) prevent extraneous implementation code from being added to ALL subclasses, regardless of whether they actually make use of that code.
In my own personal opinion, this final reason, about the intended Purpose of Interfaces is far more important than looking at the effective language semantic differences in what the compiler will allow you to do with interfaces and abstract classes. An Interface should ALWAYS be used to specify the contract that all implementing classes must implement, and any client can rely upon, and should always be used to define a type, which specifies the END RESULT of an object's behavior.
An abstract class, on the other hand, shouldn't really be used for that, but should only be used to make sure that a certain common behavior is always performed identically by any and all subclasses of that class.
Note, however, that java allows you to do both, to varying degrees, with both ideas. It's just a really bad idea to do so -- it may confuse others who attempt to decipher your code, and it usually means that you have a poorly encapsulated design.
Joined: Jan 10, 2007
So for example There is two Account types(Student and Platinum) which they both can use the methods Withdraw and Deposit. But the Student account cant Overdraft. And they both Interest paying type of accounts.
In that situation is my code right?
[ January 19, 2007: Message edited by: umut uzumcu ]
Originally posted by umut uzumcu: So for example There is two Account types(Student and Platinum) which they both can use the methods Withdraw and Deposit. But the Student account cant Overdraft...
If a class extends an abstract class, then it must either provide implementation for all abstract methods, or be declared abstract itself. So in your example, StudentAccount would need to be declared abstract because it doesn't implement the abstract overdraft method.
If overdraft is something that will not be implemented in all subtypes, then it might not belong in the interface. Instead, it might be something implemented in the method body of PlatinumAccount's withdrawal method, but not in the method body of StudentAccount's withdrawal method. Maybe something like...
[ January 20, 2007: Message edited by: marc weber ]