Statement on glibc/iconv Vulnerability

Métodos de enumerações

Enums (tanto Puras quanto Backed) podem conter métodos, e podem implementar interfaces. Se uma Enum implementa uma interface, então qualquer verificação de tipo para aquela interface também aceitará todos os casos daquela Enum.

<?php

interface Colorido
{
public function
cor(): string;
}

enum
Naipe implements Colorido
{
case
Copas;
case
Ouros;
case
Paus;
case
Espadas;

// Cumpre o contrato da interface.
public function cor(): string
{
return match(
$this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}

// Não faz parte de uma interface; tudo bem.
public function forma(): string
{
return
"Retângulo";
}
}

function
pintar(Colorido $c)
{
/* ... */
}

pintar(Naipe::Paus); // Funciona

print Naipe::Ouros->shape(); // imprime "Retângulo"
?>

Nesse exemplo, todas as quatro instâncias de Naipe possuem dois métodos, cor() e forma(). Até onde o código chamador e as checagens de tipo sabem, elas se comportam exatamente da mesma forma que qualquer outra instância de objeto.

Em uma Backed Enum, a declaração de interface vai após a declaração do tipo de lastro.

<?php

interface Colorido
{
public function
cor(): string;
}

enum
Naipe: string implements Colorido
{
case
Copas = 'C';
case
Ouros = 'O';
case
Paus = 'P';
case
Espadas = 'E';

// Cumpre o contrato da interface.
public function cor(): string
{
return match(
$this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}
}
?>

Dentro de um método, a variável $this é definida e se refere à instância do Caso.

Métodos podem ser arbitrariamente complexos, mas na prática geralmente retornam um valor estático ou match no $this para fornecer resultados diferentes para casos diferentes.

Note que nesse caso, uma prática melhor de modelagem de dados seria definir também um Tipo Enum CorDeNaipe com valores Preto e Vermelho e retornar isso no seu lugar. No entanto, isso complicaria esse exemplo.

A hierarquia acima é logicamente similar a seguinte estrutura de classes (embora esse não seja o código real que é executado):

<?php

interface Colorido
{
public function
cor(): string;
}

final class
Naipe implements UnitEnum, Colorido
{
public const
Copas = new self('Copas');
public const
Ouros = new self('Ouros');
public const
Paus = new self('Paus');
public const
Espadas = new self('Espadas');

private function
__construct(public readonly string $nome) {}

public function
cor(): string
{
return match(
$this) {
Naipe::Copas, Naipe::Ouros => 'Vermelho',
Naipe::Paus, Naipe::Espadas => 'Preto',
};
}

public function
forma(): string
{
return
"Retângulo";
}

public static function
cases(): array
{
// Método ilegal, porque definir manualmente um método cases() em uma Enum não é permitido.
// Veja também a seção "Listagem de valores".
}
}
?>

Métodos podem ser públicos, privados, ou protegidos, apesar dos privados e protegidos são equivalentes na prática, pois herança não é permitida.

add a note

User Contributed Notes 1 note

up
7
iloveyii at yahoo dot com
8 months ago
Just to complete the function shape in the above neat example:

<?php
interface Colorful
{
public function
color(): string;
}

enum
Suit implements Colorful
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;

// Fulfills the interface contract.
public function color(): string
{
return match(
$this) {
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}

// Not part of an interface; that's fine.
public function shape(): string
{
return match(
$this) {
Suit::Hearts => '❤️',
Suit::Diamonds => '💎',
Suit::Clubs => '♣️',
Suit::Spades => ' ♠️'
};

}
}

echo
Suit::Diamonds->shape();
echo
PHP_EOL;
echo
Suit::Clubs->shape();
To Top