SitePoint Sponsor

User Tag List

Page 2 of 4 FirstFirst 1234 LastLast
Results 26 to 50 of 85
  1. #26
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    Attributes should be as private as possible and methods should be as public as possible.
    This is absolutely true.
    The reason is, that later you can always change the implementation of a given method, without rearranging all the code.

  2. #27
    SitePoint Zealot Mau's Avatar
    Join Date
    Jan 2006
    Location
    California, USA
    Posts
    134
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by REMIYA View Post
    Actually the first class you have put as an example is a bad implementation
    Yes, exactly as I said!

  3. #28
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    Dudes, learn OOP. Keyword: encapsulation. Attributes should be as private as possible and methods should be as public as possible.
    Did you fall asleep before getting to the Polymorphism chapter? How do you redeclare the same attributes in the subclass? You might need to do this to give an attribute in the subclass a different default value.

    In OOP this is called overriding. You can declare you attributes private only if you are psychic, do not support inheritance or you are some kind of mad scientist that uses an artificial language just to make a point.

  4. #29
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by phpimpact View Post
    Did you fall asleep before getting to the Polymorphism chapter? How do you redeclare the same attributes in the subclass? You might need to do this to give an attribute in the subclass a different default value.

    In OOP this is called overriding. You can declare you attributes private only if you are psychic, do not support inheritance or you are some kind of mad scientist that uses an artificial language just to make a point.
    If you're going to give it a different default value, you should run the setter function in the constructor of the new subclass. It's not much harder than that.

    Never set the default value at the same time as declaration. Do it in the constructor. Always. The object should only be considered fully instantiated once the constructor has run anyways.

  5. #30
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    That sounds a bit odd too, although slightly better than the PHP way.
    Ruby has a few idiosyncrasies like that; having 0 evaluate to true (rather than false) is another. But having private available to subclasses makes more sense anyway.

    Quote Originally Posted by kyberfabrikken View Post
    I'm some times missing a friend access modifier. This would allow you to expose members, but only to a certain number of classes. That would be quite useful, if you use a lot of aggregation.
    I don't know, I've always thought that over reliance on "friend" can lead to hard to maintain code.


    Quote Originally Posted by kyberfabrikken View Post
    Ruby does another thing though, which is very nifty; It makes all properties protected, and only allows you to expose methods. This is something, which is clever to enforce at the language level. In contrast, PHP makes all properties public by default.
    Ruby also makes it trivial to add getters and setters, so there's no reason to make properties public anyway.

  6. #31
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    I don't know, I've always thought that over reliance on "friend" can lead to hard to maintain code.
    If the alternative was public, I think it would be preferable. I'm not sure though. Right now, I just end up with a lot of public functions and a lot of protected attributes, and frankly it doesn't bother me too much. The friend accessor has another problem associated with it, in that it would tend to create concrete class dependencies (Unless a friend could be an interface).
    All very theoretical -- I'm not at all suggesting, that this should be introduced into PHP at this point. That would just serve to further muddle things.

  7. #32
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    Dudes, learn OOP. Keyword: encapsulation. Attributes should be as private as possible and methods should be as public as possible.
    Nonononono!

    The principle is actually very easy:

    1. The objects are defined by their behavior.
    2. The behavior is defined by actions the objects can perform.
    3. Those actions are defined with the methods that can be called by other objects.
    4. Only those methods should be "public" (i.e. callable from outside).
    5. Everything else (attributes or objects) should be "private" (i.e. only callable/visible/modifiable from inside).

    And once again, the inheritance rights should be at least completely separate from access rights, and ideally they should be restricted in no way -- a subclass should automatically inherit everything the parent class has.

    Just think of it in terms of real world objects. We never know properties of objects unless we do some action: we have to ask a person for their name, we have to look at an object to see its color etc. The same principle should apply to objects in programming.

    Another issue is that people tend to think of objects in term of classes, instead in terms of instances. None of us is a Person; we are instances of a Person class, each with different attributes and details. When we interact, it's not a Person interacting with a person -- it's Berislav interacting with Athox, for instance.

  8. #33
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    If you're going to give it a different default value, you should run the setter function in the constructor of the new subclass. It's not much harder than that
    What you are doing is wrong. Your subclasses are setting values inside the constructor, and that's an odd way of overriding values and dealing with polymorphism.

    What you are doing is hiding the class instantiation behaviour inside a method. So, by looking at your API or documentation no one will ever know the values that you are overriding. This is not about getters and setters, is about overriding attributes in a transparent way.

  9. #34
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BerislavLopac View Post
    Nonononono!

    The principle is actually very easy:

    1. The objects are defined by their behavior.
    2. The behavior is defined by actions the objects can perform.
    3. Those actions are defined with the methods that can be called by other objects.
    4. Only those methods should be "public" (i.e. callable from outside).
    5. Everything else (attributes or objects) should be "private" (i.e. only callable/visible/modifiable from inside).

    And once again, the inheritance rights should be at least completely separate from access rights, and ideally they should be restricted in no way -- a subclass should automatically inherit everything the parent class has.

    Just think of it in terms of real world objects. We never know properties of objects unless we do some action: we have to ask a person for their name, we have to look at an object to see its color etc. The same principle should apply to objects in programming.

    Another issue is that people tend to think of objects in term of classes, instead in terms of instances. None of us is a Person; we are instances of a Person class, each with different attributes and details. When we interact, it's not a Person interacting with a person -- it's Berislav interacting with Athox, for instance.
    Hey, it looks like you love to play OOP teacher

  10. #35
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by REMIYA View Post
    Hey, it looks like you love to play OOP teacher
    Sorry, I didn't mean to lecture. I was just putting into words my thoughts on the matter. I might be wrong, but I doubt it.

  11. #36
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by phpimpact View Post
    What you are doing is wrong. Your subclasses are setting values inside the constructor, and that's an odd way of overriding values and dealing with polymorphism.

    What you are doing is hiding the class instantiation behaviour inside a method. So, by looking at your API or documentation no one will ever know the values that you are overriding. This is not about getters and setters, is about overriding attributes in a transparent way.
    If you've ever programmed in C++, you'll know that initializing a class attribute at the same time as declaration is wrong.

    The attribute values are what makes the object unique. You should avoid "default" values. If you can't set all the "defaultized" attributes at the constructor, then there's a doubtful need of the attribute.

    In a subclass constructor, you should always call the parent constructor as well, like in the following code, unless the functionality of the constructor is to OVERRIDE the parent constructor COMPLETELY.

    PHP Code:
    class {
      protected 
    $var// should be private, but protected for this example
      
    protected $var2// same

      
    public function __construct() {
        
    $this->var true// should go through a setter, but for example
        
    $this->var2 false// same
      
    }
    }

    class 
    extends {
      public function 
    __construct() {
        
    // you don't know what other things the parent construct 
        // might do, and all you want to do is change the initial value of the
        // $var.
        
    parent::__construct();
        
    $this->var false;
      }


  12. #37
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    If you've ever programmed in C++, you'll know that initializing a class attribute at the same time as declaration is wrong.
    If you've ever programmed C++ you know it's one of the most inelegant languages out there and should hardly serve as an example of how proper OOP should work.
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  13. #38
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Jasper Bekkers View Post
    If you've ever programmed C++ you know it's one of the most inelegant languages out there and should hardly serve as an example of how proper OOP should work.
    My point was that if you initialize a variable at declaration in C++, you'll get a compiler error. And that should be a hint, shouldn't it.

    And C++ is probably inelegant, but the OO is ten times better than what PHP can do.

  14. #39
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    My point was that if you initialize a variable at declaration in C++, you'll get a compiler error. And that should be a hint, shouldn't it.
    No, it shouldn't. Instead, it bears no relation to PHP whatsoever.

  15. #40
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    My point was that if you initialize a variable at declaration in C++, you'll get a compiler error. And that should be a hint, shouldn't it.
    Mostly a hint about C/C++ having a very strong separation between compile time and run time. In PHP, this border is blurred.

  16. #41
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    Mostly a hint about C/C++ having a very strong separation between compile time and run time. In PHP, this border is blurred.
    Amazing how people are getting stuck on the things that don't matter in this discussion. I'll try that too: C and C++ are two different languages. Mentioning C and C++ as the same thing is somewhat like calling HTML and PHP the same thing.

    That was fun. Now get to the point.

  17. #42
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Posts
    27
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Actually I think you miss the point Athox, this discussion is not about how to initialize a variable properly, its not even a discussion about setters/getters but a discussion about access modifiers, and in terms of OOP (namely inheritance) private (as PHP implements it) is bad practise.

    I agree on the other hand that you should set default values in the constructor, not within the declaration, because as long as the constructor isnt called we have a class without any state, and as such it shouldnt have any values. When the constructor is called however, the class turns into an instance, and as such it can have (default) values

  18. #43
    SitePoint Enthusiast
    Join Date
    Oct 2006
    Posts
    85
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myc View Post
    Actually I think you miss the point Athox, this discussion is not about how to initialize a variable properly, its not even a discussion about setters/getters but a discussion about access modifiers, and in terms of OOP (namely inheritance) private (as PHP implements it) is bad practise.
    Yeah, but PHP implements that part exactly the same way as most other languages.

    Either way, my argument earlier was that attributes should be as private as possible. And someone started giving me a lecture about how to match OOP with real world objects, and somewhere near that part someone else were talking about how methods should be the external communication for the object.
    Can't the two posters just read each others posts and save the world? It would be great.

    Having private attributes is one thing. If you want it to be changed in the subclasses, but still not from outside the class, just make the getter and setter protected. It's the correct way, no matter how you put it.

    People's personal interpretations of how OOP should work are not very objective, are they? (pun intended )

  19. #44
    SitePoint Guru BerislavLopac's Avatar
    Join Date
    Sep 2004
    Location
    Zagreb, Croatia
    Posts
    830
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Athox View Post
    Yeah, but PHP implements that part exactly the same way as most other languages.
    Which doesn't mean that the other languages got it right.

    Quote Originally Posted by Athox View Post
    Either way, my argument earlier was that attributes should be as private as possible.
    This isn't an argument, it's an opinion, and it heavily depends on how you define the term "private". In "most other languages" (as you put it) this keyword restricts two completely separate things: which objects may access a property, and which properties are inherited by a subclass. My point was that these are two completely separate concerns and should not be controlled by a single language construct.

    Check out how is access defined in Smalltalk; here's an excerpt from the Wikipedia article:
    The state an object holds is always private to that object. Other objects can query or change that state only by sending requests (messages) to the object to do so. Any message can be sent to any object: when a message is received, the receiver determines whether that message is appropriate.
    In other words, you might or might not be right -- depending on the definition of the word "private", which depends on the language used. Considering we are on a PHP board, if we consider PHP you are actually wrong, as "private" inflicts inheritance restrictions which are actually harmful.

    Quote Originally Posted by Athox View Post
    And someone started giving me a lecture about how to match OOP with real world objects, and somewhere near that part someone else were talking about how methods should be the external communication for the object.
    I think both of these points were mine, and as I replied above my intention wasn't to lecture anyone, and especially not you. Naturally not all methods will be public; there is a ton of uses for purely internal methods. However, an object is defined by its external behavior, which is implemented by public methods. This is the same thinking which stands behind interfaces -- an interface is actually a "type", as it defines the method signatures required for an object to be of that type.

    Quote Originally Posted by Athox View Post
    Having private attributes is one thing. If you want it to be changed in the subclasses, but still not from outside the class, just make the getter and setter protected. It's the correct way, no matter how you put it.
    Your error here lies in the words "If you want it to be changed in the subclasses, but still not from outside the class" -- no attributes are changed inside or outside of a class. You don't run your methods on a class -- you always call them upon an instance of a class. The only exception are static members, but in PHP they don't differ from global variables/functions except in regards to organization of code.

  20. #45
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Athox, you are the only person I know in the PHP community that says that all attributes should be private. So, you are right, everyone else is wrong.

  21. #46
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myc View Post
    I agree on the other hand that you should set default values in the constructor, not within the declaration, because as long as the constructor isnt called we have a class without any state, and as such it shouldnt have any values. When the constructor is called however, the class turns into an instance, and as such it can have (default) values
    Actually, that's not strictly true, at least not in all cases. I've noticed that, when using PDOStatement->fetchObject(), the resulting object will have it's properties set BEFORE the constructor is called. While this is most likely a bug, it does show that objects do have state before the constructor is called.

    In any case, there are situations where it is preferable to give properties default values, as these values can be queried using get_class_vars().

  22. #47
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by phpimpact View Post
    Athox, you are the only person I know in the PHP community that says that all attributes should be private. So, you are right, everyone else is wrong.
    Athox is right. The attributes should be PRIVATE or PROTECTED. The methods to access them should be PUBLIC.

  23. #48
    SitePoint Zealot Mau's Avatar
    Join Date
    Jan 2006
    Location
    California, USA
    Posts
    134
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by REMIYA View Post
    Athox is right. The attributes should be PRIVATE or PROTECTED. The methods to access them should be PUBLIC.
    Sure, Athox is right, but is Athox exclusively right? If Athox was exclusively correct, then public properties would result in a parse error, no?

    Just as there is more than one way to solve a math problem, there are multiple ways to solve a programming problem. My personal approach is yours, REMIYA, but there has been lots of quality software that uses others (Zend Framework, most notably).

    This argument is isomorphic to KDE vs Gnome: at the end of the day, they both do exactly the same thing and it boils down to personal preference.

  24. #49
    SitePoint Wizard REMIYA's Avatar
    Join Date
    May 2005
    Posts
    1,351
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Mau View Post
    Just as there is more than one way to solve a math problem, there are multiple ways to solve a programming problem.
    Flexibility

  25. #50
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    Actually, that's not strictly true, at least not in all cases. I've noticed that, when using PDOStatement->fetchObject(), the resulting object will have it's properties set BEFORE the constructor is called. While this is most likely a bug, it does show that objects do have state before the constructor is called.
    It's not a bug, although I can't recall why it happens. (I did get a sort of explanation from Ilia once.) Calling PDOStatement::setFetchMode() with PDO::FETCH_PROPS_LATE causes properties to be set only when they're accessed. I did some experiments with this about a year ago and found that in this case they're set after __construct(), but Ilia's explanation to me suggested that they might not even be set until they're accessed like $obj->prop. (In retrospect, this seems a bit strange because that may happen long after PDOStatement::fetch() or fetchAll() spits out the object.)
    Zealotry is contingent upon 100 posts and addiction 200?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •