digitalmars.D.learn - how to change attribute in descendant?
- novice2 (50/50) Jan 18 2007 Hello.
- Pragma (47/56) Jan 18 2007 It's funny you post this now. I had a co-worker who had the same exact ...
- =?UTF-8?B?SmFyaS1NYXR0aSBNw6RrZWzDpA==?= (16/19) Jan 18 2007 Eric, do you happen to know, if it's possible to do the opposite - i.e.
- Pragma (19/42) Jan 18 2007 (I'm assuming that you're coming from a novice background here - my apol...
- =?UTF-8?B?SmFyaS1NYXR0aSBNw6RrZWzDpA==?= (43/75) Jan 18 2007 Sorry - the question was a bit naive. What I meant was that why isn't it
- Jarrett Billingsley (8/10) Jan 18 2007 Since the spec never says anything about protection on base
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (9/21) Jan 18 2007 They have been a very long time there. I suppose Walter has copied them
- novice (3/4) Jan 18 2007 methods can. Even though the compiler lets you do this:
- %u (23/24) Jan 18 2007 This seems to be a clear sign of misunderstanding/misusing object orient...
- Jarrett Billingsley (6/13) Jan 18 2007 OT: Mr/s. %u, would you please, please use a newsreader? There is a bug...
Hello. I need declare some base class A with general functionality, then more special descendants AA and AB. "A" class have some fields, that i don't want "show", i make it protected. Then in some descendant i need "open" it. I need change it from "protected" to "public". In Delphi i just redeclare it in descendant, but in "public" section. Delphi allow change visibility of class members from low to higher. Private->protected->public. How i can do this in D? /********* test.d ********/ import std.stdio; //base class with general code abstract class Animal { protected int legsCount; protected int poisonStrength; public bool canWalk() { return legsCount>0; } public bool canKill() { return poisonStrength>0; } } //tiger = animal with legs without poison class Tiger : Animal { public int legsCount; } //snake = animal without legs with poison class Snake : Animal { public int poisonStrength; } void main() { Tiger t = new Tiger; t.legsCount = 4; writefln("tiger: legs=%d, canWalk=%d, canKill=%d", t.legsCount, t.canWalk, t.canKill); Snake s = new Snake; s.poisonStrength = 100; writefln("snake: poison=%d, canWalk=%d, canKill=%d", s.poisonStrength, s.canWalk, s.canKill); } output: tiger: legs=4, canWalk=0, canKill=0 snake: poison=100, canWalk=0, canKill=0
Jan 18 2007
novice2 wrote:Hello. I need declare some base class A with general functionality, then more special descendants AA and AB. "A" class have some fields, that i don't want "show", i make it protected. Then in some descendant i need "open" it. I need change it from "protected" to "public". In Delphi i just redeclare it in descendant, but in "public" section. Delphi allow change visibility of class members from low to higher. Private->protected->public.It's funny you post this now. I had a co-worker who had the same exact same problem in Java yesterday. :) In short: fields cannot be overridden in the same way that methods can. Even though the compiler lets you do this: class A{ char[] name = "Class A"; } class B:A{ char[] name = "Class B"; } ... it is considered bad form. Avoid doing this if you can. A matching member name, instead of overriding the declaration within the super-class, subtly *masks* the super-class' declaration instead. Technically, both fields co-exist, side-by-side. This is because the compiler treats all member declarations the same, regardless if they match a super-class' member name (regardless of type). Obviously, this can become very confusing: void main(){ A a = new A(); B b = new B(); writefln("A: %s",a.name); // prints: Class A writefln("B: %s",b.name); // prints: Class B writefln("B: %s",(cast(A)b).name); // prints: Class A <-- A.name is still there, and is not overridden } The way to fix this is pretty straightforward. Just use one field only for any such purpose: class A{ char[] name; this(){ name = "Class A"; } } class B:A{ this(){ name = "Class B"; } } This way, every 'A' and every subclass of 'A' will have the same 'name' field. It then down to each subclass to change the value of 'name' as is appropriate. In the case of your program, where you try to 'open' things up as you go down the hierarchy, you can do something like this: class A{ private char[] myName; protected char[] name(){ return myName; } this(){ myName= "Class A"; } } class B:A{ public char[] name(){ return myName; } this(){ myName= "Class B"; } } Again, since only methods can be overridden, this is the only way to go. This example also demonstrates D's property syntax, which is a nice concession for situations like this. Try using this snippet with the "void main()" snippet above. :) -- - EricAnderton at yahoo
Jan 18 2007
Pragma wrote:This example also demonstrates D's property syntax, which is a nice concession for situations like this. Try using this snippet with the "void main()" snippet above. :)Eric, do you happen to know, if it's possible to do the opposite - i.e. make public methods private by using private/protected inheritance? The spec says (http://www.digitalmars.com/d/class.html): InterfaceClass: Identifier Protection Identifier Protection: private package public export But what does it mean? I've asked this a few times before (nobody answered). The compiler just bypasses the protection attributes. I think other than public inheritance is anyway bad in D, especially when the protection is used with interfaces.
Jan 18 2007
Jari-Matti Mäkelä wrote:Pragma wrote:(I'm assuming that you're coming from a novice background here - my apologies if this is not the case) Sadly the documentation is kind of in an "expert mode" state at the moment. In many places, it assumes that you're already familiar with C++ or Java - most of us here are, so we mentally fill in these gaps without realizing they're missing! *ahem* anyway, the protection attributes break down like so: public - accessible by all protected - accessible by the declaring scope and any scopes that inherit it private - only accessible by the declaring scope package - accessible by all, *within the same package* export - accessible by external programs and libraries (it's of out of place in this discussion) ...where a scope is a module, interface, class or struct. Well one thing that isn't illustrated in the grammar (quoted above) is that 'public' is implied for anything accessed from within the same module - perhaps this is what you're seeing when the compiler 'bypasses' things? You have to break your classes and interfaces out into distinct files for these attributes to be enforced as you'd expect. While I know this seems odd, it's much better than what Java or C++ would have to do to achieve the same effect. From the perspective of someone (me) who writes libraries in D, it's a help and not a hindrance. -- - EricAnderton at yahooThis example also demonstrates D's property syntax, which is a nice concession for situations like this. Try using this snippet with the "void main()" snippet above. :)Eric, do you happen to know, if it's possible to do the opposite - i.e. make public methods private by using private/protected inheritance? The spec says (http://www.digitalmars.com/d/class.html): InterfaceClass: Identifier Protection Identifier Protection: private package public export But what does it mean? I've asked this a few times before (nobody answered). The compiler just bypasses the protection attributes. I think other than public inheritance is anyway bad in D, especially when the protection is used with interfaces.
Jan 18 2007
Pragma kirjoitti:Jari-Matti Mäkelä wrote:Sorry - the question was a bit naive. What I meant was that why isn't it working.Eric, do you happen to know, if it's possible to do the opposite - i.e. make public methods private by using private/protected inheritance? The spec says (http://www.digitalmars.com/d/class.html): InterfaceClass: Identifier Protection Identifier Protection: private package public export But what does it mean? I've asked this a few times before (nobody answered). The compiler just bypasses the protection attributes. I think other than public inheritance is anyway bad in D, especially when the protection is used with interfaces.(I'm assuming that you're coming from a novice background here - my apologies if this is not the case)...where a scope is a module, interface, class or struct. Well one thing that isn't illustrated in the grammar (quoted above) is that 'public' is implied for anything accessed from within the same moduleYes.- perhaps this is what you're seeing when the compiler 'bypasses' things?No. You see, if I read and quess the grammar correctly, some of this should work: module aaa; interface A { public void a(); // the public is of course implied here } class B { public void b() { } } --- module bbb class C : private A, private B // the problem is this part of the grammar { private void a() { } } --- module ccc void main() { auto a = new C(); a.a(); // should raise a compile time error ? a.b(); // should raise a compile time error } --- Here's the same code in standard C++ and it correctly raises a compile time error: #include <stdio.h> class A { public: void a() { printf("hello"); } }; class B: private A { }; int main() { B *b = new B(); b->a(); return 0; }You have to break your classes and interfaces out into distinct files for these attributes to be enforced as you'd expect.But it doesn't help.
Jan 18 2007
"Jari-Matti Mäkelä" <jmjmak utu.fi.invalid> wrote in message news:eooa7j$1bie$1 digitaldaemon.com...Sorry - the question was a bit naive. What I meant was that why isn't it working.Since the spec never says anything about protection on base classes/interfaces, and since it's been asked about many times, I guess it's one of two things: (1) a vestige from a long, long time ago when these were planned to work, but were never implemented, or (2) just there for future expansion. It'd be interesting to see what code is there for it in the compiler frontend.
Jan 18 2007
Jarrett Billingsley kirjoitti:"Jari-Matti Mäkelä" <jmjmak utu.fi.invalid> wrote in message news:eooa7j$1bie$1 digitaldaemon.com...They have been a very long time there. I suppose Walter has copied them from the C++ spec and forgotten a bit later. I don't mind even if D won't support them, since Java also has plain public inheritance and it's still usable as a language. Most of the information hiding can be done by abstracting the classes more. Private inheritance at least might cause some odd corner cases on runtime when used in conjunction with the implicit friend syntax within the same module and interfaces.Sorry - the question was a bit naive. What I meant was that why isn't it working.Since the spec never says anything about protection on base classes/interfaces, and since it's been asked about many times, I guess it's one of two things: (1) a vestige from a long, long time ago when these were planned to work, but were never implemented, or (2) just there for future expansion. It'd be interesting to see what code is there for it in the compiler frontend.
Jan 18 2007
== Quote from Pragma (ericanderton yahoo.removeme.com)'s articleIn short: fields cannot be overridden in the same way thatmethods can. Even though the compiler lets you do this: Thank you for explanation. Delphi ability knowing confuse me.
Jan 18 2007
novice2 Wrote:Then in some descendant i need "open" it.This seems to be a clear sign of misunderstanding/misusing object orientation. Descendendants, as you say, need to be like ancestors without any restrictions. Thus there cannot be any need to "open" any closed "attributes". IMO you mean something like this: class Animal{ Attribute walk=null, kill=null; bool canWalk(){ return walk !is null;} bool canKill(){ return kill !is null;} } class Tiger:Animal{ this(){ walk= new Walk(4);} } class Walk:Attribute{ int legs; this( int count){ legs= count; }; } class Attribute{} void main(){ Tiger t= new Tiger; writefln( t.walk.legs, t.canWalk, t.canKill); ...
Jan 18 2007
"%u" <u infearof.spm> wrote in message news:eop4o3$2mq1$1 digitaldaemon.com...novice2 Wrote:OT: Mr/s. %u, would you please, please use a newsreader? There is a bug in the web interface which messes up your name when you post, and it's really disconcerting not knowing your name (and indeed, whether or not all the posts by %u are by the same author).Then in some descendant i need "open" it.This seems to be a clear sign of misunderstanding/misusing object orientation. Descendendants, as you say, need to be like ancestors without any restrictions. Thus there cannot be any need to "open" any closed "attributes".
Jan 18 2007