• 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 classes and inhereitance

 
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,
I have to questions
1) Is it considered good style, bad style, or just personal preference to have an Abstract class that inherits from a concrete class?
public MyConcreteClass {
...
}
public Abstract MyAbstractBaseClass extends MyConcreteClass {
...
}
2) Is it considered good style, bad style, or just personal preference to have an Abstract class that inherits from another abstract class?
public Abstract org.trusted.opensource.java.pkg.AnAbstractClass {
...
}
public Abstract MyAbstractBaseClass extends AnAbstractClass {
...
}

Thanks,
Joshua
 
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Abstract class extending from a concrete class is against OOPS principles, IMO. The point here is "when do we go for an abstraction". Abstraction is the generalization we derive out of things and the concrete behaviour will be consolidating this generalization in their own way. Hence Abstraction-->Concrete is the natural order of inheritance. We can do whatever we want as long as the compiler doesn't complain about it, but it should also justify the rationale behind our approach.
 
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well Object is a concrete class so by definition all abstract classes extend a concrete class.
Having an abstract class extend another abstract class is also fine.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't think this question can be answered universally.
The main purpose of an abstract class is to defer implementation of specific details while providing common code - for example when using the Template Method pattern.
It would probably perplex me somewhat if an abstract class inherited from a concrete one, but I wouldn't rule it out totally.
Do you have a specific example in mind?
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Object is definitely a concrete class, but with the intent to provide all the Java classes with some default functionality like cloning, etc. Its definitely not an abstraction in the conceptual sense, IMO. If we are modelling some classes for solving a problem in a particular domain, we tend to look at abstraction w.r.t players (classes) in that domain.
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Object is definitely a concrete class, but with the intent to provide all the Java classes with some default functionality like cloning, etc.


Little correction - Object is definitely an abstract class in Java........ Serious typo. Sorry.
I guess this abstraction helps the programming language a lot, like for example, adding different elements to a Vector (by upcasting them to Object), etc. But in the conceptual sense, this is not strictly an abstraction, but for the ease of implementation of things.
 
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 Jayadev Pulaparty:

Little correction - Object is definitely an abstract class in Java........ Serious typo. Sorry.


You were right the first time. Object is not an abstract class. You can prove this by doing this:
Object o = new Object();
Works just fine. In fact, these Objects make nice semaphores to use for synchronized blocks of code.
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Uh! I've been totally messed this up . Looked at the Java API now. When i took the SCJP exam, i always looked at Object as an abstract class which is the superclass of every Java class. Some late breaking news for me -
Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
having a public constructor -- public Object()
This definitely means that we can instantiate an Object class object. But why so? Can someone give an example wherein we need such a thing like instantiating an Object?
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thomas,

In fact, these Objects make nice semaphores to use for synchronized blocks of code.


Can you please elaborate on this. Just curious of how the Objects are used.
Thanks.
 
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
Suppose you have several blocks of code in different methods in your class that you want to synchronize but not with each other. In other words, if you are in block1, I don't want anyone else in block1 but I don't care about someone else going into block2. If I synchronize on (this) the two blocks will be co-synchronized. A thread in one blocks the other. So instead I create two sempahore objects and use them. For example.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jayadev Pulaparty:
If we are modelling some classes for solving a problem in a particular domain, we tend to look at abstraction w.r.t players (classes) in that domain.


I don't agree. When I am designing, I am looking for abstractions that serve the implementation of the solution. I don't care much wether those abstractions also exist in the problem domain.
And if such an abstraction would benefit from inheriting existing functionality from an already existing concrete class, it wouldn't trouble me to do so.
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I don't agree. When I am designing, I am looking for abstractions that serve the implementation of the solution. I don't care much wether those abstractions also exist in the problem domain.


I think it depends on "where" we are trying to look for abstractions. The abstractions that get exposed to the client side should reflect the players in the domain to make things more intuitive, IMO. The implementation side (for example, the algorithm side of a strategy pattern) can be like what you said.
 
joshua van-breukelen
Greenhorn
Posts: 22
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Whew! Ok. First of all, thank you to everyone your their input.
Now Ilja, you had requested a more specific example.
I am in the design phase of an application that I am building using the Struts framework.
My Actions will have a certain amount of duplicate functionality and “org.apache.struts.action.Action” is a concrete class.
If I make a base class;
package this.will.probably.lead.to.an.endless.debate;
import org.apache.struts.action.Action;
public abstract class MyBrilliantAbstractAction extends Action {

}
and then have several Action classes:
public class Action1 extends MyBrilliantAbstractAction {

}
public class Action2 extends MyBrilliantAbstractAction {

}
public class Action3 extends MyBrilliantAbstractAction {

}

I can centralize/create a layer of abstraction (oh, boy I know someone out there is going to take me to task on my semantics) for the overlapping functionality.

Part Deux, the second – With regards to abstract inheriting from abstract:
Several Form classes in my application will share common properties and org.apache.struts.action.ActionForm is abstract. Therefore:

package AGAIN.this.will.probably.lead.to.an.endless.debate;
import org.apache.struts.action.ActionForm;
public abstract class MyHumbleAbstractActionForm extends ActionForm {

}
and then have several ActionForm classes:
public class Action1 extends MyHumbleAbstractActionForm {

}
public class Action2 extends MyHumbleAbstractActionForm {

}
public class Action3 extends MyHumbleAbstractActionForm {

}
Based on Don’s comments earlier today:

Well Object is a concrete class so by definition all abstract classes extend a concrete class. Having an abstract class extend another abstract class is also fine.


I’m pretty happy with the design. I’m already 2/3 the way through the UML. If I “hear”/read a post that is really earth shattering and inspired I’ll change it…I have an open mind.
Oh, and Ilja, you never answered my request for a Hefeweizen…
Aber trotzdem, viel Spass,
Joshua
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by joshua van-breukelen:
Now Ilja, you had requested a more specific example.


Thanks for the elaboration! I think this in an excellent example of when it makes sense to let an abstract class inherit from a concrete/other abstract one - when you need to extend a class from framework in several different ways and want to reuse some common code.
We needed to take an even closer look at wether it would make sense to extract the common code into a different class and use delegation instead of inheritance. But if the common code is strongly bound to the Action/Form class, it probably wouldn't be worth the hassle. You are certainly just doing fine - and you could still extract the extra class later on when it becomes obvious that you need to.


Oh, and Ilja, you never answered my request for a Hefeweizen…
Aber trotzdem, viel Spass,
Joshua


Uh, Hefeweizen? Hilf mir auf die Spr�nge...
Gru�, Ilja
[ March 18, 2003: Message edited by: Ilja Preuss ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ilja Preuss:
Uh, Hefeweizen? Hilf mir auf die Spr�nge...


Got it! https://coderanch.com/t/98111/patterns/Which-design-UML-tool
Just didn't understand at that time what you were driving at...
When you are in Karlsruhe or neighborhood, we could certainly meet for a Hefeweizen - though, as a "Wahl-Badener", I am more into wine...
Gru�, Ilja
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Does your abstract class have any abstract methods in it ?
This is a related question on good style that I have come up against. Is it good style to have an abstract class without any abstract methods ?
The only reason I can think of doing this is to make a class non-instantiable.
In this case you can also (and the choice I normally go for as I think it is bad style to have an abstract class without abstract methods) is to give the class a protected constructor. The drawback with this choice is that the class can be instantiated from within the package.
So neither of these choices seem ideal to me. I realise I'm splitting hairs hairs here but does anyone have anyone have opinions on this ?
thanks,
T.
[ March 18, 2003: Message edited by: Don Kiddick ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Don Kiddick:
This is a related question on good style that I have come up against. Is it good style to have an abstract class without any abstract methods ?


Why would it not?


The only reason I can think of doing this is to make a class non-instantiable.


In fact, that *is* the semantic of an abstract class - a class that cannot be instantiated.


In this case you can also (and the choice I normally go for as I think it is bad style to have an abstract class without abstract methods) is to give the class a protected constructor. The drawback with this choice is that the class can be instantiated from within the package.


Even a class with a private constructor can be instantiated. Therefore, if you wanted to communicate that a class shouldn't be instantiated, it would be a reasonable choice to make it abstract, in my opinion.


So neither of these choices seem ideal to me. I realise I'm splitting hairs hairs here but does anyone have anyone have opinions on this ?


Yes. I really wonder why you think making it abstract wouldn't be ideal.
Can you give an example of a class which shouldn't be instantiated but also shouldn't be declared abstract?
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ilja. After reading what you said and this :
http://java.sun.com/docs/books/tutorial/java/javaOO/abstract.html
I agree ! You learn something new everyday !
thanks,
T.
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Don Kiddick:
You learn something new everyday !


As my mother likes to say:

Man wird alt wie eine Kuh
und lernt immer noch dazu!


(Rough translation: Even getting old like a cow, you still learn something new anyhow!)


thanks


You're welcome!
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As has been noted, abstract should be used when the class represents an abstract concept and it doesn't make sense to have instances of it. However, non-instantiability should be a consequence of, not the main factor for, making a class abstract. Using abstract primarily to prevent instantiation by other classes should be suspect: consider making constructors private or protected instead.
Joshua, I have done the same thing in my current Struts project, creating an abstract Action class that provides the Template for processing any incoming requests. Subclasses have the option of implementing several methods called in the template. In some cases, you want to define default behavior so you can create a Base class.
Sample Hierarchy:
AbstractAction - provides template in perform or execute and abstract methods. Tag the perform or execute method final to ensure integrity of the template method in subclasses.
BaseAction (extends AbstractAction) - provides default (commonly just do-nothing)implementations of the abstract methods.
ConcreteAction (extends BaseAction) - this is the level at which you create your own actions and provide application-specific implementations of the abstract methods.
Note that earlier versions of Struts had a similar hierarchy but some of them were deprecated/refactored as the framework evolved.
[ March 18, 2003: Message edited by: Junilu Lacar ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Junilu Lacar:
As has been noted, abstract should be used when the class represents an abstract concept and it doesn't make sense to have instances of it. However, non-instantiability should be a consequence of, not the main factor for, making a class abstract.


Please provide an example of a class for which it wouldn't make sense to have instances of it, but which you wouldn't think of as an "abstract concept".

Using abstract primarily to prevent instantiation by other classes should be suspect.


Why?

consider making constructors private or protected instead.


Mhh, if you make the constructor protected, other classes *can* instantiate it. If you make it private, even subclasses can't be instantiated...
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It all goes back to making the code convey its intentions.
When you declare a class as abstract, you signify a design intent: normally, that this class provides a "general contract" for use and that subclasses are expected to "enforce" or "adhere to" the contract. This should be the primary reason for declaring a class as abstract. The fact that you can't instantiate it comes as a consequence of that primary design intent.
Take the java.lang.Math class for instance. It doesn't really represent any OO "concept", but it still doesn't make sense to instantiate it because it only has static methods. Yet, it wasn't appropriate to make it an abstract class to prevent other classes from instantiating it. Instead, the constructor was made private. Within the Math class itself, no attempt is made to use the private constructor at all.
So, I always question the true intent before I make something abstract. If the main intent is to prevent instantiation by other classes, then I would first consider the other approaches to see if they make more sense.
Another example I can think of is the typesafe-enum pattern. The common implementation of this pattern usually has the constructor declared as private to prevent instantiation by other classes. Yet the typesafe-enum is not really an "abstract" concept. Of course, you can't declare the class as abstract because you still need to invoke the constructor within the class for each constant value.
[ March 18, 2003: Message edited by: Junilu Lacar ]
 
Ilja Preuss
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Junilu Lacar:
When you declare a class as abstract, you signify a design intent: normally, that this class provides a "general contract" for use and that subclasses are expected to "enforce" or "adhere to" the contract.


That's not only true for abstract classes, but for subclassing in general. It's the Liskov Substitution Principle in action.
As long as we are speaking about classes which aren't meant to be subclassed, we are on the same page.
I somehow focussed on classes which meant to be subclassed, as that is what in my impression the original question was about...
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

That's not only true for abstract classes, but for subclassing in general. It's the Liskov Substitution Principle in action.

Agreed. When you use abstract though it is (hopefully) more likely to remind a programmer writing subclasses (including yourself) that you want them to remember the LSP.

...we are on the same page.

We almost always are although we sometimes manage to miss seeing eye-to-eye.
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So for a class that is never meant to be instantiated (generally utility classes e.g. Math, Collections, System) or for a class that is only supposed to be instantiated from within the class (as in the Singleton and TypeSafeEnumeration pattern) - make the constructor private.
For a class that does not make any sense to instantiate but you want be able to sublcass, make the class abstract.
Well that's how I see it anyway !
T.
 
World domination requires a hollowed out volcano with good submarine access. Tiny ads are optional.
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic