Java Forum / General / December 2005
Java Question
rajesh.shiggaon@gmail.com - 27 Dec 2005 13:06 GMT Hi Everyone:
I know we cannot use a super keyword for an abstract implemented method. But below is my class hirearchy. As you know finalize has to be explictily chained, how can i achieve this with my below code?
class A { public void finalize(){ System.out.println("Inside the finaliaze method"); }
}
abstract class B extends A { public abstract void finalize(); }
class C extends B {
public void finalize(){ System.out.println("Inside the class B"); //super.finalize(); How can I call the finalize method in Class A } }
Thanks in advance.
Rajesh Shiggaon
Roedy Green - 27 Dec 2005 13:34 GMT On 27 Dec 2005 05:06:52 -0800, "rajesh.shiggaon@gmail.com" <rajesh.shiggaon@gmail.com> wrote, quoted or indirectly quoted someone who said :
>//super.finalize(); How can I call the finalize method in Class A You can't unless you call it in class B or if you name it in A something not overridden in B.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Thomas Hawtin - 27 Dec 2005 13:48 GMT > I know we cannot use a super keyword for an abstract implemented > method. But below is my class hirearchy. As you know finalize has to be [quoted text clipped - 18 lines] > } > } B.finalize should be calling A.finalize, so shouldn't be abstract.
In general you could get around this sort of situation by adding a protected/package private method to B that calls A.finalize.
It's best to leave finalize methods as protected and throwing Throwable. Or better still, don't use them.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Viator - 27 Dec 2005 20:48 GMT > abstract class B extends A { > public abstract void finalize(); > } Why???
Luc The Perverse - 27 Dec 2005 21:59 GMT >> abstract class B extends A { >> public abstract void finalize(); >> } > > Why??? A C++ programmer could easily do that thinking it might be needed just out of habit.
-- LTP
:) Adam Maass - 28 Dec 2005 05:41 GMT > Hi Everyone: > [quoted text clipped - 22 lines] > > Thanks in advance. Omit your finalize() from class B. It isn't needed.
rajesh.shiggaon@gmail.com - 28 Dec 2005 11:13 GMT Many of you have asked why abstract void finalize() is in class B, I was thinking that by making this method abstract all the subtypes will be implementing there own version of this methd. In simple word to enfore the subtypes to implement this metyhd.
Thanks for all your response.
Since the calling of finalize() in the Class A, why the complier prevent this kind of code.
Thanks Rajesh S
> > Hi Everyone: > > [quoted text clipped - 24 lines] > > Omit your finalize() from class B. It isn't needed. Thomas Hawtin - 28 Dec 2005 14:34 GMT > Since the calling of finalize() in the Class A, why the complier > prevent this kind of code. Although extending a class is a disaster for encapsulation, the base/super-class does still expose a particular interface to the derived/sub-class. In this case class B indicates that it does not implement finalize. class A's declaration of finalize is not visible.
In C++ the base class' member function remains visible, but requires the function name to be qualified with the class name. You can even have an abstract (pure virtual, = 0) function, but supply an implementation that can be called explicitly.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Roedy Green - 28 Dec 2005 14:48 GMT On Wed, 28 Dec 2005 14:43:16 +0000, Thomas Hawtin <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone who said :
>Although extending a class is a disaster for encapsulation Could you explain that. I thought the notion of extending classes was FOR encapsulation. If you had a theme and variations, you encapsulate the common code.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Andrew McDonagh - 28 Dec 2005 15:14 GMT > On Wed, 28 Dec 2005 14:43:16 +0000, Thomas Hawtin > <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone [quoted text clipped - 5 lines] > FOR encapsulation. If you had a theme and variations, you encapsulate > the common code. No, association is for encapsulation.
Andrew McDonagh - 28 Dec 2005 15:15 GMT >> On Wed, 28 Dec 2005 14:43:16 +0000, Thomas Hawtin >> <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone [quoted text clipped - 5 lines] >> FOR encapsulation. If you had a theme and variations, you encapsulate >> the common code. we may extract the common code into a base class, we don't encapsulate it. But still, prevailing OO design suggests we favor delegation over inheritance.
Andrew McDonagh - 28 Dec 2005 15:25 GMT >>> On Wed, 28 Dec 2005 14:43:16 +0000, Thomas Hawtin >>> <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone [quoted text clipped - 8 lines] > we may extract the common code into a base class, we don't encapsulate > it. But still, prevailing OO design theory
> suggests we favor delegation over inheritance. As this allows for dynamic relationships which are easier and safer to change, than the static and usually brittle inheritance relationships.
Thomas Hawtin - 28 Dec 2005 15:50 GMT > On Wed, 28 Dec 2005 14:43:16 +0000, Thomas Hawtin > <usenet@tackline.plus.com> wrote, quoted or indirectly quoted someone [quoted text clipped - 5 lines] > FOR encapsulation. If you had a theme and variations, you encapsulate > the common code. The important thing about variations is that client code should be able to handle different implementations of an interface without alteration. That's polymorphism.
Overriding methods brings a high level of coupling. A change of implementation (but not interface) of one class can upset another.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
rajesh.shiggaon@gmail.com - 28 Dec 2005 11:17 GMT Many of you have asked why abstract void finalize() is in class B, I was thinking that by making this method abstract all the subtypes will be implementing there own version of this methd. In simple word to enfore the subtypes to implement this metyhd.
Thanks for all your response.
Since the calling of finalize() in the Class A not possible, why the complier cant prevent this kind of code.
Thanks Rajesh S
> > Hi Everyone: > > [quoted text clipped - 24 lines] > > Omit your finalize() from class B. It isn't needed. Viator - 28 Dec 2005 18:53 GMT >>Many of you have asked why abstract void finalize() is in class B, I >>was thinking that by making this method abstract all the subtypes will >>be implementing there own version of this methd. In simple word to >>enfore the subtypes to implement this metyhd.
>>Thanks for all your response.
>>Since the calling of finalize() in the Class A not possible, why the >>complier cant prevent this kind of code. Don't you think that a call to super.finalize() in finalize method of a class is a functional requirement and nothing to do with the Java language. For example, it is not a compile time error not to call super.finalize() in the finalize method. It is always the responsibility of the programmer to get it correct and for that reason to have a correct class hierarchy. Forcing the subclasses to implement the finalize method has no point if the subclass has nothing to cleanup (In C++ most of the time you free a dynamically allocated memory in destructors while in Java that is done by GC).
Amit :-)
Thomas Hawtin - 28 Dec 2005 19:25 GMT > to have a correct class hierarchy. Forcing the subclasses to implement > the finalize method has no point if the subclass has nothing to cleanup > (In C++ most of the time you free a dynamically allocated memory in > destructors while in Java that is done by GC). If the intent of an abstract finaliser is to follow the C++ idiom of pure virtual destructors, then it's very wrong.
In C++ you will get a destructor whatever. If you don't write one, you'll get an implicit implementation anyway. So you can write this sort of thing:
class Base { public: virtual ~Base() = 0; }; Base::~Base() { } class Derived : Base { };
The C++ pure virtual destructor idiom is for asserting that the class must be subclassed before it can be instantiated. The Java equivalent is to label the class abstract (or use an interface).
BTW: There is a more robust technique than calling super.finalize. Keep a private reference to a guard object that actually contains the finaliser. In that way you don't need to worry about your class and subclasses calling super. However, you don't then know the order in which the finalisers are called.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
rajesh.shiggaon@gmail.com - 29 Dec 2005 10:15 GMT If we are sure that the subclass has to clean up, then only way we can force this by using the abstract method. I dont think so there is any problem with the class hierrachy. The hirearcy makes sense. If we go with this hirearcy we will loose the functionality of fianalize method in class A.
We are loosing the functioality of finalize of what is used for.
Rajesh S
Ranganath Kini - 29 Dec 2005 11:29 GMT If you need to ensure that C needs to implement finalize(), I absolutely dont see any need to make finalize() in class B abstract or even have the method definition in class B in the first place. If finalize() is not redefined in class B as abstract, the implementation of class A is automatically inherited by B and the same will automatically be inherited by C. This is Java's default behaviour. If subclasses of B need to redefine or extend the inherited finalize() implementation, they may do so by overriding.
I strongly believe that by making finalize() method abstract in class B, u break the automatic implementation inheritance of Java. And it also does not make sense in invoking super.finalize() in class C when u know that super.finalize() (i.e. B.finalize() ) is abstract. If u need to reuse the implementation of class A, dont hide A's finalize() by making it abstract in class B.
I view your implementation as very odd and I think that such a requirement may eiether have to be redesigned or properly documented before distributing the code. You can only inform and suggest subclasses to do the right thing. You cannot correct them if their designs are bad.
Regards, Ranganath
Ranganath Kini - 29 Dec 2005 05:05 GMT For your odd requirement, I might consider implementing the program like this:
/*********************************************************** * Name: C.java * ***********************************************************/ class A { public void finalize() { finalizeImpl(); }
protected void finalizeImpl() { System.out.println("Inside the finaliaze method"); } }
abstract class B extends A { public abstract void finalize(); }
public class C extends B { public void finalize(){ System.out.println("Inside the class B"); super.finalizeImpl(); }
public static void main( String[] args ) { C myC = new C(); myC.finalize(); } }
Hope it helps!
Regards, Ranganath
rajesh.shiggaon@gmail.com - 29 Dec 2005 10:17 GMT Hey Ranganath:
We can do the above functionality in 100 ways, but the finalize method we loose its value nad will not make any sense.
Thanks Rajesh S
Andrew McDonagh - 29 Dec 2005 11:59 GMT > Hi Everyone: > [quoted text clipped - 24 lines] > > Rajesh Shiggaon So, by now, hopefully you have some idea of what the others have been saying about why or how you could do this... if not here's a little something for you...
As you know your current approach won't work but we can get the same effect legally by using a different abstract method, which the base class (B) calls....this is know as 'The Template Method'
class A { public void finalize(){ System.out.println("Inside the finalize method"); }
}
abstract class B extends A { public abstract void extraFinalizeStuff();
public void finalize(){ super.finalize(); extraFinalizeStuff(); } }
class C extends B {
public void extraFinalizeStuff(){ System.out.println("Inside the class B"); }
}
So this is basically saying that any class deriving from B must implement (or itself be an abstract class) the 'extraFinalizeStuff()'.
Those derived classes don't need to override the base class's 'finalize()' method, as it will automatically call the 'extraFinalizeStuff()'.
Note however, this approach is only ever going to enforce that the implementing derived classes implement the template method, it doesn't help for further derived classes below that.
Aside from this, the notion of using inheritance, whilst appealing is itself, its own worst enemy, because of issues like this and more. If we took the delegation approach to your problem, we would move the code that lives in those finalize methods, into classes of their own and so we wouldn't have to chain them together, they would behave just like normal classes.
Andrew
Thomas Hawtin - 29 Dec 2005 12:46 GMT > public void finalize(){ > super.finalize(); > extraFinalizeStuff(); > } Or
protected void finalize() throws Throwable { try { extraFinalizeStuff(); } finally { super.finalize(); } }
As a rule, deconstruction should run in the reverse order of construction. And you should do your best to clear up, even in the event of error.
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Andrew McDonagh - 29 Dec 2005 12:59 GMT >> public void finalize(){ >> super.finalize(); [quoted text clipped - 16 lines] > > Tom Hawtin true...good catch
sipayi@gmail.com - 29 Dec 2005 20:57 GMT Two sets of questions/thoughts:
Was the originator of the thread trying to enforce some rules onto objects at the time of destruction? Such as, releasing resources, etc.? Wouldn't the solution simply be a coding guidelines document?
Shouldn't the object that acquired these resources the best judge to release them? Would delegation may not really solve it? There is already a delegate (garbage collector) which cleans up whenever. And how would you delegate? Aspects?
Or, have I totally missed the point? -Siplin
Andrew McDonagh - 29 Dec 2005 21:39 GMT > Two sets of questions/thoughts: > > Was the originator of the thread trying to enforce some rules onto > objects at the time of destruction? Such as, releasing resources, etc.? > Wouldn't the solution simply be a coding guidelines document? Yes, from what I read, they are trying to enforce that the base class A's finalize method is called when one of its derived classes finalize method is called.
Maybe its an exercise in rule enforcement with inheritance for the op. Maybe the code is a simplified version of what they have already....an hierarchy of derived, intermediate, abstract and a base class, where the base class contains common code that allocates and therefore needs to de-allocate during a finaliser.
> Shouldn't the object that acquired these resources the best judge to > release them? Would delegation may not really solve it? There is > already a delegate (garbage collector) which cleans up whenever. And > how would you delegate? Aspects? Absolutely... which was my point with the following....
Quoting....
> Note however, this approach is only ever going to enforce that the > implementing derived classes implement the template method, it doesn't [quoted text clipped - 6 lines] > we wouldn't have to chain them together, they would behave just like > normal classes. The real problem from my point of view is not rule enforcement of an inheritance hierarchy.......its the inheritance hierarchy itself.
Replacing that hierarchy with a set of collaborating classes, allows us to have those classes know what and when to De/Allocate resources themselves without reliance upon flimsy inheritance rules.
Andrew
Stefan Schulz - 30 Dec 2005 14:20 GMT > Hi Everyone: > > I know we cannot use a super keyword for an abstract implemented > method. But below is my class hirearchy. As you know finalize has to be > explictily chained, how can i achieve this with my below code? Ask yourself why you want to do so. If you need to finalize(), then you are dealing with some resource not (easily) accessible to the garbage collector. Adding more finalization usually indicates these resources are not well-encapsulated. Consider moving the resource handle into an own class which deals with finalization, and let the gc do the rest.
Or, to state it differently:
protected final void finalize() throws Throwable { /* ... */ }
is about the only kind of finalizer there should be.
 Signature You can't run away forever, But there's nothing wrong with getting a good head start. --- Jim Steinman, "Rock and Roll Dreams Come Through"
Free MagazinesGet 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 ...
|
|
|