• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

abstract class

 
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
can an abstract class extend from a concrete class.?
class J{
void x(){
}
}
abstract K extends J{
}
is this correct.
 
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can do it, yes, but not with the example above. The requirement for an abstract class is that at least one method in it be declared abstract. There are no limits on inheritance.
So:

should compile, minus any problems I've created by not testing my own answer.
[ December 03, 2002: Message edited by: Michael Ernest ]
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Actually, that is not a requirement, the compiler will not complain if you label a class with no abstract methods as abstract.
Go ahead and try it.
Bill
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, you see, that's why I avoid testing whenever possible. Not only is it more work, it can get in the way of my preferred answer.
Well, ok, all you have to do is mark a class abstract and it cannot be instantiated. The original example is indeed all you need.
That said, I was looking back at one of the JDC tutorials and happened across this passage:

An abstract class may contain abstract methods, that is, methods with no implementation. In this way, an abstract class can define a complete programming interface, thereby providing its subclasses with the method declarations for all of the methods necessary to implement that programming interface. However, the abstract class can leave some or all of the implementation details of those methods up to its subclasses.

This "makes sense," but it's incorrect. What it should say is "none, some or all of the implementation details..."
Sigh; exams. I'm trying to think of a practical use for this form of an abstract class and I'm at a loss. Anyone?
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
An example from the Java API:
The concrete class java.util.EventObject extends from java.lang.Object.
The abstract class java.awt.AWTEvent is a sub class of java.util.EventObject.
If you drill down a bit further, the class hierarchy can have concrete and abstract in any order as the requirement goes.
java.lang.Object (concrete)
|
+--java.util.EventObject(concrete)
|
+--java.awt.AWTEvent(abstract)
|
+--java.awt.event.ComponentEvent(concrete)
|
+--java.awt.event.InputEvent(abstract)
|
+--java.awt.event.KeyEvent
(concrete)
[ December 04, 2002: Message edited by: Abu Yoosuf ]
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Abu -
Yep, that's an example all right. But what problem does it solve?
I'm playing dumb here just a little because I would like to hear what benefit anyone interprets from this arrangement.
I'm looking for something deeper than "so you can't instantiate AWTEventObject." Yes, of course, but who would do that, or more to the point why do you need to defend against that?
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mike,
Allow me to try a different example, as I am not best placed to explain the api hierarchy from the previous post.
Let's take this example:
We have a Acme framework (copy rights owned by Acme Co.) that allows us to build components (modules) for various applications that are deployed on this framework. For convenience, Acme have provided a concrete component base class with a set of public api methods as the starter and you extend from it to write your components.
The Acme framework runtime environment, when launching a component, will make sure it calls the public api methods provided in the component base class. So, if your component have a particular api method overridden, the framework will use polymorphism to execute it.
So far, it hasn't answered your question. Am I right?
Ok. Now, you come along and want to build some components on this framework. You recognise, your components show some common features that aren't shown by other components.
So, working from bottom up, you will design your components in a way, you capture your common features in the MikeBaseComponent and extend from this class to build your specific components. MikeBaseComponent will obviously extend from Acme framework's component class.
Since you captured the common features in the MikeBaseComponent and it doesn't expose any specific business requirements, naturally you would make it an abstract class. To the point, you should make it an abstract class as its job is to encapsulate the common features of its sub classes and not expose any specific business requirements. In other words, MikeBaseComponent is not to be instantiated. Sub classes of MikeBaseComponent will expose the specific business requirements and hence will be instantiated.
Hope this somewhat helps to explain why we may need to be able to create the class hierarchy as we want in any order.
 
Leverager of our synergies
Posts: 10065
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is an ad-hoc explanation. "We derive an abstract class from a concrete because in Java we can". But this is precisely the problem with OOP -- it allows you to build abstractions with unclear semantics that correspond to nothing is the real word. Let's take a biological taxonomy. I can understand how a concrete bird can be considered belonging to an abstract category of "bird". But an abstract category of, say, passerines, inheriting from a concrete bird - excuse me... This doesn't make sense.
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Abu. This is what I imagined the defense might be. My reluctance to it stands, though, on one basic principle.
If I have a class that should not be instantiated, I can mark it abstract, forcing someone else to subclass it. However, the only think I force anyone to do is to extend my class if no methods are abstract. I haven't defined an an "incomplete interface" which needs to be filled out. All I've really done is make my class, on first sight, rather annoying.
To me this appraoch seems like a precious and murky use of an abstract class modifier. It certainly could be used as you describe, but I don't think the meaning is evident without an explanation. If Java should support a way of declaring a concrete class off-limits, is this the way to do it?
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Mike,
I hear what you are saying. Allow me to expand on my prev example. Let's say, all of your subclasses (inherited from MikeBaseClass) rely on querying the database for exposing their respective functionality.
We do not want the duplicate code lying around in all of your sub components. So the common stuff that require to connect to the database/rendering the output/etc.. can be pushed up the chain to MikeBaseComponent.
This gives you much cleaner solution, maintaining in just one place.

Now the sub class can provide its own impl of the query. This is probably just one instance of many number of places where this [concrete [abstract][concrete][abstract][concrete]concrete] class hierarchy can be used.
[ December 10, 2002: Message edited by: Abu Yoosuf ]
[ December 10, 2002: Message edited by: Abu Yoosuf ]
[ December 10, 2002: Message edited by: Abu Yoosuf ]
 
Mapraputa Is
Leverager of our synergies
Posts: 10065
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I did some self-analysis to figure out why mixing abstract and concrete classes doesn’t feel right and here are the results…
It is said the semantics of inheritance is “IS A”. This is different from another way of code reuse – function call. Function calls do not have any additional semantics. When your function calls another function, say, sin(), it doesn’t mean anything besides that your function uses sin() function. When class BBB extends class AAA, we can say that bbb is a thing of type AAA.
Now what it means to declare a class as abstract? The only answer I can think about is that we do not want anybody to instantiate this class for conceptual reasons. Otherwise, technically it is enough to provide a class with only private constructors, there is no need for a dedicated language construct. Otherwise, there are no reasons to prohibit instantiation of a class that doesn’t have abstract methods. “Abstract” keywords is here to make a point.
Inheritance forms hierarchy of types, or, in other words, hierarchy of abstractions.
Example:
Shape
|
|--- Circle
|
|---- Square
|
+---…
How can we instantiate a shape? We cannot. There is no enough information. We can instantiate a circle or a square, but not “a shape”. In this case we would make the Shape class abstract.
Now, there is such thing as levels of hierarchy. In other words, there is a direction, up to bottom, and this direction is that the level of abstractness decreases. Each new type means a concept less abstract than the previous one. Finally, we will arrive at something we can actually instantiate, and this will be a concrete class.
Now to add another level of hierarchy as an abstract class means to change the direction to the opposite – from concrete to more abstract. This would serve to no other goal but to introduce confusion.
Does all this make sense?
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
With all due respect, I disagree. The essence of an "IS-A" semantic is, the characteristics of a parent are passed on to the child, i.e. super class to sub class. IMHO, the function/method calls are nothing but programmatic mapping of those characteristics of the classes.
For example, let's take the characteristic of consumption for Animals,
consume()
{
<>eat();
swallow();
<>secreteEnzyme();
<>digest();
<>excrete();
}
Now, if this is considered to be some additional functional calls that are used by consume(), and besides that they do not have any semantic, then IMHO we have misinterpreted the "IS-A" semantic. In order to say Mammal is a thing of type Animal, we need to be able encapsulate the characteristic of consumption in Animal. At the same time, Mammal should be able to expose its specific characteristic of digest() that differs from Reptile's digest().
As for the Shape example, all I know is, Yourdon brothers' are making a living out of it ;-)
 
Mapraputa Is
Leverager of our synergies
Posts: 10065
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We do not want the duplicate code lying around in all of your sub components. So the common stuff that require to connect to the database/rendering the output/etc.. can be pushed up the chain to MikeBaseComponent.
Abu, what bother me, you do not even say what MikeBaseComponent class is to represent!
Inheritance, the mechanism of code reuse, has a number of disadvantages, see Joshua Bloch's "Effective Java" for more explanations. If all you want is to use "querying the database" functionality, there is no need to extend, you can simple call this class’ methods.
 
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's Interesting the Discussion ..
but first let's see the facts.
if you declare a class Abstract it only means to TAG such class Abstract so it's no posible to make an instance of it.

nevertheless where it comes from (all classes come from somewere remember the Object class is parent of all classes)
the usage of an abstract class depends on what you are trying to inforce..
declaring a class abstract just forces anyone that would like to use it; to Extend such class and not ot use directly..

besides declaring a class abstract you could optionaly declare Abstract methods.
so such methods MUST be implemented.

so you got 2 sentences an abstract class. and abstract methods on it ..
so depends on what are you objectives.
abstract would be just an abstraction or in other word just an idea wich you leave to other programers to extend..
in OO Programming you use in each class 2 diferent definitions.
1.- and interface (i would use a struct to use such class)
2.- and an implementation (in the case of concrete classes)
so abstract classes are in the middle of such definitions they are an interface and a partially implemented class.
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

We do not want the duplicate code lying around in all of your sub components. So the common stuff that require to connect to the database/rendering the output/etc.. can be pushed up the chain to MikeBaseComponent.


Ok. Let me rephrase it in "OO" terminology.
+ The Children inherit the characteristics of the Parent -i.e. Parent passes on its characteristics to the Children. Now, how do we program this concept in our chosen language?
Take your example:
abstract class Shape
{
abstract double getArea();
}
class Square
{
double getArea()
{
return ...;
}
}
class Circle
{
double getArea()
{
return ...;
}
}
class Rectangle
{
doubl getArea()
{
return ...;
}
}
and so on. For every child of Shape there will be some specific implementation of getArea().
Now, what we have here in the Parent class Shape is, a characteristic called area. Parent says to anyone who cares about it, "look, I have a characteristic called area. I know for sure my children will have this characteristic, but at this moment in time, I am not sure how that characteristic is going to be mutated by the time my child is born. So, I am going to leave it for them to sort it out."
Now, child is about to be born. It looks up and sees, hmm... Parent is saying to sort myself out. Ok. I sort myself out before I go out to the world.
This is the rationale behind the

MikeBaseComponent represents the common characteristics of its sub classes and it maintains the "IS-A" semantic with the AcmeFramework's Component class. So you can see the direction is still one way.


If all you want is to use "querying the database" functionality, there is no need to extend, you can simple call this class’ methods.


If you notice, I mentioned that this is a specific example of numerous other occurrences where abstract/concrete can be useful to the design of a solution.
IMHO, this arrangement is a benefit to the overall design of a business solution. If we can map all the business requirements to the classic Shape/Circle/Square example (OO's version helloworld example), the mega buck earners with the tag 'architects' would be queuing infront of unemployment benefit offices.
Thanks for the recommendation of Joshua's book.
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mapraputa Is:
Now to add another level of hierarchy as an abstract class means to change the direction to the opposite – from concrete to more abstract. This would serve to no other goal but to introduce confusion.
Does all this make sense?


Going back to the java event api.
java.lang.Object (concrete)
|
+--java.util.EventObject (concrete)
|
+--java.awt.AWTEvent (abstract)
|
+--java.awt.event.ComponentEvent (concrete)
|
+--java.awt.event.InputEvent (abstract)
|
+--java.awt.event.KeyEvent (concrete)
The direction isn't lost.
The reason for it is, from java.lang.Object to java.awt.event.KeyEvent the relationship is a Specialization . On the other hand, from java.awt.event.KeyEvent to java.lang.Object the relationship is Generalization .
[CODE]
java.lang.Object (concrete)
^ GENERALIZATION
|
|

SPECIALIZATION
|
|
V
+--java.awt.event.KeyEvent (concrete)

Now, if you take an arbitrary relationship from this class hierarchy, say, AWTEvent to InputEvent, the direction is only one way.
[ December 11, 2002: Message edited by: Abu Yoosuf ]
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm in the middle of Sun ONE stuff this week so I haven't been able to spend as much time in this thread as I'd like. But my point is simple anyway.
Yusef really isn't defending the initial question of marking a concrete class abstract so that it can't be instantiated, a practice I still think has more potential for confusion than elegance.
What Yusef is defending, judging by his examples, is a use of abstract I would have agreed with all along: to require additional behavior in a child class which is then tied together in the parent. Here's a very wispy example of what I mean:

This is a simple suggestion of a Template pattern, in which a parent class controls flow or order of execution but leaves the details of implementation to a subclass.
We can pretend that TemplateProcess is "less abstract," i.e., only requires the subclass to implement one method. In any event, the parent class is still abstract; the parent of that might in fact have been concrete, but in extending the functionality of that parent we've also added requirements.
This approach seems fine to me, if a bit of a mind-bender at first sight. I don't care for it in the same way that I don't care for anonymous inner classes: when the convenience of the programmer takes precedence of the readability of the resulting code, I think we've ignored the costs of full development cycle(i.e., time lost reading obscure code) for the sake of appeasing some uber-stressed programmers. But both have their uses and simply require that maintenance programmers will understand these forms.
 
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here's an example from the API of an abstract class with no abstract methods:
FocusAdapter (in fact all the Adapter classes).
Why?
The idea behind the Adapter classes is so that when you want to be a Listener, you don't have to supply implementations for all the methods in the Listener Interface.
FocusListener has two methods; focusLost() and focusGained(). If you implement the listener, then you must supply implementations for both methods even if you are only interested in foucsGained().
The FocusAdapter implements both methods but they are empty. So you can extend the Adapter and supply the implementation for the method you want. The Adapter has no abstract methods because that would defeat the whole purpose of the Adapter. The Adapter is abstract because there is no reason why you would ever want to instantiate a class with nothing but empty methods. By making it abstract, the designers are clearly pointing out that this class is meant to be extended, not instantiated.
[ December 11, 2002: Message edited by: Thomas Paul ]
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sheriffs,
I am currently driving a car without a Sun certified licence.
I was told that I can come to your ranch and learn to drive before taking the test. I was also told that it is perfectly legal to get into any parked car and go for test drives. If I make
mistakes along the road, there are other certified drivers and sheriffs to help me out. Here I am trying to test drive a car. You two sheriffs are pathetic. You two are taking turn to stop me every half a yard. Gosh! Now a third one joins in.
[ December 12, 2002: Message edited by: Abu Yoosuf ]
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Michael Ernest:
Yusef really isn't defending the initial question of marking a concrete class abstract so that it can't be instantiated, a practice I still think has more potential for confusion than elegance.


Sorry Sheriff,
You're a bit late to catch up with things. We are on a detour. We are no longer heading towards the initial destination.
I was trying to answer the questions that were raised. Yes, I agree. My recent posts for this thread aren't answering the initial question.
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mapraputa Is:
I did some self-analysis to figure out why mixing abstract and concrete classes doesn’t feel right and here are the results…

Imagine the situation where you have useful non-abstract class A. Someone comes up with the clever idea that A can be enhanced with some new functionality. This new functionality can actually be implemented in 3 different ways. So they extend A with an abstract class B which provides the method signatures for the new functionality. Then they provide C, D, and E which implement the new functionality.
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Abu - Map and I are sheriffs, but we're also fellow subscribers to this board. Responding to what ideas that others post is how a bulletin board works.
Just because we have administrative privileges doesn't mean we're stopping you when we respond to your ideas. If you feel we've cut off or ignored an important point, feel free to re-state it.
Do you consider us pathetic because we're challenging the concepts you presented?
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Thomas Paul:
Imagine the situation where you have useful non-abstract class A. Someone comes up with the clever idea that A can be enhanced with some new functionality. This new functionality can actually be implemented in 3 different ways. So they extend A with an abstract class B which provides the method signatures for the new functionality. Then they provide C, D, and E which implement the new functionality.


Why wouldn't you just create an interface with the new functionality? A default implementation class C, composed of class A and the implemented interface, would convey the same thing in a straightforward way.
D & E could then extend and override C behavior. If they're truly different implementations, capturing their commonalities in an interface rather than a parent class I think would make more sense.
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Michael Ernest:

Why wouldn't you just create an interface with the new functionality? A default implementation class C, composed of class A and the implemented interface, would convey the same thing in a straightforward way.
D & E could then extend and override C behavior. If they're truly different implementations, capturing their commonalities in an interface rather than a parent class I think would make more sense.



What if B is also providing some base functionality shared by C, D, and E?
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike,
Come on, lighten up! I was just kidding. Honestly, I am learning a lot from this site.
Anyway,

Now, if we are to provide an interface instead of the abstract middle layer class B shown in the above code snippet:

In this approach, we have lost the common characteristic of commonStuffToMyChildren that suppose to be in the middle layer.
Another thing with this approach is, there is no stopping of jackin in the interface B to some other remotely related class hierarchy [to cut corners... believe me, in my very short life as a programmer, I have seen this happening].
Please note, I am not slating the concept of interface. All I am saying is, it has its own pitfalls.

in some other place,
B accessingR = new R();
B accessingC = new C();
IMHO, this leads to more trouble.
[ December 11, 2002: Message edited by: Michael Ernest ]
 
Thomas Paul
mister krabs
Posts: 13974
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The problem is that it implies that you could implement the interface WITHOUT extending the base class that the interface is designed to add to. It removes all links between the interface and class A. On occasion this may be a good design but on other occasions this may be a very bad design as in Abu's example.
Making B an abstract class that extends A locks the relationship in place.
[ December 11, 2002: Message edited by: Thomas Paul ]
 
Michael Ernest
High Plains Drifter
Posts: 7289
Netbeans IDE VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Abu Yoosuf:
Mike,
Come on, lighten up! I was just kidding. Honestly, I am learning a lot from this site.


Shows you how tired I am this week -- my mistake.
 
Abu Yoosuf
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My mistake too. I should have qualified my statements with a smiley or something to make it clear that I wasn't serious.
Apologies for that.
Nice talkin to you guys. Take care!
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
pertaining to the interface vs. abstract class part of the discussion, here is a good link
http://developer.java.sun.com/developer/JDCTechTips/2001/tt1106.html#tip2
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic