From: Lew on 12 Feb 2010 17:05 mscottschilling(a)hotmail.com says... >>>> Suppose the call to "super()" needn't be the first line of a constructor. >>>> Discuss the effect and/or legality of the following code: >>>> >>>> class MyClass extends YourClass >>>> { >>>> public MyClass(int i) >>>> { >>>> if ( i > 0) >>>> { >>>> super(i); >>>> } >>>> } >>>> ... Pitch wrote: >>> If you look at super() as just another method call it's perfectly ok. Lew wrote: >> Constructor calls are not method calls. So that won't work. Pitch wrote: > No it won't, but if is was a method it would. If it was a method none of this thread would have happened. This entire discussion is about constructors, not methods. -- Lew
From: Lew on 12 Feb 2010 17:13 Pitch wrote: > class A > { > private String data = getData(); You shouldn't call overridable methods from a constructor. This would not change even with the ability to put calls before 'super(...)'. > protected void getData() > { > return "A"; > } > } > > class B extends A > { > private String newData = "unknown"; > > public B(String data) > { > newData = data; > } > > protected String getData() > { > return newData; > } > } > > When you instantate an object of type B, field A.data will be "unknown" > instead of intended value "A". So the author of class A has allowed the > subclass to change the behaviour of the superclass initailization. Exactly why you aren't supposed to do that sort of thing. Again, putting code before 'super(...)' would only exacerbate that problem, as your second example shows. > Woudn't it be simpler to put it like this: > > class B extends A > { > private String newData = "unknown"; > > public B(String data) > { > newData = data; > super(); > } > > protected String getData() > { > return newData; > } > } No. You haven't improved anything. The subclass override still changes the behavior of the superclass constructor. Now you are using the subclass to alter what should have been an invariant in the superclass, the allocation of the superclass's private field. Either way you look at it, it's a Bad Idea. -- Lew
From: Pitch on 12 Feb 2010 19:17 In article <hl4729$j8s$1(a)news.eternal-september.org>, mscottschilling(a)hotmail.com says... > > Pitch wrote: > > In article <hl1ban$hes$1(a)news.eternal-september.org>, > > mscottschilling(a)hotmail.com says... > >> > >> Pitch wrote: > >>> In article <hkvi82$usn$1(a)news.eternal-september.org>, > >>> mscottschilling(a)hotmail.com says... > >>>> > >>>> Suppose the call to "super()" needn't be the first line of a > >>>> constructor. Discuss the effect and/or legality of the following > >>>> code: > >>>> > >>>> class MyClass extends YourClass > >>>> { > >>>> public MyClass(int i) > >>>> { > >>>> if ( i > 0) > >>>> { > >>>> super(i); > >>>> } > >>>> } > >>>> ... > >>> > >>> If you look at super() as just another method call it's perfectly > >>> ok. > >> > >> But it isn't "just another method call", which is the point of the > >> example. It's the call that guarantees that the superclass, starting > >> from a completely uninitialized state, has been fully initialized. > >> It needs to be called precisely once, and that needs to be done > >> before any instance methods are called or instance fields accessed. > > > > > > I though we are talking about changes in the language so it doesn't > > mater if it's not a method right now, or if it's allowed only once to > > be called. If we are talking of possible changes to Java it could be > > just another method and it could be called more than once, ok? > > > > In that case your example works perfectly ok. > > As I explained above, it breaks all guarantees about class construction. > That's a bad thing. Well, I keep talking hypothetically and you keep sticking with Java. Nevermind. -- stirr your cofee properly
From: Pitch on 12 Feb 2010 19:38 In article <hl424b$l5t$1(a)news-int.gatech.edu>, Pidgeot18(a)verizon.invalid says... > > Of course. I don't think this can be changed, I just want people to > > agree this restricton should have not be introduced at all. > > Even C++ requires that superconstructors be called before the > constructor executes (although it does permit you to wrap the whole > initializer in a try-catch block, which was incidentally the feature > that originally prompted this IIRC). I belive Java picked it up from C. > I can't think of a language which treats constructors as regular > methods. Delphi has virtual constructors but bas class TObject has a non-virtual empty destructor which you cannot override. In the other thread I mentioned some .NET languages have this rule, but some don't like VB.NET, and the compiled code is interchangeable. It is perfectly ok to use a class with such loose constructor in C# e.g. > It is a very sensible restriction, and the expectation by programmers > coming from other languages is that it will be. Constructors have the > notion of actually reserving the memory space and then initializing it > at the same time--hence we have the `new' keyword and the actual > constructor call. If you were to separate the memory space reservation > and initialization out, then it would make sense to allow constructors > to be called multiple times. But Java doesn't allow you to do so, so the > point is moot. I belive we have three steps in object construction: memory allocation (new), member initialization, and constructor body execution. Keyword new is also used in allocating structures bz name or by a pointer. I can also add that memory allocation means the object is alive at that moment we have a refetence to this. After is only language specific implementation. -- stirr your cofee properly
From: Pitch on 12 Feb 2010 19:43
In article <hl4jr2$g36$1(a)news.albasani.net>, noone(a)lewscanon.com says... > > Pitch wrote: > > class A > > { > > private String data = getData(); > > You shouldn't call overridable methods from a constructor. > > This would not change even with the ability to put calls before 'super(...)'. > > > protected void getData() > > { > > return "A"; > > } > > } > > > > class B extends A > > { > > private String newData = "unknown"; > > > > public B(String data) > > { > > newData = data; > > } > > > > protected String getData() > > { > > return newData; > > } > > } > > > > When you instantate an object of type B, field A.data will be "unknown" > > instead of intended value "A". So the author of class A has allowed the > > subclass to change the behaviour of the superclass initailization. > > Exactly why you aren't supposed to do that sort of thing. Again, putting code > before 'super(...)' would only exacerbate that problem, as your second example > shows. I just wanted to show it is possible in Java to call a method of an object which is not fully initialized. Why doesn't complier warn about that? (it's rethorical) I guess, as Patricia has put it, the rope is too long in this case. Anyway, I give up. Since there are so many issues concerning a simple constructor execution, the best way has to be the one we have. And sorry all if my English was confusing. Godd bless you and Metallica sucks :) EOD -- stirr your cofee properly |