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:
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
// 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();
?>
2. Definindo uma classe
<?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:
- Use a palavra-chave
classpara definir uma classe. Os nomes das classes utilizamPascalCase. - Declare propriedades com
public string $name;(o PHP 7.4+ suporta declarações de tipo). $thisrefere-se ao objeto atual dentro de um método.
3. Criação de objetos
Uma classe é apenas um “projeto”. Você cria “objetos” concretos com a palavra-chave new:
<?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
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
?>
$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 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 ✅
?>
5. Modificadores de acesso
Os modificadores de acesso controlam a visibilidade das propriedades e dos métodos:
<?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 |
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
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
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
?>
❓ 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(),$thisrefere-se a$car1.
P: Por que não usar
varpara declarar propriedades? R: Essa é a sintaxe do PHP 4 e está obsoleta. O PHP moderno sempre usapublic/private/protectedcom declarações de tipo.
📖 Resumo
classdefine um projeto,newcria um objeto$thisrefere-se ao objeto atual dentro de um método__construct()é executado automaticamente nonew, inicializando o objeto- Promoção de propriedades no construtor do PHP 8: escreva
public string $namediretamente nos parâmetros public/private/protectedcontrolar a visibilidade- Encapsulamento: propriedades privadas + métodos públicos, controlando como os dados são modificados
📝 Exercícios
- Crie uma classe
Bookcom as propriedades título/autor/preço, um construtor para inicializá-las e um métodogetInfo()que retorne as informações do livro. - Crie uma classe
BankAccountcom 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. - Reescreva o exercício 1 utilizando a promoção de propriedades no construtor do PHP 8. Veja quantas linhas de código você economiza.



