php 公共,私有和受保护之间有什么区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4361553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:49:39  来源:igfitidea点击:

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

phpoopprivatepublicprotected

提问by Adam

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

何时以及为什么应该在类中使用publicprivateprotected函数和变量?它们之间有什么区别?

Examples:

例子:

// Public
public $variable;
public function doSomething() {
  // ...
}

// Private
private $variable;
private function doSomething() {
  // ...
}

// Protected
protected $variable;
protected function doSomething() {
  // ...
}

回答by Sarfraz

You use:

你用:

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

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

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

  • public范围使该属性/方法可从任何地方、对象的其他类和实例使用。

  • private当您希望您的属性/方法仅在其自己的类中可见时的范围。

  • protected当您想让您的属性/方法在扩展当前类(包括父类)的所有类中可见时的范围。

More:(For comprehensive information)

更多:(有关综合信息)

回答by Shankar Damodaran

dd

日

Public:

民众:

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

当您将方法(函数)或属性(变量)声明为 时public,可以通过以下方式访问这些方法和属性:

  • 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

当您将方法(函数)或属性(变量)声明为 时protected,可以通过以下方式访问这些方法和属性

  • 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

PHP 致命错误:无法访问受保护的属性 GrandPa::$name



Private:

私人的:

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

当您将方法(函数)或属性(变量)声明为 时private,可以通过以下方式访问这些方法和属性:

  • 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 itselfand 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

注意:未定义的属性:Daddy::$name
致命错误:无法访问私有属性 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, protectedand privatemembers (properties and methods) cannot be accessed outside of the class.

这个主题并没有真正超出范围,我在这里添加它只是为了证明反射真的很强大。正如我在上述三个实施例所述,protectedprivate构件(属性和方法)不能被访问之类的外部。

However, with reflection you can do the extra-ordinaryby even accessing protectedand privatemembers outside of the class!

然而,随着反射,你可以做的超乎寻常的甚至访问protectedprivate类的成员外!

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 Grandpasand say we have three properties. For easy understanding, consider there are three grandpas with names:

我们有一个名为的类,Grandpas并说我们有三个属性。为了便于理解,假设有三个有名字的爷爷:

  • Mark Henry
  • John Clash
  • Will Jones
  • 马克亨利
  • 约翰冲突
  • 威尔琼斯

Let us make them (assign modifiers) public, protectedand privaterespectively. You know very well that protectedand privatemembers cannot be accessed outside the class. Now let's contradict the statement using reflection.

让我们让他们(分配调节剂)publicprotectedprivate分别。你很清楚,protectedprivate成员不能在类外访问。现在让我们用反射来反驳这个陈述。

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 privateand protectedmembers cannot be accessed outsideof the class without using reflection

请不要与下面的例子混淆。正如您仍然看到的,如果不使用反射,则无法在类外部访问privateprotected成员

<?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_exportand var_dumpare debugger functions. They present information about a variable in a human-readable form. These three functions will reveal the protectedand privateproperties of objects with PHP 5. Static class members will notbe shown.

print_r,var_exportvar_dump调试器函数。它们以人类可读的形式呈现有关变量的信息。这三个函数将揭示protectedprivate用PHP 5.静态类成员对象的属性将被显示。



More resources:

更多资源:



回答by The Awnry Bear

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.

如果您“编码到接口而不是实现”,那么做出可见性决策通常非常简单。通常,变量应该是私有的或受保护的,除非您有充分的理由公开它们。使用公共访问器(getter/setter)来限制和调节对类内部的访问。

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.

以汽车为例,诸如速度、档位和方向之类的东西将是私有实例变量。您不希望驾驶员直接操纵空气/燃料比之类的东西。相反,您将有限数量的操作公开为公共方法。到汽车的界面可能包括诸如accelerate()deccelerate()/ brake()setGear()turnLeft()turnRight(),等。

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.

这种方法还允许您在不破坏接口与客户端代码的契约的情况下更改和改进类中公共方法的实现。例如,您可以改进该accelerate()方法以提高燃油效率,但该方法的用法将保持不变;客户端代码无需更改,但仍能从效率提升中获益。

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 highlyrecommend picking up a copy of PHP Objects, Patterns, and Practiceby Matt Zandstra. This is the book that first taught me howto 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.

编辑:由于您似乎仍在学习面向对象的概念(这比任何语言的语法都更难掌握),我强烈建议您阅读Matt Zandstra 撰写的PHP 对象、模式和实践的副本。这本书首先教会了我如何有效地使用 OOP,而不仅仅是教我语法。我已经提前几年学习了语法,但是如果不了解 OOP 的“原因”,那是没有用的。

回答by Olaf

private- can be accessed from WITHIN the class only

private- 只能从 WITHIN 类访问

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

protected- 可以从 WITHIN 类和 INHERITING 类中访问

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

public- 也可以从类外的代码访问

This applies to functions as well as variables.

这适用于函数和变量。

回答by Matthew Watts

The difference is as follows:

区别如下:

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

Public:: 类的任何用户都可以直接访问公共变量或方法。

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.

Protected:: 受保护的变量或方法不能被类的用户访问,但可以在继承自该类的子类内部访问。

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.

Private:: 私有变量或方法只能从定义它的类内部访问。这意味着不能从扩展类的子级调用私有变量或方法。

回答by Suman K.C

Visibility Scopeswith Abstract Examples:: Makes easy Understanding

Visibility Scopeswith Abstract examples::易于理解

This visibility of a property or method is defined by pre-fixing declaration of one of three keyword (Public, protected and private)

属性或方法的这种可见性由三个关键字(Public、protected 和 private)之一的前缀声明定义

Public: If a property or method is defined as public, it means it can be both access and manipulated by anything that can refer to object.

公共:如果一个属性或方法被定义为公共,这意味着它可以被任何可以引用对象的东西访问和操作。

  • Abstract eg. Think public visibility scope as "public picnic"that anybody can come to.
  • 摘要例如。将公共可见性范围视为任何人都可以参加的“公共野餐”

Protected :when a property or method visibility is set to protected members can only be access within the class itself and by inherited & inheriting classes. (Inherited:- a class can have all the properties and methods of another class).

受保护:当属性或方法可见性设置为受保护成员时,只能在类本身以及继承和继承类中访问。(继承:- 一个类可以拥有另一个类的所有属性和方法)。

  • Think as a protected visibility scope as "Company picnic"where company members and their family members are allowed not the public. It's the most common scope restriction.
  • 将受保护的可见性范围视为“公司野餐”,允许公司成员及其家庭成员不公开。这是最常见的范围限制。

Private :When a property or method visibility is set to private, only the class that has the private members can access those methods and properties(Internally within the class), despite of whatever class relation there maybe.

Private :当属性或方法可见性设置为私有时,只有拥有私有成员的类才能访问这些方法和属性(在类内部),不管那里可能存在什么类关系。

  • with picnic analogy think as a "company picnic where only the company members are allowed"in the picnic. not family neither general public are allowed.
  • 与野餐类比认为野餐中“公司野餐,只允许公司成员参加”。不是家庭也不允许一般公众。

回答by Techie

/**
 * 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

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

回答by Ahmad Awais

?? Here is an easy way to remember the scope of public, protectedand private.

?? 这是记住public,protected和范围的简单方法private

PUBLIC:

PUBLIC

  • publicscope: A public variable/function is available to both objects and other classes.
  • public范围:公共变量/函数可用于对象和其他类。

PROTECTED:

PROTECTED

  • protectedscope: A protected variable/function is available to all the classes that extend the current class.
  • No! Objects cannot access this scope
  • protected范围:受保护的变量/函数可用于扩展当前类的所有类。
  • 不!对象无法访问此范围

PRIVATE:

PRIVATE

  • privatescope: A private variable/function is only visible in the current class where it is being defined.
  • No! Class that extend the current class cannot access this scope.
  • No! Objects cannot access this scope.
  • private范围:私有变量/函数仅在定义它的当前类中可见。
  • 不!扩展当前类的类无法访问此范围。
  • 不!对象无法访问此范围。

Read the Visibilityof a method or variable on PHP Manual.

阅读PHP 手册中方法或变量的可见性

回答by DanMan

Considering 'when':
I tend to declare everything as private initially, if I'm not exactly sure. Reason being, that it's usually much easier to turn a private method public than the other way round. That's because you can at least be sure that the private method hasn't been used anywhere but in the class itself. A public method may already be in use everywhere, possibly requiring an extensive re-write.

考虑“何时”:
如果我不确定,我倾向于最初将所有内容声明为私有。原因是,将私有方法公开通常比反过来要容易得多。那是因为您至少可以确定私有方法除了在类本身之外没有在任何地方使用过。公共方法可能已经在任何地方使用,可能需要大量重写。

Update: i go for a default of protectednowadays, because I've come to find that it's good enough for encapsulation and doesn't get in the way when I'm extending classes (which i try to avoid anyway). Only if i have a good reason to use the other two, i will.

更新:我protected现在使用默认值,因为我发现它对于封装来说已经足够好了,并且在我扩展类时不会妨碍(无论如何我都尽量避免)。只有当我有充分的理由使用其他两个时,我才会使用。

A good reason for a privatemethod would be one that implements something inherent to that object that even an extending class should not change (factual reason, in addition to encapsulation, like internal state management). Eventually, it's still easy enough to track down where a protectedmethod is being used usually, so i default to protectednowadays. Maybe not 100% objective "in the trenches" experience, I admit.

一个private方法的一个很好的理由是实现该对象固有的某些东西,即使是扩展类也不应该改变(事实原因,除了封装,如内部状态管理)。最终,仍然很容易跟踪protected通常使用方法的位置,所以我protected现在默认使用。我承认,也许不是 100% 客观的“战壕”体验。

回答by code_burgar

PHP manual has a good read on the question here.

PHP 手册对这里的问题有很好的阅读。

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.

属性或方法的可见性可以通过在声明前加上关键字 public、protected 或 private 来定义。声明为 public 的类成员可以在任何地方访问。声明为 protected 的成员只能在类本身内以及被继承类和父类访问。声明为私有的成员只能由定义该成员的类访问。