Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / September 2005

Tip: Looking for answers? Try searching our database.

Reaching a indirect superclass

Thread view: 
SL - 10 Sep 2005 18:32 GMT
Hi,

I have three classes extending each other :

class a {
}

class b extends a {
}

class c extends b {
}

The class a and b implements a method x(), and the subclass c want to
reach a.x(), not the overriding b.x() in the direct superclass. How
can I do, and is it a good idea to try doing so ?

I have tried to implement in the class b a method returning a
"pointer" (?) to class a, but it does not work :

class b extends a {
 protected XMLFilter getXMLFilter () {
   return (XMLFilter) super;
 }
}

but the compiler return :

   [javac] C:\home\Corpus\CorpusReader\src\com\LdT\CorpusReader\Pipeline\AbstractBaseFilter.java:96: '.' expected
   [javac]     return (XMLFilter) super;
   [javac]

Which is the "orthodox" way to face this situation ?

Thanks for your help,

sl
Thomas Fritsch - 10 Sep 2005 20:45 GMT
> I have three classes extending each other :
>
[quoted text clipped - 10 lines]
> reach a.x(), not the overriding b.x() in the direct superclass. How
> can I do, and is it a good idea to try doing so ?
Hi,

Why do you want to call the a.x() method explicitly, and not *the* x()
method without actually knowing which x() method you call ?
The whole thing behind overriding methods is, that all the x() methods
should do very similar things. You should think about a specification of
what method x() should do in general and write this as a javadoc-comment
into class a. The b.x() methods might do something more special than the
generic a.x() method, but nevertheless has to follow the specification given
for a.x().
Wanting to call a specific b.x() method may be an indication of an unsolved
discrepancy within the class design (sorry, is not meant as an offence!).

(BTW: Please use class names with a capital first letter. That convention is
wide-spread, and it makes code easier to understand at first glance.)

Signature

"TFritsch$t-online:de".replace(':','.').replace('$','@')

SL - 11 Sep 2005 10:11 GMT
Thank very much for all this answers.

> Why do you want to call the a.x() method explicitly, and not *the* x()
> method without actually knowing which x() method you call ?

[...]

> The whole thing behind overriding methods is, that all the x() methods
> should do very similar things.

[...]

> Wanting to call a specific b.x() method may be an indication of an unsolved
> discrepancy within the class design (sorry, is not meant as an offence!).

You're right. But I'm still wondering if it may be a good solution in
a peculiar context... I explain this (perhaps not so) peculiar context

- I am using chained SAX Filter.

- Each filter I design to inherit from
 org.xml.sax.helpers.XMLFilterImpl.

- The XMLFilterImpl super-class is the only one to hold a reference to
 the next filter in the pipeline, so that the subclass didn't need to
 deal with it. When my sub-class want to throw a SAX callback to the
 next filter, I just need to call the callback on the superclass. For
 instance, let's say I am in the subclass and I want to throw to the
 next filter all the start element with local name = "foo" :

 public void startElement (String uri,
               String localName,
               String qName,
               Attributes atts)
   throws SAXException {
       if (localName.equals("foo") {
         super.startElement(uri, localName, qName, atts);
       }
 }

So the whole pipeline look like :

            |----------|       |----------|        |----------|
            |XMLFilter |\      |XMLFilter |\       |XMLFilter |\      
            |----------| \     |----------| \      |----------| \      
                  |       \          |       \                   \        
sax stream   |----------|   \   |----------|   \    |----------|   \    
------------>|MyFilter1 |    -->|MyFilter1 |    --> |MyFilter1 |    -->etc...
            |----------|       |----------|        |----------|        

(nice, isn't it ?)

- Moreover, what is greatly useful with this design, is that the
 subclass need only to implement the callbacks it want to modify --
 all the callbacks not implemented in the subclass are received by
 the XMLFilter superclass and, then, thrown to the next filter in the
 pipeline. This allows a very economic way of writing filters.

- I want to "reverse" the /default behaviour/ of the superclass. I
 want that, by default, that the superclass do /not/ throw the
 callbacks to the next filter, and that the subclass explicitly
 request for it when it want a callback to be thrown. This is more
 economic in the kind of situations of much callbacks are to be
 discarded, but few of them.

So I plan to write an abstract class sitting between the XMLFilterImpl
and my subclass :

----------------------------------------

public abstract class *AbstractBaseFilter*
 extends *XMLFilterImpl*
 implements [other stuff] {

 private boolean *discardCallbacks* = false;

 /**
  * @param discardCallbacks
  * When a subclass has turn this property to <code>false</code>
  * it needs to reach directly the XMLFilter on top of this class for
  * throwing callbacks further in the pipeline. If it sends the events
  * to its direct superclass (this), they will be silently discarted,
  * according to the requested behaviour. For reaching this
  * XMLFilter, it may ask for a reference using {@link
  * #???}, which return the reference of the superclass.
  *
  * <code>true</code> the received callback are thrown to the
  * super class.
  *
  * <code>false</code> (default) the received callback are not
  * thrown to the super class.
  */
 protected AbstractBaseFilter(boolean discardCallbacks) {
   this.discardCallbacks = discardCallbacks;
 }

 // Overriding ContentHander callback

 public void *startDocument* () throws SAXException {
   if (!discardCallbacks) {
     super.startDocument ();
   }
 }

}

----------------------------------------

The subclass may turn *discardCallbacks* to true or false according to
the wished default behaviour of its superclass.

Now I need, in this subclass, a method allowing the subclass to reach
directly the XMLFilterImpl superclass, in ordre when it set
*discardCallbacks* to true to throw events in the pipeline. That's why
I tried :

 protected XMLFilter getXMLFilter () {
   return (XMLFilter) this;
 }

I may call, from the subclass, the getContentHandler() of the
XMLFilterImpl, for reaching the next filter in the pipeline, but it
breaks the principle, in this design, that the subclass must not deal
directly with the next filter (if I understand correctly).

Do you think this is poorly designed ?

According to the various answer to my original post, should I rather
implement in AbstractBaseFilter new methods throwing /anyway/ the
content, like :

----

 public void *startDocument* () throws SAXException {
   if (!discardCallbacks) {
     super.startDocument ();
   }
 }

 public void forceStartDocument* () throws SAXException {
     super.startDocument ();
 }

----

But I looks poorly designed to, since all methods are duplicated.

I may imagine too that the sublcass directly deal with
discardCallbacks, if I declare the variable protected; for instance,
when it want to throw something :

discardCallbacks = false;
super.startDocument();
discardCallbacks = true;

But it seems to me very error prone to frequently change the value of
*discardCallbacks*.

Thanks for your advice.

SL
Thomas Fritsch - 10 Sep 2005 21:16 GMT
> I have three classes extending each other :
[...]

> The class a and b implements a method x(), and the subclass c want to
> reach a.x(), not the overriding b.x() in the direct superclass. How
> can I do, and is it a good idea to try doing so ?
>
> I have tried to implement in the class b a method returning a
> "pointer" (?) to class a, but it does not work :
What you mean, is probably a reference to an object.

> class b extends a {
>  protected XMLFilter getXMLFilter () {
>    return (XMLFilter) super;
     return super.getXMLFilter();
// would be compilable, but I'm not sure, whether it does what you want.
     return this;
// might also make sense, assumed your class inherits from XMLFilter
>  }
> }

Signature

"TFritsch$t-online:de".replace(':','.').replace('$','@')

Roedy Green - 10 Sep 2005 23:30 GMT
On 10 Sep 2005 19:37:00 +0200, SL <nospam@nospam.com> wrote or quoted

>The class a and b implements a method x(), and the subclass c want to
>reach a.x(), not the overriding b.x() in the direct superclass. How
>can I do, and is it a good idea to try doing so ?

then either a or b must preserve that functionality for you under a
different name.  You have no ability to dig deeper than one level on
your own.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Roedy Green - 10 Sep 2005 23:31 GMT
On 10 Sep 2005 19:37:00 +0200, SL <nospam@nospam.com> wrote or quoted

>The class a and b implements a method x(),
It is very confusing when you ignore naming conventions.  See
http://mindprod.com/jgloss/namingconventions.html

Please rephrase that as :
The classes A and B implement a method x(),
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Again taking new Java programming contracts.

Bjorn Abelli - 11 Sep 2005 08:59 GMT
"SL" wrote...

> I have three classes extending each other :
>
[quoted text clipped - 10 lines]
> reach a.x(), not the overriding b.x() in the direct superclass. How
> can I do, and is it a good idea to try doing so ?

[snip]

> Which is the "orthodox" way to face this situation ?

The "orthodox" way is to not do it... ;-)

Any given subclass is a specialization of its immediate superclass, and
hence you are confined to specialize only the behaviour inherited from that
superclass, not further up in the hierarchy.

If you want an "un-orthodox" way to solve it, you could use a reversed
"Template Method"-pattern, something like this:

class a {
 public void x() {
   ax();
 }
 final protected void ax() { }
}

class b extends a {

 public void x() {
   bx();
 }
 protected void bx() {}
}

class c extends b {
 public void x() {
   ax();
 }
}

In the "Template Method"-pattern, it's the other way around, that the
inherited "x" calls methods that are supposed to be overridden. In this
reversed variant, the called methods are left intact, so they are available
throughout the hierarchy. It's possible that this pattern exists under
another name.

It's a bit clumsy, and there are probably better ways of doing this, but I
have used it on occasion...

// Bjorn A


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.