php - usado - toda classe é instância de um objeto




Qual é a diferença entre público, privado e protegido? (10)

Quando e por que devo usar funções e variáveis public , private e protected dentro de uma classe? Qual a diferença entre eles?

Exemplos:

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

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

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

⚡️ Aqui está uma maneira fácil de lembrar o escopo do public , protected e private .

PUBLIC :

  • escopo public : Uma variável / função pública está disponível para os objetos e outras classes.

PROTECTED :

  • escopo protected : Uma variável / função protegida está disponível para todas as classes que estendem a classe atual.
  • Não! Objetos não podem acessar este escopo

PRIVATE :

  • escopo private : Uma variável / função privada é visível apenas na classe atual em que está sendo definida.
  • Não! Classe que estender a classe atual não pode acessar esse escopo.
  • Não! Objetos não podem acessar esse escopo.

Leia a visibilidade de um método ou variável no Manual do PHP.


A diferença é a seguinte:

Public :: Uma variável ou método público pode ser acessado diretamente por qualquer usuário da classe.

Protected :: Uma variável ou método protegido não pode ser acessado por usuários da classe, mas pode ser acessado dentro de uma subclasse que herda da classe.

Private :: Uma variável privada ou método só pode ser acessado internamente a partir da classe na qual ele está definido. Isso significa que uma variável privada ou método não pode ser chamado de um filho que estende a classe.


Eles estão lá para permitir diferentes níveis de encapsulation


Manual PHP tem uma boa leitura sobre a questão aqui .

A visibilidade de uma propriedade ou método pode ser definida prefixando a declaração com as palavras-chave public, protected ou private. Os membros da classe declarados públicos podem ser acessados ​​em todos os lugares. Os membros declarados protegidos podem ser acessados ​​somente dentro da própria classe e por classes herdadas e parentais. Os membros declarados como privados só podem ser acessados ​​pela classe que define o membro.


Público: é um estado padrão quando você declara uma variável ou método, pode ser acessado por qualquer coisa diretamente no objeto.

Protegido: pode ser acessado somente dentro do objeto e subclasses.

Privado: pode ser referenciado apenas no objeto, não em subclasses.


Para mim, esta é a maneira mais útil de entender os três tipos de propriedade:

Público : use isso quando estiver OK com essa variável sendo acessada diretamente e alterada de qualquer lugar em seu código.

Exemplo de uso de fora da classe:

$myObject = new MyObject()
$myObject->publicVar = 'newvalue';
$pubVar = $myObject->publicVar;

Protegido : Use isto quando você quer forçar outros programadores (e você) a usar getters / setters fora da classe ao acessar e configurar variáveis ​​(mas você deve ser consistente e usar os getters e setters dentro da classe também). Esta ou a private tendem a ser a maneira padrão de configurar todas as propriedades da classe.

Por quê? Porque se você decidir em algum ponto no futuro (talvez em até 5 minutos) que você quer manipular o valor que é retornado para aquela propriedade ou fazer alguma coisa com ele antes de obter / configurar, você pode fazer isso sem refatorar em todos os lugares que você tem usado em seu projeto.

Exemplo de uso de fora da classe:

$myObject = new MyObject()
$myObject->setProtectedVar('newvalue');
$protectedVar = $myObject->getProtectedVar();

Privado : private propriedades private são muito semelhantes às propriedades protected . Mas a característica diferencial / diferença é que torná-lo private também o torna inacessível a classes filhas sem usar o getter ou setter da classe pai.

Então, basicamente, se você está usando getters e setters para uma propriedade (ou se ela é usada apenas internamente pela classe pai e não deve ser acessível em nenhum outro lugar), você pode torná-la private , apenas para evitar que alguém a use. tentando usá-lo diretamente e introduzindo bugs .

Exemplo de uso dentro de uma classe filha (que estende MyObject):

$this->setPrivateVar('newvalue');
$privateVar = $this->getPrivateVar();

Variáveis ​​no PHP são lançadas em três tipos diferentes:

Público: os valores desse tipo de variável estão disponíveis em todo o escopo e exigem a execução do seu código. declarar como: public $examTimeTable;

Particular: os valores desse tipo de variável estão disponíveis apenas para a classe à qual pertencem. private $classRoomComputers;

Protegido: Valores desta classe somente e disponíveis apenas quando o Access foi concedido em uma forma de herança ou em sua classe filha. geralmente usado :: para conceder acesso pela classe pai

protected $familyWealth;


Você usa:

  • escopo public para disponibilizar essa variável / função de qualquer lugar, outras classes e instâncias do objeto.

  • escopo private quando você quer que sua variável / função seja visível em sua própria classe apenas.

  • escopo protected quando você deseja tornar sua variável / função visível em todas as classes que estendem a classe atual incluindo a classe pai.

Mais: (para informações completas)


Escopos de visibilidade com exemplos abstratos : facilita a compreensão

Esta visibilidade de uma propriedade ou método é definida pela declaração de pré-fixação de uma das três palavras-chave (pública, protegida e privada)

Público : se uma propriedade ou método for definido como público, isso significa que pode ser acessado e manipulado por qualquer coisa que possa se referir a um objeto.

  • Resumo por ex. Pense no escopo de visibilidade pública como um "piquenique público" para o qual qualquer um pode chegar.

Protegido: quando uma visibilidade de propriedade ou método é definida como membros protegidos, só pode ser acessado dentro da própria classe e por classes herdadas e herdadas. (Herdado: - uma classe pode ter todas as propriedades e métodos de outra classe).

  • Pense como um escopo de visibilidade protegida como "piquenique da empresa", em que os membros da empresa e seus familiares não são permitidos ao público. É a restrição de escopo mais comum.

Particular: quando uma visibilidade de propriedade ou método é definida como privada, apenas a classe que possui os membros privados pode acessar esses métodos e propriedades (Internamente dentro da classe), apesar de qualquer relação de classe, talvez.

  • com a analogia do piquenique, pense em um "piquenique da empresa em que apenas os membros da empresa são permitidos" no piquenique. não família nem público em geral são permitidos.

Público:

Quando você declara um método (função) ou uma propriedade (variável) como public , esses métodos e propriedades podem ser acessados ​​por:

  • A mesma classe que declarou isso.
  • As classes que herdam a classe declarada acima.
  • Qualquer elemento estrangeiro fora dessa classe também pode acessar essas coisas.

Exemplo:

<?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'

Protegido:

Quando você declara um método (função) ou uma propriedade (variável) como protected , esses métodos e propriedades podem ser acessados ​​por

  • A mesma classe que declarou isso.
  • As classes que herdam a classe declarada acima.

Os membros de outsiders não podem acessar essas variáveis. "Outsiders" no sentido de que eles não são instâncias de objetos da própria classe declarada.

Exemplo:

<?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

O erro exato será este:

PHP Erro fatal: não é possível acessar a propriedade protegida GrandPa :: $ name

Privado:

Quando você declara um método (função) ou uma propriedade (variável) como private , esses métodos e propriedades podem ser acessados ​​por:

  • A mesma classe que declarou isso.

Os membros de outsiders não podem acessar essas variáveis. Outsiders no sentido de que eles não são instâncias de objeto da própria classe declarada e até mesmo as classes que herdam a classe declarada.

Exemplo:

<?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

As mensagens de erro exatas serão:

Aviso: Propriedade indefinida: Daddy :: $ name
Erro fatal: não é possível acessar a propriedade privada GrandPa :: $ name

Dissecando a aula de vovô usando Reflection

Este assunto não está realmente fora do escopo, e estou adicionando aqui apenas para provar que a reflexão é realmente poderosa. Como afirmei nos três exemplos acima, private membros protected e private (propriedades e métodos) não podem ser acessados ​​fora da classe.

No entanto, com reflexão, você pode fazer o extraordinário , mesmo acessando membros protected e private fora da classe!

Bem, o que é reflexo?

O Reflection adiciona a capacidade de fazer engenharia reversa de classes, interfaces, funções, métodos e extensões. Além disso, eles oferecem maneiras de recuperar comentários de documentos para funções, classes e métodos.

Preâmbulo

Temos uma classe chamada Grandpas e dizemos que temos três propriedades. Para facilitar a compreensão, considere que existem três grandpas com nomes:

  • Mark Henry
  • John Clash
  • Will Jones

Vamos torná-los (atribuir modificadores) public , protected e private respectivamente. Você sabe muito bem que membros protected e private não podem ser acessados ​​fora da classe. Agora vamos contradizer a afirmação usando reflexão.

O código

<?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>";
}

Saída:

#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

Equívocos comuns:

Por favor, não confunda com o exemplo abaixo. Como você ainda pode ver, os membros private e protected não podem ser acessados fora da classe sem usar reflexão

<?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);

Saída:

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

Funções de depuração

print_r , var_export e var_dump são funções do depurador . Eles apresentam informações sobre uma variável em uma forma legível por humanos. Estas três funções irão revelar as propriedades protected e private de objetos com PHP 5. Os membros da classe estática não serão mostrados.

Mais recursos:





protected