What is the difference between public, private, and protected?

后端 未结 17 1576
抹茶落季
抹茶落季 2020-11-21 07:54

When and why should I use public, private, and protected functions and variables inside a class? What is the difference between them?<

相关标签:
17条回答
  • 2020-11-21 08:09

    dd

    Public:

    When you declare a method (function) or a property (variable) as public, those methods and properties can be accessed by:

    • The same class that declared it.
    • The classes that inherit the above declared class.
    • Any foreign elements outside this class can also access those things.

    Example:

    <?php
    
    class GrandPa
    {
        public $name='Mark Henry';  // A public variable
    }
    
    class Daddy extends GrandPa // Inherited class
    {
        function displayGrandPaName()
        {
            return $this->name; // The public variable will be available to the inherited class
        }
    
    }
    
    // Inherited class Daddy wants to know Grandpas Name
    $daddy = new Daddy;
    echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'
    
    // Public variables can also be accessed outside of the class!
    $outsiderWantstoKnowGrandpasName = new GrandPa;
    echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry'
    

    Protected:

    When you declare a method (function) or a property (variable) as protected, those methods and properties can be accessed by

    • The same class that declared it.
    • The classes that inherit the above declared class.

    Outsider members cannot access those variables. "Outsiders" in the sense that they are not object instances of the declared class itself.

    Example:

    <?php
    
    class GrandPa
    {
        protected $name = 'Mark Henry';
    }
    
    class Daddy extends GrandPa
    {
        function displayGrandPaName()
        {
            return $this->name;
        }
    
    }
    
    $daddy = new Daddy;
    echo $daddy->displayGrandPaName(); // Prints 'Mark Henry'
    
    $outsiderWantstoKnowGrandpasName = new GrandPa;
    echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error
    

    The exact error will be this:

    PHP Fatal error: Cannot access protected property GrandPa::$name


    Private:

    When you declare a method (function) or a property (variable) as private, those methods and properties can be accessed by:

    • The same class that declared it.

    Outsider members cannot access those variables. Outsiders in the sense that they are not object instances of the declared class itself and even the classes that inherit the declared class.

    Example:

    <?php
    
    class GrandPa
    {
        private $name = 'Mark Henry';
    }
    
    class Daddy extends GrandPa
    {
        function displayGrandPaName()
        {
            return $this->name;
        }
    
    }
    
    $daddy = new Daddy;
    echo $daddy->displayGrandPaName(); // Results in a Notice 
    
    $outsiderWantstoKnowGrandpasName = new GrandPa;
    echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error
    

    The exact error messages will be:

    Notice: Undefined property: Daddy::$name
    Fatal error: Cannot access private property GrandPa::$name


    Dissecting the Grandpa Class using Reflection

    This subject is not really out of scope, and I'm adding it here just to prove that reflection is really powerful. As I had stated in the above three examples, protected and private members (properties and methods) cannot be accessed outside of the class.

    However, with reflection you can do the extra-ordinary by even accessing protected and private members outside of the class!

    Well, what is reflection?

    Reflection adds the ability to reverse-engineer classes, interfaces, functions, methods and extensions. Additionally, they offers ways to retrieve doc comments for functions, classes and methods.

    Preamble

    We have a class named Grandpas and say we have three properties. For easy understanding, consider there are three grandpas with names:

    • Mark Henry
    • John Clash
    • Will Jones

    Let us make them (assign modifiers) public, protected and private respectively. You know very well that protected and private members cannot be accessed outside the class. Now let's contradict the statement using reflection.

    The code

    <?php
    
    class GrandPas   // The Grandfather's class
    {
        public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
        protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected  modifier
        private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
    }
    
    
    # Scenario 1: without reflection
    $granpaWithoutReflection = new GrandPas;
    
    # Normal looping to print all the members of this class
    echo "#Scenario 1: Without reflection<br>";
    echo "Printing members the usual way.. (without reflection)<br>";
    foreach($granpaWithoutReflection as $k=>$v)
    {
        echo "The name of grandpa is $v and he resides in the variable $k<br>";
    }
    
    echo "<br>";
    
    #Scenario 2: Using reflection
    
    $granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class
    $granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private)
    
    
    echo "#Scenario 2: With reflection<br>";
    echo "Printing members the 'reflect' way..<br>";
    
    foreach($granpaNames as $k=>$v)
    {
        echo "The name of grandpa is $v and he resides in the variable $k<br>";
    }
    

    Output:

    #Scenario 1: Without reflection
    Printing members the usual way.. (Without reflection)
    The name of grandpa is Mark Henry and he resides in the variable name1
    
    #Scenario 2: With reflection
    Printing members the 'reflect' way..
    The name of grandpa is Mark Henry and he resides in the variable name1
    The name of grandpa is John Clash and he resides in the variable name2
    The name of grandpa is Will Jones and he resides in the variable name3
    

    Common Misconceptions:

    Please do not confuse with the below example. As you can still see, the private and protected members cannot be accessed outside of the class without using reflection

    <?php
    
    class GrandPas   // The Grandfather's class
    {
        public     $name1 = 'Mark Henry';  // This grandpa is mapped to a public modifier
        protected  $name2 = 'John Clash';  // This grandpa is mapped to a protected modifier
        private    $name3 = 'Will Jones';  // This grandpa is mapped to a private modifier
    }
    
    $granpaWithoutReflections = new GrandPas;
    print_r($granpaWithoutReflections);
    

    Output:

    GrandPas Object
    (
        [name1] => Mark Henry
        [name2:protected] => John Clash
        [name3:GrandPas:private] => Will Jones
    )
    

    Debugging functions

    print_r, var_export and var_dump are debugger functions. They present information about a variable in a human-readable form. These three functions will reveal the protected and private properties of objects with PHP 5. Static class members will not be shown.


    More resources:

    • The PHP Manual - OOP Properties
    • The PHP Manual - OOP Visibility
    • Techflirt.com - Visibility in PHP Classes
    • Jordizle.com - Public, Private, Protected in PHP 5

    0 讨论(0)
  • 2020-11-21 08:09

    Reviving an old question, but I think a really good way to think of this is in terms of the API that you are defining.

    • public - Everything marked public is part of the API that anyone using your class/interface/other will use and rely on.

    • protected - Don't be fooled, this is also part of the API! People can subclass, extend your code and use anything marked protected.

    • private - Private properties and methods can be changed as much as you like. No one else can use these. These are the only things you can change without making breaking changes.

    Or in Semver terms:

    • Changes to anything public or protected should be considered MAJOR changes.

    • Anything new public or protected should be (at least) MINOR

    • Only new/changes to anything private can be PATCH

    So in terms of maintaining code, its good to be careful about what things you make public or protected because these are the things you are promising to your users.

    0 讨论(0)
  • 2020-11-21 08:10

    The difference is as follows:

    Public :: A public variable or method can be accessed directly by any user of the class.

    Protected :: A protected variable or method cannot be accessed by users of the class but can be accessed inside a subclass that inherits from the class.

    Private :: A private variable or method can only be accessed internally from the class in which it is defined.This means that a private variable or method cannot be called from a child that extends the class.

    0 讨论(0)
  • 2020-11-21 08:10

    PHP manual has a good read on the question here.

    The visibility of a property or method can be defined by prefixing the declaration with the keywords public, protected or private. Class members declared public can be accessed everywhere. Members declared protected can be accessed only within the class itself and by inherited and parent classes. Members declared as private may only be accessed by the class that defines the member.

    0 讨论(0)
  • 2020-11-21 08:14

    They're there to allow for different levels of encapsulation

    0 讨论(0)
  • 2020-11-21 08:17
    /**
     * Define MyClass
     */
    class MyClass
    {
        public $public = 'Public';
        protected $protected = 'Protected';
        private $private = 'Private';
    
        function printHello()
        {
            echo $this->public;
            echo $this->protected;
            echo $this->private;
        }
    }
    
    $obj = new MyClass();
    echo $obj->public; // Works
    echo $obj->protected; // Fatal Error
    echo $obj->private; // Fatal Error
    $obj->printHello(); // Shows Public, Protected and Private
    
    
    /**
     * Define MyClass2
     */
    class MyClass2 extends MyClass
    {
        // We can redeclare the public and protected method, but not private
        protected $protected = 'Protected2';
    
        function printHello()
        {
            echo $this->public;
            echo $this->protected;
            echo $this->private;
        }
    }
    
    $obj2 = new MyClass2();
    echo $obj2->public; // Works
    echo $obj2->private; // Undefined
    echo $obj2->protected; // Fatal Error
    $obj2->printHello(); // Shows Public, Protected2, Undefined
    

    Extracted From :

    http://php.net/manual/en/language.oop5.visibility.php

    0 讨论(0)
提交回复
热议问题