Java Forum / General / October 2005
Constructor inheritance
Alex - 23 Oct 2005 22:39 GMT I have parent class with a lot of constructors. So, I have to repeat all of them. Then I use new class as parent again. And should recreate all constructrors again.
Is there any way to "inherit" constructors without redefining them? Maybe Java 1.5 has something? Like generic constructor :)
Alex.
Andrew McDonagh - 23 Oct 2005 23:23 GMT > I have parent class with a lot of constructors. > So, I have to repeat all of them. Why?
As a minimum you need to repeat one of them for it to compile - not all.
> Then I use new class as parent again. > And should recreate all constructrors again. [quoted text clipped - 3 lines] > > Alex. Ok, first off a class with lots of constructors tends to mean the class is capable of being used for a variety of reason.
e.g. Class Account {
public Account(boolean, isCheckAccount, double overdraftLimit) {..} public Account(boolean isSavingsAccount, double interestRate) {...}
//etc }
If this isn't your case then great - but can you post the class's code here so we can see it (note you can remove the bodies of the methods - we just need to see the skeleton.
If it is the case, then instead of having lots of constructors, what you need is more classes. Each class can then support the 'Single Responsibility Principle' (Worth googling for if you haven't come across it).
However, regardless of the above, if you do need to have lots of constructors (which I doubt very much - I'd bet you need extra classes), then you have a few choices.
1) Chain your constructors so that each constructor calls a 'catch-all' constructor - then the catch-all constructor is the only one that needs to call the base classes constructor.
See example here: http://www.logemann.org/day/archives/000104.html And see why some people don't like constructor chaining here: http://www.beust.com/weblog/archives/000206.html
2) Google 'Replace COnstructors for factory methods' (or just see http://www.industriallogic.com/xp/refactoring/constructorCreation.html)
3)....for others to chip in with....
HTH
Andrew
Lasse Reichstein Nielsen - 23 Oct 2005 23:50 GMT > Ok, first off a class with lots of constructors tends to mean the > class is capable of being used for a variety of reason. My experience is that lots of constructors is a sign some of the arguments having reasonable default values. Then you make a constructor without these optional arguments, calling the real constructor with default values in their place. With just three such optional arguments, you would get eight constructors, each omitting a number of arguments.
/L
 Signature Lasse Reichstein Nielsen - lrn@hotpop.com DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html> 'Faith without judgement merely degrades the spirit divine.'
Alex - 24 Oct 2005 00:00 GMT Thanks for answers. But, plesse, don't change the subject. Was it question how to declare constructors, when or for what? Was it question for programming tips?
It is particular question: how to simplify constructor "inheritance". I know it is impossible in general (except you have to redefine all of them). But may be some tricks exist...
Please, no answres like "Why do you need all these constructors anyway?"...
Sincerely, Alex.
Roedy Green - 24 Oct 2005 00:12 GMT >It is particular question: how to simplify constructor "inheritance". >I know it is impossible in general (except you have to redefine all of >them). >But may be some tricks exist... The elegant to solution to most difficult problems is to find a way that you don't need a solution.
That's how you crack security systems.
That's how you save your company/country really big money.
Constructors don't inherit. That's a fact of life. You are going to have to bypass that problem, not find a way to make them inherit.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Andrew McDonagh - 24 Oct 2005 01:13 GMT > Thanks for answers. No problem.
> But, plesse, don't change the subject. We aren't - we are trying to determine what kind of trick you need.
> Was it question how to declare constructors, when or for what? > Was it question for programming tips? [quoted text clipped - 3 lines] > them). > But may be some tricks exist... I gave you two.
but if you know so much I think you are best placed to answer your own question from now on.
> Please, no answres like "Why do you need all these constructors > anyway?"... Don't worry - I doubt anyone here will try from now on.
> Sincerely, Alex. Andrew Thompson - 24 Oct 2005 01:40 GMT > But, plesse, don't change the subject. Notes.
1) This is a Usenet Newsgroup for the discussion of the Java programming language. Nobody changed the subject.
2) If you meant more 'veer away from my question', the sad reality is that people will answer your question - if the feel like it, and.. - when they get around to it.
My suggestion - enjoy the thread, but keep pulling it gently back to where you want it to go. If people want to go off in a obscure side-thread, let them do so without comment, but reply to the parts of any message you see as relate to your original problem.
Roedy Green - 24 Oct 2005 03:38 GMT >My suggestion - enjoy the thread, but keep pulling it >gently back to where you want it to go. If people want >to go off in a obscure side-thread, let them do so without >comment, but reply to the parts of any message you see as >relate to your original problem. You must understand is that from our point of view, your function here is a bring up interesting questions to discuss. We are not here to solve your problem. If that happens as a side effect of the discussion, great.
That is an exaggeration, but if you act as if you believed that, you will get the maximal utility from the group.
see http://mindprod.com/jgloss/newsgroups.html
If you act like some precious little prince ordering his servants about, you will soon find your questions ignored.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Roedy Green - 24 Oct 2005 00:08 GMT >My experience is that lots of constructors is a sign some of the >arguments having reasonable default values. Then you make a >constructor without these optional arguments, calling the real >constructor with default values in their place. With just three such >optional arguments, you would get eight constructors, each omitting >a number of arguments. Look at almost any of Sun's classes with a lot of constructors .There is one do everything but eat constructor then all the others call it.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Andrew McDonagh - 24 Oct 2005 01:28 GMT >>Ok, first off a class with lots of constructors tends to mean the >>class is capable of being used for a variety of reason. [quoted text clipped - 7 lines] > > /L Yes that is one of the typical reasons for having them and SUn's code base is littered with them.
I personally don't think they are a good idea though.
If a constructor has lots of parameters that can be defaulted or not, I prefer one or two different ways of using them:
1) refactor the many parameters into a few new Classes and objects of those types as parameters instead. That way I get to reuse these logical parameter grouping as a true objects.
2) Lets take JTable (see http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JTable.html) it has 7 different Constructors taking anything from 0 to 3 parameters, each constructor doing something slightly different.
Its a mess. A single constructor and a JTable Factory would have been cleaner. As it is, the extra JTable constructors now give the Class additional responsibilities, its no longer a Table it also has 6 other responsibility that do conversion from one type of data type to the internal data type.
YMMV
Andrew
Alex - 24 Oct 2005 15:13 GMT Thanks a lot for all. I think it was interesting question and we have aggrement - constructors can't be "inherited" in any way.
Andrew's example is the best. If you want to use JTable - you have to "inherit" all it's constructors. And it's a pain...
isamura - 24 Oct 2005 17:32 GMT : Thanks a lot for all. : I think it was interesting question and we have aggrement - : constructors can't be "inherited" in any way. : : Andrew's example is the best. If you want to use JTable - you have to : "inherit" all it's constructors. And it's a pain... I've been listening in with some interest and was hoping to have an explaination why it is so.
A quick test show the only constructor that can be inherited is an empty one. For example,
ClassB() extends ClassA()
new ClassB(); can inherit the ClassA() constructor without over-riding.
If ClassA has another constructor ClassA(String s), then
new ClassB("this will be a pain"); won't compile unless a ClassB(String s) constructor is defined. Eventhough it may just call super(s);
So, why can't Java find a matching constructor for new ClassB(s) from ClassA(String s)? I don't see why the compliler can't translate a missing constructor to super(s); and try it.
Hoping to be enlightened...
.K
zero - 24 Oct 2005 18:21 GMT > > I've been listening in with some interest and was hoping to have an [quoted text clipped - 21 lines] > > .K Constructors are not inherited. Not ever. The empty constructor you mentioned is in fact the default constructor. Any class that has no constructor is given a default constructor by the compiler. This default constructor calls the superclass constructor.
So in this case if you have:
class ClassA { public ClassA() { System.out.println("ClassA constructor"); } }
class ClassB { }
then the compiler will re-write ClassB as
class ClassB { public ClassB() { super(); } }
Note that the ClassA constructor is NOT inherited by ClassB. It is just called from the default ClassB constructor.
The compiler only creates no-argument default constructors. If ClassA has a second constructor ClassA(String s), that does not necessarily mean ClassB should have one too. The compiler won't create one, because it doesn't know if you actually want one. It does create a no-argument constructor, because all (non-abstract) classes must have a constructor.
isamura - 24 Oct 2005 18:56 GMT : > I've been listening in with some interest and was hoping to have an : > explaination why it is so. [quoted text clipped - 25 lines] : constructor is given a default constructor by the compiler. This default : constructor calls the superclass constructor. That is interesting. The compiler gives a false sense of OOness...certainly got me.
: So in this case if you have: : [quoted text clipped - 22 lines] : doesn't know if you actually want one. It does create a no-argument : constructor, because all (non-abstract) classes must have a constructor. In my example ClassB is a subclass of ClassA (in a ISA relationship), so more than likely the ClassA(String s) constructor is inherited. Wouldn't it be more productive (for developers) if the compiler would do its magic and create all inherited constructors, when missing? I guess this is just my wishful thinking but we have to live with what is given. Just don't expect all of us to be happy about it.
.K
Andrew McDonagh - 24 Oct 2005 19:54 GMT > : > I've been listening in with some interest and was hoping to have an > : > explaination why it is so. [quoted text clipped - 62 lines] > > ..K No, because we often don't want the same set of constructors on derived classes, that are available on base (super) classes.
Simplistically, a compiler jobs is to convert your .java source code into JVM compatible byte code.
However, most modern IDEs have the ability for you to right click on a derive class and over ride as many methods & constructors you'd like, with a few mouse clicks.
isamura - 24 Oct 2005 21:13 GMT : > : > I've been listening in with some interest and was hoping to have an : > : > explaination why it is so. [quoted text clipped - 65 lines] : No, because we often don't want the same set of constructors on derived : classes, that are available on base (super) classes. Inheritance is supposed to promote code resuse (and good design). I will agree that at times it may be desirable to over-ride a behavior of the super class that is not appropriate, but this does (should) not happen often. At least not in my "camp".
: Simplistically, a compiler jobs is to convert your .java source code : into JVM compatible byte code. So it was surprising the compiler generates missing default constructors.
: However, most modern IDEs have the ability for you to right click on a : derive class and over ride as many methods & constructors you'd like, : with a few mouse clicks. Yes I can see why such a feature is neccessary...<sigh>
Tor Iver Wilhelmsen - 24 Oct 2005 22:40 GMT > Inheritance is supposed to promote code resuse (and good design). I > will agree that at times it may be desirable to over-ride a behavior > of the super class that is not appropriate, but this does (should) > not happen often. At least not in my "camp". Why not? That is akin to not provide accessors to every variable in a class: Some behavior is meant to be unavailable to client classes. Constructors are not and should not provide behavior, ONLY initialization.
In C++ you can go even further, by restricting the very interfaces of superclasses (prohibited in Java):
class MyClass: private BaseClass { // All public members in BaseClass become private to MyClass }
> So it was surprising the compiler generates missing default > constructors. No, it has to. You need at least one constructor in order to initialize fields. Same holds in e.g. C++.
Andrew McDonagh - 24 Oct 2005 23:25 GMT >>Inheritance is supposed to promote code resuse (and good design). I >>will agree that at times it may be desirable to over-ride a behavior [quoted text clipped - 3 lines] > Why not? That is akin to not provide accessors to every variable in a > class: Some behavior is meant to be unavailable to client classes. Whilst true, if we want to restrict behavior to client classes, then using different Interfaces (as in the OO sense - not just Java's Interfaces) would actually provide a cleaner mechanism.
A.L.A The 'Interface Segregation Principle'.
This way we can reduce the total foot print of the object's interface that is passed around the system. Thereby allowing the us to make behavior unavailable to client classes, simply by having them accept parameter of different Interfaces.
Our classes implement several interfaces.
> Constructors are not and should not provide behavior, ONLY > initialization. Agreed - most of the time. I prefer to use Factories if I need behavior rather than initialisation.
> In C++ you can go even further, by restricting the very interfaces of > superclasses (prohibited in Java): > > class MyClass: private BaseClass { > // All public members in BaseClass become private to MyClass > } For me, one of the only things missing from Java that C++ has. (but please don't tell the Java police...).
I think this is what C#'s Delegates is all about - which Java gets in version 6 if I'm not mistaken. Can anyone else confirm my thinking - or have I got the wrong end of the stick?
Its a very good way of code reuse without creating the is-a relationship.
For those not clear on this, what it means is that a Derived class can make use of the behavior within the base class, but as far as the rest of the OO design is concerned, the derived class 'is NOT a' <base class>. The derived class is does not support the public interface described by the base class.
Hendrik Maryns - 25 Oct 2005 12:33 GMT Andrew McDonagh schreef:
>>> Inheritance is supposed to promote code resuse (and good design). I >>> will agree that at times it may be desirable to over-ride a behavior [quoted text clipped - 29 lines] >> // All public members in BaseClass become private to MyClass >> } <snip>
> Its a very good way of code reuse without creating the is-a relationship. > [quoted text clipped - 3 lines] > class>. The derived class is does not support the public interface > described by the base class. Why would you want to use inheritance if it is NOT for an is-a relationship? That's all inheritance is about. Otherwise, use delegation. MyClass would not pass Liskov's principle. Anyway, as it is not a good idea to have public members anyway, I don't see any need for this (except when by members you also mean methods).
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Andrew McDonagh - 25 Oct 2005 20:54 GMT > Andrew McDonagh schreef: snipped
>>> In C++ you can go even further, by restricting the very interfaces of >>> superclasses (prohibited in Java): [quoted text clipped - 15 lines] > Why would you want to use inheritance if it is NOT for an is-a > relationship? That's all inheritance is about. In Java yes, in OO terms no...
> Otherwise, use > delegation. MyClass would not pass Liskov's principle. Anyway, as it > is not a good idea to have public members anyway, I don't see any need > for this (except when by members you also mean methods). > > H. ...Inheritance comes in two forms.
1) Interface Inheritance - What you'd expect, this allows Liskov's Principle. But not necessary code reuse - as in inheriting from a pure abstract class, or in Java terms, implementing an Interface
2) Implementation Inheritance - What is described above in the C++ code. The derive class can't be used in terms of Liskov's principle, but it does have access to all of the base class code and so code re-use in this form is possible.
In Java we have the choice
1) being very specific about Interface Inheritance - e.g. 'class Blar implements MyInterface'
2) use Interface & Implementation inheritance at the same time - e.g. 'class Blar extends MyBaseClass'
But we can't have only Implementation inheritance like C++ - and in general its (even though I miss it sometimes) a very good thing - as it forces us to 'favor delegation over Inheritance' ( a nice google-able term there) - which naturally creates a dynamic low coupled design.
Andrew
Hendrik Maryns - 26 Oct 2005 12:48 GMT Andrew McDonagh schreef: snipped
>> Why would you want to use inheritance if it is NOT for an is-a >> relationship? That's all inheritance is about. > > In Java yes, in OO terms no... Depends on what you call OO. I'll refine my previous sentence: That's all inheritance _should be_ about.
<snip>
> ...Inheritance comes in two forms. > [quoted text clipped - 6 lines] > does have access to all of the base class code and so code re-use in > this form is possible. I'd call this abuse of the inheritance system.
> In Java we have the choice > [quoted text clipped - 8 lines] > forces us to 'favor delegation over Inheritance' ( a nice google-able > term there) - which naturally creates a dynamic low coupled design. Indeed.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Andrew McDonagh - 26 Oct 2005 19:37 GMT > Andrew McDonagh schreef: > snipped [quoted text clipped - 6 lines] > Depends on what you call OO. I'll refine my previous sentence: That's > all inheritance _should be_ about. Agreed
> <snip> > [quoted text clipped - 10 lines] > > I'd call this abuse of the inheritance system. Hmm... it is another valid use - but certainly not one I'd favour usually - I think I've only ever seen one instance where it was the right choice - though for the life of me I can't remember it :-)
>> In Java we have the choice >> [quoted text clipped - 11 lines] > > Indeed. Tor Iver Wilhelmsen - 26 Oct 2005 16:47 GMT > But we can't have only Implementation inheritance like C++ Yes you can:
public class MyClass {
private OtherClass myOtherClassPart = new OtherClass();
}
MyClass can freely call OtherClass methods (implementation) without exposing the interface.
The syntax is different, the effect the same.
Andrew McDonagh - 26 Oct 2005 19:35 GMT >>But we can't have only Implementation inheritance like C++ > [quoted text clipped - 8 lines] > MyClass can freely call OtherClass methods (implementation) without > exposing the interface. That's Delegation though, not inheritance.
In the Implementation Inheritance we could have code like:
class OtherClass { String getName() { return "foo"; } }
public class MyClass {
private OtherClass myOtherClassPart = new OtherClass();
public String toString() { return getName(); // <-- call to non-existent method }
}
When in fact with current Java, this would not compile because MyClass does not have a method called 'getName()'. So we have to do:
public String toString() { // we have to delegate to member var. return myOtherClassPart.getName(); }
Tor Iver Wilhelmsen - 27 Oct 2005 15:57 GMT > When in fact with current Java, this would not compile because MyClass > does not have a method called 'getName()'. So we have to do: [quoted text clipped - 3 lines] > return myOtherClassPart.getName(); > } Yes, but the only difference to the programmer is a little more typing. There is no difference to the client.
Andrew McDonagh - 27 Oct 2005 19:15 GMT >>When in fact with current Java, this would not compile because MyClass >>does not have a method called 'getName()'. So we have to do: [quoted text clipped - 6 lines] > Yes, but the only difference to the programmer is a little more > typing. There is no difference to the client. true - but its still delegation not inheritance - its important we understand the difference here, newbies have enough trouble getting to grips with the problem space as it is - it we start mis-interpreting words they will be buggered.
Tor Iver Wilhelmsen - 28 Oct 2005 16:08 GMT > true - but its still delegation not inheritance - its important we > understand the difference here, newbies have enough trouble getting to > grips with the problem space as it is - it we start mis-interpreting > words they will be buggered. But is the distinction at all interesting?
class MyClass: private OtherClass { ... }
MyClass object;
OtherClass* other = &object;
does not work, giving an error that OtherClass is an inaccessible base of MyClass. You might as well have used a delegate.
The real point here is that Java is highly unlikely to add such a feature anyway.
Chris Uppal - 28 Oct 2005 10:03 GMT > Yes, but the only difference to the programmer is a little more > typing. And the fact that overloading doesn't work.
And the fact that the delegate's notion of "this" is not the same as the outer object's notion of "this".
And the fact that the outer object cannot make use of any protected members of the delegate.
-- chris
Tor Iver Wilhelmsen - 28 Oct 2005 16:15 GMT > And the fact that overloading doesn't work. It does if you extend the delegate.
> And the fact that the delegate's notion of "this" is not the same as > the outer object's notion of "this". Correct, you need to qualify the outer this in code that extends the delegate.
> And the fact that the outer object cannot make use of any protected > members of the delegate. Any code extending the delegate can.
Why can't people use the "workarounds" Java provides instead of trying to turn Java into C++? Is it really the end of the world just because the syntax is a little more verbose?
Do people really post to C++ newsgroups complaining that it doesn't have a root object class, for instance?
Jaakko Kangasharju - 28 Oct 2005 16:24 GMT > Do people really post to C++ newsgroups complaining that it doesn't > have a root object class, for instance? Yes :)
Seriously, I've seen that complaint about C++ a few times (and also others that all basically amount to "C++ is not Java and therefore wrong"). And I think the existence of a root object class at least used to be a regular flamewar topic in comp.lang.smalltalk.
 Signature Jaakko Kangasharju, Helsinki Institute for Information Technology What sucks about holidays: You have to pay for your coffee
Eike Preuss - 25 Oct 2005 10:35 GMT [snip]
>>So it was surprising the compiler generates missing default >>constructors. > > No, it has to. You need at least one constructor in order to > initialize fields. Same holds in e.g. C++. The compiler could produce an error when some class is missing a constructor, as it does when implementing an interface, eg. So the compiler doesn't _have to_ create a default constructor for you... i just don't like the expression 'no, it has to' :) And sometimes it would be good to be reminded that I might want to initialize my new class a different way than the default-way.
++ Eike
Andrew McDonagh - 24 Oct 2005 23:11 GMT snipped
> : > compiler would do its magic and create all inherited constructors, when missing? I guess this is > : > just my wishful thinking but we have to live with what is given. Just don't expect all of us to [quoted text clipped - 7 lines] > : > Inheritance is supposed to promote code resuse (and good design). Not really, Inheritance is to provide an 'is-a' relationship between one derived type and its parent type, there by allowing the 'Liskov Substitutability Principle' to work.
Code reuse is useful side effect of this relationship, but its not it aim. Indeed designs that make use of inheritance simply to get code reuse are usually the fragile designs, comprising of large inheritance trees.
If code re-use is the aim, then delegation not inheritance should be favored.
As a concrete example, consider Java's Thread class. To create and use a thread, a much more preferable OO design is to instantiate a Thread object and give it an instance of one of your own classes that implement the Runnable interface. This design then conforms to the 'Single Responsibility Principle'. Also, we still get total code re-use and a dynamic runtime relationship between the Thread class and the Runnable class.
Where as we could derived from Thread and implement the Run() method with the same logic that could exist within the first example's Runnable class.
But now we have a static compile time relationship, a Thread derived class that not only is a Thread but also the Runnable - its a duel responsibility class.
Yet there's no more code reuse.
> I will agree that at times it may be desirable to over-ride a behavior > of the super class that is not appropriate, but this does > (should) not happen often. At least not in my "camp". Agreed, but not what I was writing about. I was attempting to show that with constructors in Java we can chose to hide some or all of the same kind of constructors that appear on the base classes through the derived classes.
I rarely find the need to have the same number and signature type of constructors on derived classes - see my other post with the MyOwnException class deriving from RuntimeException.
> : Simplistically, a compiler jobs is to convert your .java source code > : into JVM compatible byte code. > : > So it was surprising the compiler generates missing default constructors. Not really, that is a special case dealing with the mechanics of creating an object - all classes need a constructor of some kind, the simplest one being the no-arg constructor. However, the compiler will only generate a default constructor if no other user defined constructor appears on the class. If you have created your own constructor, the compiler can't generate one because there is no universal good option available for every java application, and so the compile will fail with an error.
Andrew
isamura - 25 Oct 2005 02:54 GMT "Andrew McDonagh" <news@andrewcdonagh.f2s.com> wrote in ...
: snipped : [quoted text clipped - 18 lines] : reuse are usually the fragile designs, comprising of large inheritance : trees. Agreed. I did not mean to imply inheritance be used (abused) in this manner. I doubt code reuse can be of much in this case.
: If code re-use is the aim, then delegation not inheritance should be : favored. [quoted text clipped - 6 lines] : dynamic runtime relationship between the Thread class and the Runnable : class. Good example.
: Where as we could derived from Thread and implement the Run() method : with the same logic that could exist within the first example's Runnable : class. A thread is a process that runs a sequence of code so your previous example makes sense. But subclassing for the same purpose would not. It wouldn't even pass the IS-A test.
: But now we have a static compile time relationship, a Thread derived : class that not only is a Thread but also the Runnable - its a duel [quoted text clipped - 10 lines] : kind of constructors that appear on the base classes through the derived : classes. That is one point of view. Alternatively, allow subclasses to inherit constructors. For a given class, if any of the inherited constructors are invalid, the class can over-ride the "illegal" constructor to throw an exception to indicate it shouldn't be used. This approach may have alleviate the OP original problem. However, it is a moot point since constructors are not allowed to inherit by design.
: I rarely find the need to have the same number and signature type of : constructors on derived classes - see my other post with the : MyOwnException class deriving from RuntimeException. Sure, but it does get old having to code (with/out aid of tools)
ClassB(String s) { super(s); }
: > : Simplistically, a compiler jobs is to convert your .java source code : > : into JVM compatible byte code. [quoted text clipped - 9 lines] : universal good option available for every java application, and so the : compile will fail with an error. The "surprise" element was for a newbie (like me) to find out s/he been fooled by the compiler in thinking constructors can sometimes be inherited.
.K
Dimitri Maziuk - 25 Oct 2005 00:38 GMT isamura sez: ...
> Inheritance is supposed to promote code resuse (and good design). I will agree that at times it may > be desirable to over-ride a behavior of the super class that is not appropriate, but this does > (should) not happen often. At least not in my "camp". Google for inheritance vs. composition and be enlightened.
> So it was surprising the compiler generates missing default constructors. Not really: there's magic in Object that makes gc work, and that magic needs to be initialized by Object's constructor. So you *have* to generate default constructors in order to guarantee that Object's constructor is executed -- otherwise the JVM might come crashing down 'round your ears.
>: However, most modern IDEs have the ability for you to right click on a >: derive class and over ride as many methods & constructors you'd like, >: with a few mouse clicks. >: > Yes I can see why such a feature is neccessary...<sigh> Yeah. Here's one more: since you can't inherit constructors, you can't do polymorphic construction (i.e. when the type of new object is determined at run-time), so you have to use factories instead. "I can see why factories are necessary...<sigh>"
Dima
 Signature I'm going to exit now since you don't want me to replace the printcap. If you change your mind later, run -- magicfilter config script
Roedy Green - 25 Oct 2005 02:06 GMT >Inheritance is supposed to promote code resuse (and good design). I will agree that at times it may >be desirable to over-ride a behavior of the super class that is not appropriate, but this does >(should) not happen often. At least not in my "camp". The net effect is a subclass constructor typically ADDS to the initialisation of the base case, perhaps overrides, it , but never replaces it. If you decompile, you will always see a chain of constructors getting called, starting with the base.
You get in deep doo do when you start letting constructors call non-final methods that are later overridden. It is legal, but leads to all kinds of bizarre behaviour.
see http://mindprod.com/jgloss/constructor.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Brendan Guild - 25 Oct 2005 00:44 GMT >: Constructors are not inherited. Not ever. The empty constructor >: you mentioned is in fact the default constructor. Any class that [quoted text clipped - 3 lines] > That is interesting. The compiler gives a false sense of > OOness...certainly got me. Inherited constructors aren't especially OO, but they are especially horrible. Very often subclasses will need to do some kind of initialization, perhaps just a single field. Imagine constructors are inherited: Even if you thought you needed to rewrite all 7 constructors for JTable before, now you are really forced to do it.
With inheritence of constructors, exactly duplicating the constructor list of every superclass becomes not a minor annoyance, but a mandatory annoyance, or else you will leave your object uninitialized.
isamura - 25 Oct 2005 03:04 GMT : >: Constructors are not inherited. Not ever. The empty constructor : >: you mentioned is in fact the default constructor. Any class that [quoted text clipped - 13 lines] : list of every superclass becomes not a minor annoyance, but a mandatory : annoyance, or else you will leave your object uninitialized. I don't follow...
If constructors were allowed to inherit then from my previous code example I should be able to intantiate ClassB like:
new ClassB("constructors don't inherit");
without declaring a constructor for ClassB like:
ClassB(String s) { super(s); }
.K
Brendan Guild - 25 Oct 2005 09:30 GMT >: With inheritence of constructors, exactly duplicating the >: constructor list of every superclass becomes not a minor annoyance, [quoted text clipped - 13 lines] > super(s); > } Very often you will not want your constructors to be empty like that because your subclass's constructor has actual work to do. In fact, that is almost always the case.
In that situation you may write whatever constructors you want and make your own decisions about how to initialize your object. If we had constructor inheritence, you would be forced to always 'override' all of the superclass's constructors, whether they are appropriate for your new class or not.
This is especially nasty when the superclass has 7 constructors. Then, if your new class wants to define it's own special constructor, you'll need a total of 8 constructors, and as you go down the hierarchy you will have more and more constructors and every time you extend a class you are forced to override all of them.
Roedy Green - 25 Oct 2005 10:12 GMT >Very often you will not want your constructors to be empty like that >because your subclass's constructor has actual work to do. In fact, >that is almost always the case. Right, nearly always when you extend a class, there are some new instance variables. Under the hood they are initialised by that class's constructors, even if you write the code as declaration line initialisers or { } init code. You can see all this much more clearly in decompiled code where constructors look much more like ordinary methods.
see http://mindprod.com/jgloss/decompiler.html
I suspect much of Java's design was done first with the JVM (Java Virtual Machine), and later the Java language syntax was added as a sort of byte code generator. A more poetic way of saying it is Gosling likely dreams in Byte Code not Java.
see http://mindprod.com/jgloss/constructor.html http://mindprod.com/jgloss/initialisation.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
isamura - 25 Oct 2005 19:28 GMT : >Very often you will not want your constructors to be empty like that : >because your subclass's constructor has actual work to do. In fact, [quoted text clipped - 6 lines] : in decompiled code where constructors look much more like ordinary : methods. I think how "often" depends on how inheritance is used. But I will agree sometimes it does involve new instance variables. In that case, what would the new constructor look like?
ClassB(String s1, String s2) { super(s1); this.s2 = s2; }
or
ClassB(String s1, String s2) { this.s1 = s1; // s1 instance var is inherited from ClassA - this breaks encapsulation this.s2 = s2; }
: see http://mindprod.com/jgloss/decompiler.html : : I suspect much of Java's design was done first with the JVM (Java : Virtual Machine), and later the Java language syntax was added as a : sort of byte code generator. A more poetic way of saying it is Gosling : likely dreams in Byte Code not Java. That's an interesting interpretation ;-)
.K
Hendrik Maryns - 26 Oct 2005 12:57 GMT isamura schreef:
<snipperdiesnip>
> I think how "often" depends on how inheritance is used. But I will agree sometimes it does involve > new instance variables. In that case, what would the new constructor look like? [quoted text clipped - 10 lines] > this.s2 = s2; > } The first, of course. (Imagine you want something to be done with s1 before it gets assigned. You only have to rewrite your ClassA constructor, not both. If you only want something to be done with it in ClassB, you can do super(doSomethingWith(s1)), provided doSomethingWith is static, or super(s1.someConvenientMethod()), which will always work. (I'd discourage using the first option).
<snippo>
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Roedy Green - 25 Oct 2005 10:05 GMT >If constructors were allowed to inherit then from my previous code example I should be able to >intantiate ClassB like: You could also think of it as "IDE, please create a set of constructors for me that just each call the equivalent super for me to get started."
But chances are you would soon throw away the implementations to send them all to YOUR common code init for this level of instance variables that then called the super DEBE constructor.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Roedy Green - 25 Oct 2005 14:34 GMT On Tue, 25 Oct 2005 09:05:55 GMT, Roedy Green <my_email_is_posted_on_my_website@munged.invalid> wrote, quoted or indirectly quoted someone who said :
>But chances are you would soon throw away the implementations to send >them all to YOUR common code init for this level of instance variables >that then called the super DEBE constructor. see http://mindprod.com/jgloss/debe.html
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
zero - 24 Oct 2005 22:40 GMT >> >> I've been listening in with some interest and was hoping to have an [quoted text clipped - 54 lines] > no-argument constructor, because all (non-abstract) classes must have > a constructor. I hope everyone understood that I meant
class ClassB extends ClassA {}
otherwise the example doesn't make much sense :-s
Roedy Green - 25 Oct 2005 02:01 GMT >A quick test show the only constructor that can be inherited is an empty one. For example, That is an illusion. Under the hood, what you are actually inheriting is a default convenience constructor automatically constructed in the absence of other constructors, that CALLs the super constructor. You are not actually inheriting the same constructor the way you do with a method.
see http://mindprod.com/jgloss/gotchas.html#CONSTRUCTORS
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Chris Uppal - 25 Oct 2005 10:37 GMT > So, why can't Java find a matching constructor for new ClassB(s) from > ClassA(String s)? I don't see why the compliler can't translate a missing > constructor to super(s); and try it. As far as I know there is no good reason why Java constuctors don't inherit. From the logical/semantic point of view there doesn't seem to be a problem (after all many OO languages -- including some which are considerably more OO than Java -- have inherited "constructors" and the work perfectly well). From the technical point of view, in terms of how the JVM works, there doesn't seem to be a problem either (it would mean allowing the <init> method to do virtual lookup like most method calls, and it would require some changes to the verifier, but neither looks particularly tricky).
So I think it's just "one of those things"...
As to why Java's designers came up with the notion of constructors that they did; I don't know. My /guess/ is that they were thinking of constructors as being "like" static methods -- and they also don't override.
The Java vision of OO is impure and incomplete.
-- chris
Roedy Green - 25 Oct 2005 14:13 GMT On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
>As far as I know there is no good reason why Java constuctors don't inherit. How about his case?
Dog( int weightInKg );
Dalmatian( int weightInKg, float percentBlack );
In your universe I would be forced to support a constructor
Dalmatian( int weightInKg );
that would force me to allow Dalmatian objects to be created without the Dalmatian colour information.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
isamura - 25 Oct 2005 19:48 GMT : On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal" : <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly [quoted text clipped - 14 lines] : that would force me to allow Dalmatian objects to be created without : the Dalmatian colour information. That may well be the case however the inherited constructor is still valid for Dalmatian. One can over-ride the constructor and provide a default percentBlack value or:
dog = new Dalmatian(20); dog.percentBlack(0.45);
.K
Roedy Green - 26 Oct 2005 01:37 GMT >That may well be the case however the inherited constructor is still valid for Dalmatian. One can >over-ride the constructor and provide a default percentBlack value or: > >dog = new Dalmatian(20); >dog.percentBlack(0.45); However, if you do that you have closed off the ability to demand values in a compile time check of your constructors.
To turn off the unwanted constructor to you have to get it to throw a run-time exception.
Constructors bother me because they have so many warts. Sometimes I say to myself, I wish that new objects were initialised with an ordinary static method called create. That would make understanding constructors much easier. But for day to day cranking out code, it would be tedious.
Note that you could create/initialise all your objects with a static create method which calls a private noarg empty constructor. But no one does. Constructors are the cabbage patch dolls of Java -- ugly but attractive.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Hendrik Maryns - 26 Oct 2005 12:44 GMT isamura schreef:
> : On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal" > : <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly [quoted text clipped - 20 lines] > dog = new Dalmatian(20); > dog.percentBlack(0.45); This will only work if you add Dalmatian in front, not if dog is of type Dog.
But this means you would have to define a method percentBlack which sets the blackness, and is never used afterwards (I don't suppose the blackness of a dalmation changes during his lifetime), very bad practice.
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
isamura - 26 Oct 2005 15:26 GMT "Hendrik Maryns" wrote in message ...
: isamura schreef: : > : On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal" [quoted text clipped - 23 lines] : This will only work if you add Dalmatian in front, not if dog is of type : Dog. Correct. I wasn't aiming to make the code compile :-)
: But this means you would have to define a method percentBlack which sets : the blackness, and is never used afterwards (I don't suppose the : blackness of a dalmation changes during his lifetime), very bad practice. Perhaps, but it is never bad practice to provide accessor methods for instance/class variables.
.K
Hendrik Maryns - 27 Oct 2005 11:14 GMT isamura schreef:
<snip>
> : But this means you would have to define a method percentBlack which sets > : the blackness, and is never used afterwards (I don't suppose the > : blackness of a dalmation changes during his lifetime), very bad practice. > : > Perhaps, but it is never bad practice to provide accessor methods for instance/class variables. That depends on what those variables represent. I would not easily provide an accessor which returns an internal HashMap or anything that stores objects, as that way you allow the user to change your internal data. At least a copy of the HashMap should be returned. Just so, it is useless to provide setters for final variables etc. Or you might want that some variables are only altered in a specific way, then there is no need for a general set method which just assigns the parameter. For example I might have a boolean which is initially false can be set to true, but never to false again. Then I will have the method
void bind(){ bound = true; }
Or even better, I have a _private_ set method, and bind looks like this:
void bind(){ setBound(true); }
And I can use setBound in my constructor too (though not necessary because of default initialisation).
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
isamura - 27 Oct 2005 21:36 GMT : isamura schreef: : [quoted text clipped - 24 lines] : setBound(true); : } Yes this is better. Also by specifying private void bind(); you limited the scope of the setter to the owning class. The same could be said for an accessor to your HashMap. _private_ methods are not visible outside the owning class, if I am not mistaken.
: And I can use setBound in my constructor too (though not necessary : because of default initialisation). This sound strange to me from an OO perspective. By definition constructors are static (class methods), yet they can see instance variables and instance methods. However, "normal" static methods can't (and shouldn't). It seems to be a contradiction and yet it works.
.K
Andrew McDonagh - 27 Oct 2005 22:33 GMT > : isamura schreef: > : [quoted text clipped - 28 lines] > to the owning class. The same could be said for an accessor to your HashMap. _private_ methods are > not visible outside the owning class, if I am not mistaken. Just wanted to clarify something for you - as I'm can't make out form the words you used, if you know or not....
Private methods and member vars of a class ARE visible to ALL instances of the class - not just a single instance.
so this works...
public class Foo {
private boolean aPrivateMethod() { return true; }
public boolean equals(Object obj) { Foo other = (Foo)obj;
return other.aPrivateMethod(); }
}
Its weird to me, and yet it also makes sense... ;-)
isamura - 28 Oct 2005 02:00 GMT : > : isamura schreef: : > : [quoted text clipped - 52 lines] : : Its weird to me, and yet it also makes sense... ;-) Hmmm, this actually makes sense to me since you are accessing the private method from within the same class (and instances). There shouldn't be any access violations here.
I wonder if the following would work:
public class Bar {
public boolean testWithFooPrivate() { Foo other = new Foo(); return other.aPrivateMethod(); } }
My understanding so far is that it won't compile, otherwise what is the point of declaring _private_ anything?
.K
Hendrik Maryns - 28 Oct 2005 11:46 GMT isamura schreef:
> : > : isamura schreef: > : > : [quoted text clipped - 68 lines] > } > }
> My understanding so far is that it won't compile, otherwise what is the point of declaring _private_ > anything? Why didn't you test? Of course it won't compile.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Chris Uppal - 28 Oct 2005 10:21 GMT > By definition > constructors are static (class methods), yet they can see instance > variables and instance methods. Technically constructors are neither instance methods nor static methods, they are a third category of code with their own rules. Semantically they are closer to instance methods than to static methods since they have a "this". In implementation terms they are actually instance methods of a special kind (treated specially by the compiler, the verifier, and the JVM). When a new object is created, the JVM first allocates its memory, setting all values to their defaults, and then invokes the constructor "method" on that object, that means that the code has a valid "this" when it runs.
(BTW you sound as if you are coming from a Smalltalk backgound here -- or some language that is very Smalltalk like in its semantics -- if so then it may help to think of Java's constructors as not being like the class-side factory method #new, but as being the equivalent of the instance-side #initialise method that is (conventionally) invoked by the #new method before it returns.)
> However, "normal" static methods can't > (and shouldn't). It seems to be a contradiction and yet it works. Actually, they can. A static method can access the private members of any of that class's instances.
-- chris
isamura - 28 Oct 2005 16:42 GMT : > By definition : > constructors are static (class methods), yet they can see instance [quoted text clipped - 8 lines] : their defaults, and then invokes the constructor "method" on that object, that : means that the code has a valid "this" when it runs. I stand corrected.
: (BTW you sound as if you are coming from a Smalltalk backgound here -- or some : language that is very Smalltalk like in its semantics -- if so then it may help : to think of Java's constructors as not being like the class-side factory method : #new, but as being the equivalent of the instance-side #initialise method that : is (conventionally) invoked by the #new method before it returns.) You've found me out! I thought your name looked familiar.
: > However, "normal" static methods can't : > (and shouldn't). It seems to be a contradiction and yet it works. : : Actually, they can. A static method can access the private members of any of : that class's instances. Perhaps I should drop the notion that static methods are analogous to class methods. And that class methods don't exist in Java. Do correct me if I am mistaken.
.K
Chris Uppal - 29 Oct 2005 14:52 GMT > Perhaps I should drop the notion that static methods are analogous to > class methods. And that class methods don't exist in Java. Do correct me > if I am mistaken. Well, I suggest a bit of both.
One the one hand, Java's classes are nothing like Smalltalk classes. In Java a class is not an object, it is only a language construct. So many of the things that you would naturally use a class object for in Smalltalk just don't make sense in Java. E.g. you can't use a class as a factory object -- if you need/want to use that pattern then you have to code up all the necessary stuff yourself. As a result, all the "static" stuff has a semantics that will seem unfamiliar to a Smalltalker -- "static" is not equivalent to Smalltalk's "class side".
On the other hand, within fairly wide limits, Java's static members are used in just the same way as Smalltalk's class-side method and classvars / class instvars. Most, probably all, of the reasons for putting code on the class side in Java would be equally valid in Smalltalk (the reverse is not always true, since Java classes are not objects). So, more often than not, the thinking is exactly the same. In fact I like to "pretend" that Java's classes /are/ objects (distinct from their instances) when I'm deciding where to put code -- decide which "object" is responsible for <whatever> and put the code on the appropriate side of the fence.
Put it like this: it's perfectly reasonable to say that "static methods are analogous to class methods", /provided/ that you hear in mind that the analogy is rather loose and incomplete.
-- chris
isamura - 30 Oct 2005 22:50 GMT : > Perhaps I should drop the notion that static methods are analogous to : > class methods. And that class methods don't exist in Java. Do correct me [quoted text clipped - 10 lines] : unfamiliar to a Smalltalker -- "static" is not equivalent to Smalltalk's "class : side". This does explain why it is not possible to assign the actual "class" to a variable and use it else where to declare the type of variables and instances. For example,
Class c = ClassA; .... c cInstance = new c(); ...
is unsupported.
: On the other hand, within fairly wide limits, Java's static members are used in : just the same way as Smalltalk's class-side method and classvars / class [quoted text clipped - 9 lines] : analogous to class methods", /provided/ that you hear in mind that the analogy : is rather loose and incomplete. Agreed. I am finding that I can't simply "map" Smalltalk concepts to Java without (in specific cases) working around limitations/restrictions. It can be frustrating but is a good learning experience in any case.
.K
Chris Uppal - 31 Oct 2005 10:11 GMT [me:]
> Agreed. I am finding that I can't simply "map" Smalltalk concepts to Java > without (in specific cases) working around limitations/restrictions. It > can be frustrating but is a good learning experience in any case. Sympathy ;-)
Same with learning any new language, the sooner you can stop thinking in OLD while programming in NEW the easier it'll be and the less mess you'll create.
(I remember getting into something of a mess programming in C++ but thinking in Java. I had known C++ for years, but had just started in Java and was very enthusiastic about its way of doing things. Fortunately I had not yet discovered Smalltalk at the time, or I would probably have created total havoc ;-)
-- chris
Roedy Green - 31 Oct 2005 11:43 GMT >Agreed. I am finding that I can't simply "map" Smalltalk concepts to Java without (in specific >cases) working around limitations/restrictions. It can be frustrating but is a good learning >experience in any case. The tendency is to try to figure out how you can get the same effect you are used to in the new language. This will drive you nuts since it will be absurdly clumsy. What you have to do is look for code that tackles the same sort of problems you want to solve and see which tools they are using.
At the very least, make sure you understand the tools that everyone seems to be talking about a lot.
These are the starting toolkit.
My problem with Java was coming from a MASM, FORTH, Abundance, C++ background, I tend to think in very low level terms what I want to accomplish. To me the language was just a sort of shorthand for getting the effects I wanted. But in Java the low levels simply are not accessible at all and nobody ever talks about how things are implemented. I had no model to hang my understanding of Java on without that.
Often I felt like a monkey in cage reaching for bananas just out of my reach when all I wanted the fool thing to do was generate some sequence of three machine instructions.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
isamura - 31 Oct 2005 20:01 GMT : >Agreed. I am finding that I can't simply "map" Smalltalk concepts to Java without (in specific : >cases) working around limitations/restrictions. It can be frustrating but is a good learning [quoted text clipped - 5 lines] : tackles the same sort of problems you want to solve and see which : tools they are using. Both you and Chris U. made good points. I am glad to hear others have had similar experience.
.K
Roedy Green - 29 Oct 2005 15:30 GMT On Fri, 28 Oct 2005 10:21:34 +0100, "Chris Uppal" <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly quoted someone who said :
>When a new >object is created, the JVM first allocates its memory, setting all values to >their defaults, and then invokes the constructor "method" on that object, that >means that the code has a valid "this" when it runs. by defaults I presume you mean 0 rather than the
int q = 7;
value.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Andrew McDonagh - 29 Oct 2005 19:53 GMT > On Fri, 28 Oct 2005 10:21:34 +0100, "Chris Uppal" > <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly [quoted text clipped - 10 lines] > > value. correct
Hendrik Maryns - 28 Oct 2005 11:47 GMT isamura schreef:
> : isamura schreef: > : [quoted text clipped - 28 lines] > to the owning class. The same could be said for an accessor to your HashMap. _private_ methods are > not visible outside the owning class, if I am not mistaken. I'm sorry for the confusion, but I meant the two above methods to be public. Only setBound is private. That way _I_ can change the bound wherever I want inside the class, without relying on the representation (i.e. if I change the representation of the binding to an int later on or whatever, I can redefine setBound and don't have to replace every bound = false in my file), and I restrict the options I give the user of the class by offering him only the bind method, which works unidirectional. (In case anyone is wondering, this is part of a class Variable, which represents a variable in a logical formula. Once it is bound, it cannot be unbound.)
> : And I can use setBound in my constructor too (though not necessary > : because of default initialisation). > : > This sound strange to me from an OO perspective. By definition constructors are static (class > methods), yet they can see instance variables and instance methods. However, "normal" static methods > can't (and shouldn't). It seems to be a contradiction and yet it works. In Java, constructors are not static, they work on an instance which is already created by new, they only do the initialisation. That way it makes sense they know about instance variables.
H.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Andrew McDonagh - 25 Oct 2005 21:02 GMT > On Tue, 25 Oct 2005 10:37:42 +0100, "Chris Uppal" > <chris.uppal@metagnostic.REMOVE-THIS.org> wrote, quoted or indirectly [quoted text clipped - 14 lines] > that would force me to allow Dalmatian objects to be created without > the Dalmatian colour information. No it wouldn't.
The rules governing Virtual constructors is the same for Virtual methods - over ride if you want/need to.
In your case, if the base class constructor: Dalmatian( int weightInKg ) was called, then the 'percentBlack' member field would be un-initialised thats all.
Roedy Green - 26 Oct 2005 01:38 GMT On Tue, 25 Oct 2005 21:02:03 +0100, Andrew McDonagh <news@andrewcdonagh.f2s.com> wrote, quoted or indirectly quoted someone who said :
>In your case, if the base class constructor: Dalmatian( int weightInKg ) >was called, then the 'percentBlack' member field would be un-initialised >thats all. That's my complaint. You don't want a security hole like that, creating invalid Dalmatian objects.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
isamura - 25 Oct 2005 19:41 GMT : > So, why can't Java find a matching constructor for new ClassB(s) from : > ClassA(String s)? I don't see why the compliler can't translate a missing [quoted text clipped - 10 lines] : : So I think it's just "one of those things"... I don't know enough about the JVM internals but suspect the same.
: As to why Java's designers came up with the notion of constructors that they : did; I don't know. My /guess/ is that they were thinking of constructors as : being "like" static methods -- and they also don't override. Can you clarify. Do you mean subclass can't inherit static methods either?
.K
Andrew McDonagh - 25 Oct 2005 21:04 GMT snipped.
> Can you clarify. Do you mean subclass can't inherit static methods either? > > ..K Correct.
Static methods don't belong to an object like normal (aka Instance) methods, they belong to the Class.
When calling a static method you: 'Class.myStaticMethod()'
there's no object, so no Vtable to use to look through.
Andrew
isamura - 25 Oct 2005 22:57 GMT "Andrew McDonagh" wrote...
: snipped. : [quoted text clipped - 10 lines] : : there's no object, so no Vtable to use to look through. This is going off-topic so I will change the thread topic.
That is puzzling since the following compiles and runs (JDK 1.42):
public static myStaticMethod(); // defined in ClassA
ClassB extends ClassA
ClassB.myStaticMethod(); // no problem
Please explain...
.K
Roedy Green - 26 Oct 2005 01:49 GMT >ClassB extends ClassA > >ClassB.myStaticMethod(); // no problem at the JVM level, that compiles as invokeStatic ClassA.myStaticMethod. Allowing you to be sloppy with which level a static came from is just a convenience of the Java language/javac.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
isamura - 26 Oct 2005 03:24 GMT : >ClassB extends ClassA : > [quoted text clipped - 3 lines] : Allowing you to be sloppy with which level a static came from is just : a convenience of the Java language/javac. (Argh!) I was afraid you might say that...another compiler illusion...
This is not a convenience, more like mud-patch which adds more to the confusion of an overly complex language. I wonder if I should just throw in the towel now.
.K
Roedy Green - 26 Oct 2005 06:30 GMT >This is not a convenience, more like mud-patch which adds more to the confusion of an overly complex >language. I wonder if I should just throw in the towel now. The really ugly compiler illusion is myObject.myStaticMethod().
Boy is that confusing! However it has some maintenance advantages.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Eike Preuss - 26 Oct 2005 09:58 GMT >>This is not a convenience, more like mud-patch which adds more to the confusion of an overly complex >>language. I wonder if I should just throw in the towel now. > > The really ugly compiler illusion is myObject.myStaticMethod(). Oh, yes, I agree. myObject.myStatic() and ClassBThatExtendsClassA.classAStatic() are absolutely !ยง&%!
> Boy is that confusing! However it has some maintenance advantages. Don't state that without explaining :) It would be nice to know of _any_ justification of the stuff above...
++ Eike
Roedy Green - 26 Oct 2005 11:33 GMT >> Boy is that confusing! However it has some maintenance advantages. >> >Don't state that without explaining :) >It would be nice to know of _any_ justification of the stuff above... Let say you wrote some code like this Dog pepe = new Dog( 1.5 /* kg */ ); Dog.register( pepe );
If you wrote that code using the compiler illusion, like this:
Dog pepe = new Dog( 1.5 /* kg */ ); pepe.register( pepe );
Now we add the Chihuahua class, and a new static method that registers the dog both at city hall and with the Chihuahua association.
I modify the code: Chihuahua pepe = new Chihuahua( 1.5 /* kg */ ); pepe.register( pepe );
The register method will automatically choose Chihuahua.register if there is such a thing or Dog.register if there is not. I don't have to manually maintain it. I only have to specify that pepe is a Chihuahua in one place.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Eike Preuss - 26 Oct 2005 13:33 GMT >>>Boy is that confusing! However it has some maintenance advantages. >> [quoted text clipped - 22 lines] > manually maintain it. I only have to specify that pepe is a Chihuahua > in one place. Hm, I see. But doesn't the fact that you would have to manually change 'Dog' to 'Chihuahua' point to a design quirk: That you shouldn't use a static method but an instance method that can be inherited (and overwritten)? So, I'm sorry that myObject.staticMethod() still doesn't make sense to me...
Another question: If the compiler replaces ClassB.staticDefinedInClassA() by ClassA.staticDefinedInClassA() what is the point in not inheriting static methods through subclasses??? If you don't inherit, you can write ClassB.staticDefinedInClassA() but you won't get the method via reflection of ClassB since ClassB.class.getMethods() won't return it and ClassB.class.getDeclaredMethods() neither. You save the method lookup for static methods, ok, but is there somethings else I'm missing?
Roedy Green - 26 Oct 2005 23:29 GMT >Hm, I see. But doesn't the fact that you would have to manually change >'Dog' to 'Chihuahua' point to a design quirk: That you shouldn't use a >static method but an instance method that can be inherited (and >overwritten)? That is beside the point I was trying to make. IF you have such a static method, then the compiler illusion helps you deal with it.
I will leave it up to someone else do decide if there are cases where static methods should ever legitimately be shadowed. In any case the language, allows it, so with complete certainty you will encounter the such methods. .
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
isamura - 27 Oct 2005 05:44 GMT [snip]
: Another question: If the compiler replaces : ClassB.staticDefinedInClassA() by ClassA.staticDefinedInClassA() what is [quoted text clipped - 4 lines] : ClassB.class.getDeclaredMethods() neither. You save the method lookup : for static methods, ok, but is there somethings else I'm missing? As you have pointed out Reflect
|
|