How to properly abstract
Dear all,
I have a rather general question regarding object-oriented programming. It is related to Java, though, because of the peculiarity of the inheritance being limited to one superclass.
Here's the problem:
I have several classes with identical data members, including the respective setters and getters. Now, I thought it would be clever to abstract these common data members and their associated methods to a super class from which these classes would inherit. However, I seem to have hit a catch22, with the following possibilities:
- If I use a normal class as superclass, it would be possible to instantiate this class, which doesn't make sense in my data model.
- If I use an abstract superclass, then it seems like I have to provide implementations of all the methods, which makes the whole thing useless.
- If I use an interface that I implement, I don't have any data members, plus I have to implement the methods.
Am I missing something? Sorry, if this seems like a really stupid question. I am still making the transition from procedural programming to object-orientation.
In addition, how would you go about the following scenario: Instead of one set of classes with common attributes, there are several different subsets, where each subset would inherit from more than one superclass.
For instance I have three superclasses A, B, C, each with a set of attributes (a1, a2, b1, b2, b3, c1, c2). And I have a set of three subclasses e, f, g. Each subclass now should be able to combine these sets of attributes freely, to give me something like, for example:
- e with attributes a1, a2, b1, b2, b3, (inheriting from A and B);
- f with attributes a1, a2, c1, c2 (inheriting from A and C);
- g with attributes a1, a2, b1, b2, b3, c1, c2 (inheriting from A, B, and C);
It seems this isn't possible in Java, but perhaps there's a way around it?
Cheers,
N.
[1974 byte] By [
NetWundia] at [2007-10-2 9:11:09]

> I have several classes with identical data members,
> including the respective setters and getters. Now, I
> thought it would be clever to abstract these common
> data members and their associated methods to a super
> class from which these classes would inherit.
It is really a good idea. You can group common members and methods of all subclasses in the superclass. But remember when you are designing: a class must make sense, I mean, the superclass and its subclasses must have a clear purpose and definition.
> However, I seem to have hit a catch22, with the
> following possibilities:
> - If I use a normal class as superclass, it would be
> possible to instantiate this class, which doesn't
> make sense in my data model.
I don磘 understand which kind of problems you can have instantiating the superclass.
> - If I use an abstract superclass, then it seems like
> I have to provide implementations of all the methods,
> which makes the whole thing useless.
No, you can put implemented methods in abstract classes if you want.
> - If I use an interface that I implement, I don't
> have any data members, plus I have to implement the
> methods.
It seems a bad idea using interfaces in your case. But, anyway, I磎 not understanding very well about your problem. I磀 like to read more details.
> In addition, how would you go about the following
> scenario: Instead of one set of classes with common
> attributes, there are several different subsets,
> where each subset would inherit from more than one
> superclass.
> For instance I have three superclasses A, B, C, each
> with a set of attributes (a1, a2, b1, b2, b3, c1,
> c2). And I have a set of three subclasses e, f, g.
> Each subclass now should be able to combine these
> sets of attributes freely, to give me something like,
> for example:
>
> - e with attributes a1, a2, b1, b2, b3, (inheriting
> from A and B);
> - f with attributes a1, a2, c1, c2 (inheriting from A
> and C);
> - g with attributes a1, a2, b1, b2, b3, c1, c2
> (inheriting from A, B, and C);
Using interfaces, you can do it. But, again, worry about the purpose of your classes and interfaces. This purpose must be clear for you. Java is not like a game, where you can combine pieces to achieve your objective. Your subclass must be the superclass, too, at the same time. Think about the IS A requirement, when you are designing super/sub classes relationship.
Thanks a lot for the quick reply!!
> But remember when you are designing: a
> class must make sense, I mean, the superclass
> and its subclasses must have a clear purpose and
> definition.
Just to clarify: I want to model an XML structure as a Java class hierarchy, using one class per each XML element. Now I found that some of the elements have a number of attributes in common. So, I thought I'd abstract these common attributes by creating classes that hold them.
> > - If I use a normal class as superclass, it would
> be
> > possible to instantiate this class, which doesn't
> > make sense in my data model.
>
> I don磘 understand which kind of problems you can
> have instantiating the superclass.
There won't be any problems per se, but it doesn't seem to make any sense in the data model. If the element modelled by the superclass doesn't "exist in the real world", why should it be possible to instantiate the respective class?
> No, you can put implemented methods in abstract
> classes if you want.
Alright, I though methods in an abstract class were also abstract by definition. I just tested it and I can have implemenations in the abstract class.
> > for example:
> >
> > - e with attributes a1, a2, b1, b2, b3,
> (inheriting
> > from A and B);
> > - f with attributes a1, a2, c1, c2 (inheriting from
> A
> > and C);
> > - g with attributes a1, a2, b1, b2, b3, c1, c2
> > (inheriting from A, B, and C);
>
> Using interfaces, you can do it.
Could you elaborate on how to implement multiple inheritance using interfaces?
> But, again, worry
> about the purpose of your classes and interfaces.
> This purpose must be clear for you. Java is not like
> a game, where you can combine pieces to achieve your
> objective. Your subclass must be the superclass, too,
> at the same time. Think about the IS A requirement,
> when you are designing super/sub classes relationship.
I think that relationship is valid in my case. Each of the XML Elements is an instance of the abstract superclass. I actually worked the other way around, inductively, so to speak: From the common attributes, I designed the superclass holding these attributes and selected an appropriate name for it.
All the best,
N.
> Could you elaborate on how to implement multiple> inheritance using interfaces? class MyClass implements ActionListener, KeyListener, FocusListener, MouseListener, WindowListener, Serializable, SwissArmyKnife
While abstraction is a good idea a lot of the time (especially if most of your code is re-used, but a few methods aren't), in the case of XML, I would not use an element-to-class relationship. (It's often bad form to base your classes on the way information is stored.) Rather, I would go the XML-binding route. (Look up JAXB or JiBX.
> > Could you elaborate on how to implement multiple
> > inheritance using interfaces?
>
> class MyClass implements ActionListener, KeyListener,
> FocusListener, MouseListener, WindowListener,
> Serializable, SwissArmyKnife
Thanks for clarifying. I am aware of the syntax alright, but in this case I thought that any data members that I might want to abstract would be impossible to include in the interface class. I thought an interface is basically a bunch of empty method signatures and nothing else. In my case, I would have to provide something like and adapter class to inherit from, which implements the methods and holds the data members. But then again, what would be the point of having the interface in the first place?
Cheers,
N.
> While abstraction is a good idea a lot of the time
> (especially if most of your code is re-used, but a
> few methods aren't), in the case of XML, I would not
> use an element-to-class relationship. (It's often bad
> form to base your classes on the way information is
> stored.) Rather, I would go the XML-binding route.
> (Look up JAXB or JiBX.
I had a look at some of the automatic output provided by some JAXB implementation, based on the schema of my XML file. It seemed to be rather messy and I figured it would take longer to clean up the auto-generated code than building everything from scratch. I was told that it's possible to use customisation of the JAXB tool, but I couldn't really be bothered digging into this. Do you reckon it would be worth it? What are the principles used by those frameworks for building a class representation of XML documents?
Cheers,
N.
> Thanks for clarifying. I am aware of the syntax
> alright, but in this case I thought that any data
> members that I might want to abstract would be
> impossible to include in the interface class. I
If you mean "attributes" - they're never abstract to begin with. And they should remain hidden, too.
> thought an interface is basically a bunch of empty
> method signatures and nothing else.
Indeed.
> In my case, I
> would have to provide something like and adapter
> class to inherit from, which implements the methods
> and holds the data members. But then again, what
> would be the point of having the interface in the
> first place?
You were asking for multiple inheritence with interfaces. I shoed you how to do it.
Since attributes are supposed to be private anyway: why should any of your classes care about them being present or not? And the point of having interfaces is well-documented at many sources on this site and throughout the net. I won't go into it again.
Frankly, I question that there is a reason for those classes to share a mutual super class. Your design doesn't look sound to me.
> > Thanks for clarifying. I am aware of the syntax
> > alright, but in this case I thought that any data
> > members that I might want to abstract would be
> > impossible to include in the interface class. I
>
> If you mean "attributes" - they're never abstract to
> begin with. And they should remain hidden, too.
Are you referring to XML attributes? If so, that's not what I tried to say. By data members of the class I mean any class attributes that represent the XML element. This could be any number of attributes of the XML element, but also other nested elements (represented as class instances) or vectors with lists of child elements.
I perhaps used the verb "to abstract" incorrectly. By abstracting, I meant to move these data members to the superclass, instead of having them in each of the sub-classes. I did not mean to have them as abstract members, i.e.: "private abstract String myString";
I am not sure what you mean by "hidden".
> > In my case, I
> > would have to provide something like and adapter
> > class to inherit from, which implements the
> methods
> > and holds the data members. But then again, what
> > would be the point of having the interface in the
> > first place?
>
> You were asking for multiple inheritence with
> interfaces. I shoed you how to do it.
Right, I was just wondering where the data members would go in this model of multiple inheritance with interfaces.
>
> Since attributes are supposed to be private anyway:
> why should any of your classes care about them being
> present or not?
I think at this stage a specifc example would be good. Let's say I have the following XML document:
<?xml version="1.0"?>
<aElement version="1.1" dataType="plaintext">
<bELement att2="blub" att4="aaa" />
<cELement att1="bla" att2="blub" att3="foo" />
<cELement att1="blabla" att2="blubblub" att3="foofoo" />
<dELement att2="blub" att4="aaa" />
<eELement att1="bla" att5="bbb" />
</aElement>
There is a root element aElement, which as one each of elements b, d, e and one or more of element c. Element c has 3 attributes, some of which are the same as for the other elements (b: att2, d: att2, e: att1). In addition, the other elements add more attributes (b: att4, d: att4, e: att5).
Now, the way I would represent this in a class hierarchy is as follows:
public class aElement
{
private String version;
private String dataType;
private bElement b;
private vector cElements;
private dElement d;
private eElement e;
}
public class bElement extends att2class
{
private String att4;
}
public class cElement extends att1class, att2class
{
private String att3;
}
public class dElement extends att2class
{
private String att4;
}
public class eElement extends att1class
{
private String att5;
}
public abstract class att1class
{
private String att1;
}
public abstract class att2class
{
private String att2;
}
Getters, setters and constructors are omitted. Attributes that occur in more than one element class are moved to a common superclass from which the subclass will inherit. In the case of cElement you can also see the problem of multiple inheritance. I wonder how this would be solved using interfaces.
> Frankly, I question that there is a reason for those classes to share a > mutual super class. Your design doesn't look sound to me.
Well, I wasn't too sure about it either, which is I why turned to this helpful forum.
Take care,
N.
Of the three options
1. Use a standard DOM.
2. Use a code generator.
3. Write a class manually for each element
option 3 should only be preferred in unusual circumstances. (For example, I adopt it for my current J2ME project because the environment is constrained). If you can't find a code generator which does a sensible job (which I quite understand, having seen the output of some) then write one. It will be worthwhile in the long run.
Inheritance should never be done for 'code reuse'.
Inheritance should never be done for 'data reuse' (presuming such a thing even exists.)
Inheritance should be done when there is a viable "is-a" relationship.
If the only relationship is code reuse then composition should be used.
And if there is data reuse (seperate from code reuse) then a DTO type object (attribute container) can be used.