Classes e objetos

Você já escreveu 21 lições de código procedural e, provavelmente, está começando a sentir que as coisas ficam confusas à medida que sua base de código cresce. A programação orientada a objetos (OOP) resolve esse problema — ela agrupa dados e funções relacionados em “classes”, tornando o código mais organizado e reutilizável.

1. Por que precisamos de classes e objetos?

Pense nisso usando uma analogia com o mundo real:

TEXT
Procedural: You follow a checklist every time you bake a cake — crack eggs → add flour → mix → bake
Object-oriented: You have a "cake machine" (class). Press "make" and out comes a cake (object)

Vamos comparar o código:

PHP
<?php
// Procedural: data and functions are scattered
$userName = "John";
$userAge = 25;
function greet($name) {
    return "Hello, {$name}";
}
echo greet($userName);

// Object-oriented: data and functions are bundled together
class User {
    public string $name;
    public int $age;
    
    function greet(): string {
        return "Hello, {$this->name}";
    }
}
$user = new User();
$user->name = "John";
$user->age = 25;
echo $user->greet();
?>
💡 Dica: A POO não é uma forma “melhor” de programar — é uma ferramenta para organizar códigos complexos. Scripts pequenos ficam mais simples com código procedural. As vantagens da POO ficam evidentes quando sua base de código ultrapassa 500 linhas.


2. Definindo uma classe

PHP
<?php
class Car {
    // Properties (data)
    public string $brand;
    public string $color;
    public int $year;
    
    // Methods (behavior)
    public function start(): string {
        return "{$this->brand} is starting!";
    }
    
    public function honk(): string {
        return "Beep beep!";
    }
}
?>

Pontos-chave da sintaxe:


3. Criação de objetos

Uma classe é apenas um “projeto”. Você cria “objetos” concretos com a palavra-chave new:

PHP
<?php
// From one blueprint (class), create three specific cars (objects)
$car1 = new Car();
$car1->brand = "Toyota";
$car1->color = "White";
$car1->year = 2024;

$car2 = new Car();
$car2->brand = "BMW";
$car2->color = "Black";
$car2->year = 2023;

echo $car1->start();  // Toyota is starting!
echo $car2->start();  // BMW is starting!

// Use the arrow operator -> to access properties and methods
echo $car1->brand;    // Toyota
$car1->color = "Red"; // Modify a property
echo $car1->color;    // Red
?>

4. O método __construct

O construtor é chamado automaticamente quando você usa new, permitindo que você inicialize um objeto:

PHP
<?php
class Car {
    public string $brand;
    public string $color;
    public int $year;
    
    // Constructor
    public function __construct(string $brand, string $color, int $year) {
        $this->brand = $brand;
        $this->color = $color;
        $this->year  = $year;
    }
    
    public function getInfo(): string {
        return "{$this->year} {$this->color} {$this->brand}";
    }
}

// Pass arguments when creating the object
$car = new Car("Toyota", "White", 2024);
echo $car->getInfo();  // 2024 White Toyota
?>
💡 Dica: Em $this->brand = $brand, o lado esquerdo $this->brand é a propriedade e o lado direito $brand é o parâmetro. O PHP 8.0+ oferece suporte à promoção de propriedades no construtor, o que torna isso ainda mais claro — veja abaixo.

▶ Exemplo: Promoção de propriedades no construtor do PHP 8

PHP
<?php
// PHP 8.0+ simplified syntax
class Car {
    public function __construct(
        public string $brand,
        public string $color,
        public int $year,
    ) {
        // Parameters automatically become properties! No more $this->brand = $brand
    }
}

$car = new Car("Toyota", "White", 2024);
echo $car->brand;  // Toyota ✅
?>
▶ Experimente
💡 Dica: Essa é uma das maiores melhorias do PHP 8 — a promoção de propriedades no construtor reduz pela metade o código repetitivo. Novos projetos devem usar essa sintaxe.


5. Modificadores de acesso

Os modificadores de acesso controlam a visibilidade das propriedades e dos métodos:

PHP
<?php
class BankAccount {
    public string $bank = "Bank of China";  // Anyone can see and modify
    private float $balance = 0;             // Only accessible inside the class
    protected string $accountId;            // Accessible inside the class and subclasses
    
    public function __construct(
        private string $owner,
        private float $initialDeposit = 0.0
    ) {
        $this->balance = $initialDeposit;
    }
    
    // Safely manipulate private properties through public methods
    public function deposit(float $amount): void {
        if ($amount > 0) {
            $this->balance += $amount;
        }
    }
    
    public function getBalance(): float {
        return $this->balance;
    }
}

$account = new BankAccount("John", 1000);
echo $account->bank;         // Bank of China ✅ public is accessible
$account->deposit(500);       // ✅ public method can be called
echo $account->getBalance(); // 1500 ✅
// echo $account->balance;   // ❌ Error: private property not directly accessible
// $account->balance = 9999; // ❌ Error: can't arbitrarily change the balance
?>
Modificador Alias Escopo de acesso
public Público Acessível em qualquer lugar
protected Protegido Classe atual e subclasses
private Privado Apenas para a turma atual
💡 Dica: Defina propriedades como private ou protected e acesse-as por meio de métodos públicos — isso é chamado de encapsulamento. Isso permite que você controle como os dados são modificados; por exemplo, deposit() pode incluir validação.


6. Comparando objetos

PHP
<?php
class User {
    public function __construct(
        public string $name,
        public int $age
    ) {}
}

$u1 = new User("John", 25);
$u2 = new User("John", 25);
$u3 = $u1;

var_dump($u1 == $u2);   // true (same property values)
var_dump($u1 === $u2);  // false (not the same object)
var_dump($u1 === $u3);  // true (pointing to the same object)
?>

7. Exemplo completo: uma classe de usuário

▶ Exemplo: Uma classe de usuário completa

PHP
<?php
class User {
    private string $passwordHash;  // Password hash—never exposed
    
    public function __construct(
        public string $username,
        public string $email,
        string $password,           // Regular parameter (not a property)
        public int $age = 0,
        public bool $isActive = true,
    ) {
        // Password is hashed during construction
        $this->passwordHash = password_hash($password, PASSWORD_DEFAULT);
    }
    
    public function verifyPassword(string $password): bool {
        return password_verify($password, $this->passwordHash);
    }
    
    public function getDisplayName(): string {
        return $this->username . ($this->isActive ? '' : ' (Deactivated)');
    }
    
    public function greet(): string {
        return "Hello, {$this->username}! Your email is {$this->email}.";
    }
}

// Usage
$user = new User("John", "john@example.com", "secret123", 25);

echo $user->greet();
echo "User status: " . $user->getDisplayName() . "<br>";

if ($user->verifyPassword("secret123")) {
    echo "Password correct!";
}
// echo $user->passwordHash; // ❌ Error: private, not accessible
?>
▶ Experimente

❓ Perguntas Frequentes

P: Quando devo usar uma classe em vez de uma função? R: Use uma classe quando os dados e as funções que operam sobre eles se relacionam naturalmente. Por exemplo, um “usuário” possui propriedades como nome, idade e e-mail, além de métodos como login e logout. Se você tiver apenas algumas funções utilitárias não relacionadas entre si, basta usar funções simples.

P: O que é $this? R: $this é uma referência ao “objeto atual sobre o qual a operação está sendo realizada” dentro de um método de objeto. Por exemplo, dentro de $car1->start(), $this refere-se a $car1.

P: Por que não usar var para declarar propriedades? R: Essa é a sintaxe do PHP 4 e está obsoleta. O PHP moderno sempre usa public/private/protected com declarações de tipo.

📖 Resumo

📝 Exercícios

  1. Crie uma classe Book com as propriedades título/autor/preço, um construtor para inicializá-las e um método getInfo() que retorne as informações do livro.
  2. Crie uma classe BankAccount com um saldo privado, métodos públicos de depósito e saque (os saques não podem exceder o saldo) e um método público para verificar o saldo. Crie algumas contas e teste as operações.
  3. Reescreva o exercício 1 utilizando a promoção de propriedades no construtor do PHP 8. Veja quantas linhas de código você economiza.
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%