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

571,932

Solution 1

You use:

  • public scope to make that property/method available from anywhere, other classes and instances of the object.

  • private scope when you want your property/method to be visible in its own class only.

  • protected scope when you want to make your property/method visible in all classes that extend current class including the parent class.

If you don't use any visibility modifier, the property / method will be public.

More: (For comprehensive information)

Solution 2

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:


Solution 3

private - can be accessed from WITHIN the class only

protected - can be accessed from WITHIN the class and INHERITING classes

public - can be accessed from code OUTSIDE the class as well

This applies to functions as well as variables.

Solution 4

It is typically considered good practice to default to the lowest visibility required as this promotes data encapsulation and good interface design. When considering member variable and method visibility think about the role the member plays in the interaction with other objects.

If you "code to an interface rather than implementation" then it's usually pretty straightforward to make visibility decisions. In general, variables should be private or protected unless you have a good reason to expose them. Use public accessors (getters/setters) instead to limit and regulate access to a class's internals.

To use a car as an analogy, things like speed, gear, and direction would be private instance variables. You don't want the driver to directly manipulate things like air/fuel ratio. Instead, you expose a limited number of actions as public methods. The interface to a car might include methods such as accelerate(), deccelerate()/brake(), setGear(), turnLeft(), turnRight(), etc.

The driver doesn't know nor should he care how these actions are implemented by the car's internals, and exposing that functionality could be dangerous to the driver and others on the road. Hence the good practice of designing a public interface and encapsulating the data behind that interface.

This approach also allows you to alter and improve the implementation of the public methods in your class without breaking the interface's contract with client code. For example, you could improve the accelerate() method to be more fuel efficient, yet the usage of that method would remain the same; client code would require no changes but still reap the benefits of your efficiency improvement.

Edit: Since it seems you are still in the midst of learning object oriented concepts (which are much more difficult to master than any language's syntax), I highly recommend picking up a copy of PHP Objects, Patterns, and Practice by Matt Zandstra. This is the book that first taught me how to use OOP effectively, rather than just teaching me the syntax. I had learned the syntax years beforehand, but that was useless without understanding the "why" of OOP.

Solution 5

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.

Share:
571,932
Adam Halasz
Author by

Adam Halasz

Hi, I made 37 open source node.js projects with +147 million downloads. Created the backend system for Hungary's biggest humor network serving 4.5 million unique monthly visitors with a server cost less than $200/month. Successfully failed with several startups before I turned 20. Making money with tech since I'm 15. Wrote my first HTML page when I was 11. Hacked our first PC when I was 4. Lived in 7 countries in the last 4 years. aimform.com - My company adamhalasz.com - My personal website diet.js - Tiny, fast and modular node.js web framework

Updated on July 08, 2022

Comments

  • Adam Halasz
    Adam Halasz almost 2 years

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

    Examples:

    // Public
    public $variable;
    public function doSomething() {
      // ...
    }
    
    // Private
    private $variable;
    private function doSomething() {
      // ...
    }
    
    // Protected
    protected $variable;
    protected function doSomething() {
      // ...
    }
    
    • Matthew
      Matthew almost 13 years
      I think this question would also benefit from answers with practical examples of the use of each, instead of providing the literal definition of what each keyword does.
  • Shahid
    Shahid about 12 years
    protected scope when you want to make your variable/function visible in all classes that extend current class AND its parent classes.
  • JDelage
    JDelage over 11 years
    @Shahid - I don't understand your point. Any class that extends class A also extend A's parent class, no?
  • pal4life
    pal4life over 11 years
    Not sure if the protected definition is correct here, from the actual selected answer it seems, Protected - Can be accessed only from the inherited class onwards and not from the original/parent class. Saying "WITHIN the class" can be a bit confusing.
  • Olaf
    Olaf over 11 years
    I don't think so, in fact it seems that the selected answer is the one that is confusing here. See Shahids comment. IMHO a protected method can very well be accessed from within the original class.
  • Shahid
    Shahid over 11 years
    @JDelage - Please see the link http://www.php.net/manual/en/language.oop5.visibility.php#10‌​9324
  • Shahid
    Shahid over 11 years
    @JDelage - and this link also link
  • Serjas
    Serjas over 11 years
    can a class can access another class's public?
  • user3871
    user3871 about 11 years
    @Safraz, Thanks for the description... but is there any harm to just making all of my methods public?
  • DanMan
    DanMan over 10 years
    @Serjas: No, only another object's, unless they're static methods/fields.
  • hakre
    hakre over 10 years
    With your update: Can you make more clear how "good enough" and "good reason" go together here? For example, using private would be still "good enough" to use, but you don't suggest that any longer albeit the earlier reasons you gave sound like a "good reason" still: encapsulation.
  • J.Steve
    J.Steve over 10 years
    @Growler Why bother using objects at all then?
  • Relaxing In Cyprus
    Relaxing In Cyprus about 10 years
    @Growler, a more helpful answer would be that it is good to hide as much of the inner workings of an object as possible. That way it is less likely to break. If you make everything public, then another programmer might alter a variable which you don't want changed by anything other than the inner workings of your object.
  • Josiah
    Josiah over 9 years
    The book recommended in the edit of this post is really very excellent. The chunk I so far has proved quite enlightening. The first few chapters answered most of my class-related questions.
  • John Slegers
    John Slegers about 9 years
    I don't know if this applies to all programming languages, but in PHP "protected" properties / methods can be accessed in either the class in which it has been declared or classes that inherit from the class defining the property / method.
  • Patanjali
    Patanjali about 8 years
    The books that allowed me to really understand objects, without crowding out my thinking with unnecessary details, like examples in Smalltalk, were by David A Taylor, being Object Oriented Technology: A Manager's Guide and Business Engineering with Object Teechnology. Both are only 100 pages, and each easy enough to read in an afternoon. Of course, there is Gamma et al's Design Patterns, though the basic approach can simply be described by 'subclass what you want to vary'.
  • Russia Must Remove Putin
    Russia Must Remove Putin over 7 years
    You could probably flesh this out a little.
  • Vladimir Despotovic
    Vladimir Despotovic about 7 years
    There is no such thing as "instance of an object". There is only "instance of a class", which is an object. Please edit your answer.
  • JamesG
    JamesG about 7 years
    apologies for the late add on to this convo. Can you tell me why someone would use these? You have explained perfectly how they work etc.. I just would like to know the benefits of use for each of these. Thank you
  • cjmling
    cjmling about 7 years
    @JamesG its a bit explained in the other comment above. stackoverflow.com/questions/4361553/…
  • bxN5
    bxN5 almost 7 years
    I don't know why maybe it's a little out of this question but no one mentioned that in PHP there are another two access modifiers: abstract and final this keyword can be used only for PHP classes but it still access modifiers
  • DanMan
    DanMan over 6 years
    @hakre: The reason why we ought to strive for encapsulation is to avoid leaking state into the outer scope. protected does that already, but you keep it flexible for extension/inheritance. Again, unless you have a good reason to make it private.
  • hakre
    hakre over 6 years
    Well that is probably the point we disagree: protected actually leaks into outer scope and is often in your way as it supports bad design decisions like implicitly favoring inheritance while it's better to favor composition. That's why sticking with private unless you have actual requirements not to is often a better way to start writing code. This will also prevent to make design decisions too early while they are actually not yet needed.
  • DanMan
    DanMan over 6 years
    I won't argue with your overall point, because it's fair enough, but protected doesn't leak into outer scope (code that's calling/accessing the method/field) but only inner scope (extending classes). There's a difference, as minor as it may be to you. It's much easier to track down usage of a protected field than a public one.
  • Julio Marchi
    Julio Marchi over 6 years
    I would suggest you read the explanation about abstraction provided by Dhairya Lakhera here: stackoverflow.com/questions/2558559/…. It is a perfect addition to Shankar Damodaran explanations.
  • jinyong lee
    jinyong lee about 6 years
    A very nice analogy. Do you have one for protected vs private?
  • Tobias Gaertner
    Tobias Gaertner about 5 years
    "including the parent class" is IMHO misleading - it should be "including the class itself"