Ejemplo herencia

<?php

/**
 * Description of Herencia
 *
 * @author incid
 */
class Empleado {

    private $nombre;

    function __construct($nombre) {
        $this->nombre = $nombre;
    }

    function __get($name) {
        return $this->$name;
    }

    function __set($name, $value) {

        if (empty($value)) {
            throw new Exception("No se puede poner valores vacíos");
        }
        $this->$name = $value;
    }

    function saludo() {
        echo "Hola";
    }

}

class Gerente extends Empleado {

    private $bonus;

    function __construct($nombre, $bonus) {
        parent::__construct($nombre);
        $this->__set("bonus", $bonus);
    }

    function saludo() {
        parent::saludo();
        echo "Los gerentes saludan así: Holi";
    }

    function despedida() {
        echo "Adios muy buenas";
    }

}

class Gerente2 extends Empleado {

    private $bonus;

    function __construct($nombre, $bonus) {
        parent::__construct($nombre);
        $this->setBonus($bonus);
    }

    function getBonus() {
        return $this->bonus;
    }

    function setBonus($bonus) {
        $this->bonus = $bonus;
    }

}

$juan = new Empleado("Juan Pérez");
$juan->nombre = "Pepito";
$juan->saludo();
//$juan->despedida(); //ERROR
var_dump($juan);
$eva = new Gerente("Eva Pi", 400);
$eva->saludo();
$eva->despedida();
//$eva->bonus=0;
var_dump($eva);

Ejercicio clases constructor y getters mágicos

Vamos a crear la clase ‘Cliente’ con las siguientes propiedades privadas:

Nombre
NIF
Pais
Importe

Vamos a crear un constructor que pida obligatoriamente el Nombre y el NIF y vamos a crear getters y setters mágicos.

Los valores no pueden estar vacíos, el NIF tiene que empezar por una letra y tener una longitud de 9 caracteres y el importe no puede ser negativo.

Probad todas las características.

class Cliente {

    private $nombre;
    private $nif;
    private $pais;
    private $importe;

    function __construct($nombre, $nif) {
        $this->nombre = $nombre;
        $this->nif = $nif;
    }

    function __get($name) {
        if (!property_exists($this, $name)) {
            throw new Exception("La propiedad $name no existe");
        }
        return $this->$name;
    }

    function __set($name, $value) {
        if (!property_exists($this, $name)) {
            throw new Exception("La propiedad $name no existe");
        }
        if (empty($value)) {
            throw new Exception("La propiedad $name no puede estar vacía");
        }
        if($name=="importe" && $value<0){
             throw new Exception("El importe no puede ser negativo");
        }
        if($name=="nif" && $this->checkNif($value)) {
            throw new Exception("NIF incorrecto");
        }
        $this->$name = $value;
    }
    private function checkNif($nif){
        return (strlen($nif)!=9 || strtoupper(substr($nif, 0,1))<"A"
                || strtoupper(substr($nif, 0,1))>"Z");
    }

}

$pepe=new Cliente("Pepe", "B61235712");

$pepe->nif="B12345678";
$pepe->importe=500;

echo $pepe->nombre;

var_dump($pepe);

Combinación setters/getters mágicos y estilo Java

class Libro {

    private $titulo;
    private $autor;
    private $paginas;
    function getTitulo() {
        return $this->titulo;
    }

    function getAutor() {
        return $this->autor;
    }

    function getPaginas() {
        return $this->paginas;
    }

    function setTitulo($titulo) {
        $this->titulo = $titulo;
    }

    function setAutor($autor) {
        $this->autor = $autor;
    }

    function setPaginas($paginas) {
        $this->paginas = $paginas;
    }

        function __construct($titulo) {
        $this->__set("titulo",$titulo);
    }

    function __get($name) {
         $metodo="get$name";
        if (!method_exists($this, $metodo)) {
            throw new Exception("La propiedad $name no existe");
        }
        return $this->$metodo();
    }

    function __set($name, $value) {
        $metodo="set$name";
        if (!method_exists($this, $metodo)) {
            throw new Exception("La propiedad $name no existe");
        }
        if (empty($value)) {
            throw new Exception("El valor $name no puede estar vacío");
        }
        if ($name == "paginas" && ($value < 10 || $value > 1000)) {
            throw new Exception("Páginas entre 10 y 1000");
        }
        $this->$metodo($value);
    }

}

Getters/Setters mágicos

class Libro {

    private $titulo;
    private $autor;
    private $paginas;

    function __construct($titulo) {
        $this->titulo = $titulo;
    }

    function __get($name) {
        if (!property_exists($this, $name)) {
            throw new Exception("La propiedad $name no existe");
        }
        return $this->$name;
    }

    function __set($name, $value) {
        if (!property_exists($this, $name)) {
            throw new Exception("La propiedad $name no existe");
        }
        if (empty($value)) {
            throw new Exception("El valor $name no puede estar vacío");
        }
        if ($name == "paginas" && ($value < 10 || $value > 1000)) {
            throw new Exception("Páginas entre 10 y 1000");
        }
        $this->$name = $value;
    }

}

Ejercicio varias clases

Vamos a crear una clase Coche con las siguientes propiedades (todas privadas):

Marca
Modelo
Color
Velocidad

Las tres primeras las pasamos en el constructor, la velocidad la ponemos a 0.

Creamos setters y getters para todas las propiedades menos para la velocidad, para esta última sólo ponemos un getter. Comprobamos en todos los setters que el valor no esté vacío, en caso contrario lanzamos una excepción.

Vamos a crear un método acelerar y otro frenar. El primero aumenta la velocidad en 10 y el segundo la disminuye. El coche no puede tener velocidad negativa ni mayor de 140.

Crearemos el método toString que nos muestra la marca, el modelo y el color separados por espacio.

Vamos a crear la clase Carrera que tendrá las siguientes propiedades:

Nombre
Circuito
Coches

En el constructor pedimos las dos primeras, la tercera es un array vacío. Ponemos setters y getters en las dos primeras.

Crearemos un método addCoche al que le pasamos un objeto coche y se añade al array. Crearemos un método quitarCoche al que le pasamos un objeto coche y si hay un objeto de esa marca, modelo y color lo quitamos.

Primera versión:

class Coche {

    private $marca;
    private $modelo;
    private $color;
    private $velocidad=0;

    function __construct($marca, $modelo, $color) {
        $this->setColor($color);
        $this->setMarca($marca);
        $this->setModelo($modelo);
    }

    function acelerar() {
        $this->velocidad += 10;
        if ($this->velocidad > 140) {
            $this->velocidad = 140;
        }
    }

    function frenar() {
        $this->velocidad -= 10;
        if ($this->velocidad < 0) {
            $this->velocidad = 0;
        }
    }

    function __toString() {
        return $this->getMarca() . " " . $this->getModelo() . " " . $this->getColor();
    }

    function getMarca() {
        return $this->marca;
    }

    function getModelo() {
        return $this->modelo;
    }

    function getColor() {
        return $this->color;
    }

    function getVelocidad() {
        return $this->velocidad;
    }

    function setMarca($marca) {
        if (empty($marca)) {
            throw new Exception("La marca no puede estar vacía");
        }
        $this->marca = $marca;
    }

    function setModelo($modelo) {
        if (empty($modelo)) {
            throw new Exception("El modelo no puede estar vacía");
        }
        $this->modelo = $modelo;
    }

    function setColor($color) {
        if (empty($modelo)) {
            throw new Exception("El color no puede estar vacía");
        }
        $this->color = $color;
    }


}

Otra versión:

class Coche {

    private $marca;
    private $modelo;
    private $color;
    private $velocidad;

    function __construct($marca, $modelo, $color) {
        $this->setColor($color);
        $this->setMarca($marca);
        $this->setModelo($modelo);
        $this->setVelocidad(0);
    }

    function acelerar() {
        $this->setVelocidad($this->getVelocidad() + 10);
    }

    function frenar() {
        $this->setVelocidad($this->getVelocidad() - 10);
    }

    function __toString() {
        return $this->getMarca() . " " . $this->getModelo() . " " . $this->getColor();
    }

    function getMarca() {
        return $this->marca;
    }

    function getModelo() {
        return $this->modelo;
    }

    function getColor() {
        return $this->color;
    }

    function getVelocidad() {
        return $this->velocidad;
    }

    function setMarca($marca) {
        $this->checkParam($marca, "La marca no puede estar vacío");
        $this->marca = $marca;
    }

    function setModelo($modelo) {
        $this->checkParam($modelo, "El modelo no puede estar vacío");
        $this->modelo = $modelo;
    }

    function setColor($color) {
        $this->checkParam($color, "El color no puede estar vacío");
        $this->color = $color;
    }

    private function checkParam($param, $message) {
        if (empty($param)) {
            throw new Exception($message);
        }
    }

    private function setVelocidad($velocidad) {
        $this->velocidad = $velocidad;
        if ($this->velocidad > 140) {
            $this->velocidad = 140;
        }
        if ($this->velocidad < 0) {
            $this->velocidad = 0;
        }
    }

}

Carrera:

class Carrera {

    private $nombre;
    private $circuito;
    private $coches = [];

    function __construct($nombre, $circuito) {
        $this->setCircuito($circuito);
        $this->setNombre($nombre);
    }

    function addCoche(Coche $coche) {
        $this->coches[] = $coche;
    }

    function quitarCoche(Coche $coche) {
        for ($i = 0; $i < count($this->coches); $i++) {
            $c = $this->coches[$i];
            if ($c->getModelo() == $coche->getModelo() &&
                    $c->getMarca() == $coche->getMarca() &&
                    $c->getColor() == $coche->getColor()) {
                array_slice($this->coches, $i, 1);
            }
        }
    }

    function getNombre() {
        return $this->nombre;
    }

    function getCircuito() {
        return $this->circuito;
    }

    function setNombre($nombre) {
        $this->nombre = $nombre;
    }

    function setCircuito($circuito) {
        $this->circuito = $circuito;
    }

}

Mezcla de clases

Vamos a mezclar la clase Departamento y la clase Empleado que ya hemos visto. La idea es que el gerente de la clase departamento sea de tipo empleado.

Probad a poner las dos clases juntas y crear primero un empleado y después un departamento pasando el objeto empleado que acabamos de crear ¿Funciona? ¿Por qué sí o por qué no? ¿Hay alguna función que falle? ¿Cómo la arreglaríamos?

Ejercicio Carta

Vamos a crear una clase ‘Carta’ que va a tener las siguientes propiedades:

Palo (de tipo string)
Numero (de tipo string)
Valor (de tipo entero)

Tenemos que crear un constructor que nos obligue a dar todos los valores. Implementar también setter y getter.

Crearemos una función __toString que nos mostrará el valor de la siguiente forma: ‘7 de espadas’

<?php


/**
 * Description of Carta
 *
 * @author incid
 */
class Carta {
    private $palo;
    private $numero;
    private $valor;
    
    function __construct($palo,$numero,$valor) {
        $this->setNumero($numero);
        $this->setPalo($palo);
        $this->setValor($valor);
    }
    
    function getPalo() {
        return $this->palo;
    }

    function getNumero() {
        return $this->numero;
    }

    function getValor() {
        return $this->valor;
    }

    function setPalo($palo) {
        $this->palo = $palo;
    }

    function setNumero($numero) {
        $this->numero = $numero;
    }

    function setValor($valor) {
        $this->valor = $valor;
    }

    function __toString() {
        return $this->getNumero()." de ".$this->getPalo();
    }

}

$miCarta=new Carta("Oros",7,7);
$otra=new Carta("Copas","Rey",10);

echo $otra;

$manoMus=[new Carta("Oros","Sota",10),new Carta("Copas",7,7),
    new Carta("Oros",4,4),new Carta("Bastos",1,1)];

var_dump($manoMus);
$puntos=0;
foreach($manoMus as $carta){
    echo $carta."<br>";
    $puntos+=$carta->getValor();
}
echo "Tienes $puntos puntos";

class BarajaMus{
    private $cartas=[];
    function __construct() {
        $this->crearBaraja();
    }
    private function crearBaraja(){
        $this->cartas=[];
        $palos=['Oros','Espadas','Copas','Bastos'];
        $numeros=["As",2,3,4,5,6,7,'Sota','Caballo','Rey'];
        $valores=[1,2,3,4,5,6,7,10,10,10];
        foreach($palos as $palo){
            for($i=0;$i<count($numeros);$i++){
                $this->cartas[]=new Carta($palo,$numeros[$i],$valores[$i]);
            }
        }
    }
    function barajar(){
        shuffle($this->cartas);
    }
}

$baraja=new BarajaMus();
$baraja->barajar();

Clase Departamento

<?php

/**
 * Description of Departamento
 *
 * @author incid
 */
class Departamento {
    private $nombre;
    private $gerente;
    private $num_empleados;
    /**
     * Esta función nos construye el objeto
     * Es muy bonita y está muy bien hecha
     * Saludos a mi clase que me está leyendo
     * 
     * @param string $nombre El nombre del departamento
     * @param string $gerente El gerente asignado
     * @param int $num_empleados Número de empleados
     */
    function __construct($nombre,$gerente,$num_empleados=2) {
        $this->setNombre($nombre);
        $this->setGerente($gerente);
        $this->setNum_empleados($num_empleados);
    }
    function getNombre() {
        return $this->nombre;
    }

    function getGerente() {
        return $this->gerente;
    }

    function getNum_empleados() {
        return $this->num_empleados;
    }

    function setNombre($nombre) {
        if(empty($nombre)){
            throw new Exception("El nombre no puede estar vacío");
        }
        $this->nombre = $nombre;
    }

    function setGerente($gerente) {
        if(empty($gerente)){
            throw new Exception("El gerente no puede estar vacío");
        }
        $this->gerente = $gerente;
    }

    function setNum_empleados($num_empleados) {
        if($num_empleados<1){
            throw new Exception("Tiene que tener al menos un empleado");
        }
        $this->num_empleados = $num_empleados;
    }
    
    function __toString() {
        return $this->getNombre()." - ".$this->getGerente()." - ".$this->getNum_empleados();
    }
     
     
}

$comercial=new Departamento("Comercial","Eva Pi");

$cad="Departamento: ".$comercial;

echo $cad;

Clase empleado

class Empleado {

    private $nombre;
    private $dni;
    private $sueldo;

    function __construct($nombre, $dni, $sueldo = 1000) {
        $this->setNombre($nombre) ;
        $this->setDni($dni);
        $this->setSueldo($sueldo);
    }

    function verEmpleado() {
        return $this->getNombre() . " - " . $this->getDni() . " - " . $this->getSueldo();
    }

    function sueldoNeto() {
        return $this->getSueldo() * 0.85;
    }

    private function validar_dni($dni) {
        $letra = substr($dni, -1);
        $numeros = substr($dni, 0, -1);
        if (substr("TRWAGMYFPDXBNJZSQVHLCKE", $numeros % 23, 1) == $letra && strlen($letra) == 1 && strlen($numeros) == 8) {
            return true;
        } else {
            return false;
        }
    }

    function setSueldo($sueldo) {
        if ($sueldo < 900) {
            throw new Exception("El sueldo no puede ser menor que el interprofesional");
        }
        $this->sueldo = $sueldo;
    }

    function setNombre($nombre) {
        if (empty($nombre)) {
            throw new Exception("El nombre no puede estar vacío");
        }
        $this->nombre = $nombre;
    }

    function setDni($dni) {
        if (!$this->validar_dni($dni)) {
            throw new Exception("DNI no válido");
        }
        $this->dni = $dni;
    }

    function getSueldo() {
        return $this->sueldo;
    }

    function getNombre() {
        return $this->nombre;
    }

    function getDni() {
        return $this->dni;
    }

}

$pepe = new Empleado("José Pérez", "12345678Z");
$pepe->setSueldo(2000); //Esto nos permite acceder a la propiedad
echo $pepe->verEmpleado();

Ejercicio constructor

En la siguiente clase vamos a añadir un constructor que nos obligue a poner el nombre, el dni, pero que el sueldo sea opcional (lo podemos pasar o no) y que si no lo pasamos por defecto valga 1000:

class Empleado {

    public $nombre;
    public $dni;
    public $sueldo;

    function verEmpleado() {
        return $this->nombre . " - " . $this->dni . " - " . $this->sueldo;
    }

    function sueldoNeto() {
        return $this->sueldo * 0.85;
    }

}

Solución:

class Empleado {

    public $nombre;
    public $dni;
    public $sueldo;

    function __construct($nombre, $dni, $sueldo = 1000) {
        if (empty($nombre)){
            throw new Exception("El nombre no puede estar vacío");
        }
        if(!$this->validar_dni($dni)){
            throw new Exception("DNI no válido");
        }
        if ($sueldo<900){
             throw new Exception("El sueldo no puede ser menor que el interprofesional");
        }
        $this->nombre = $nombre;
        $this->dni = $dni;
        $this->sueldo = $sueldo;
    }

    function verEmpleado() {
        return $this->nombre . " - " . $this->dni . " - " . $this->sueldo;
    }

    function sueldoNeto() {
        return $this->sueldo * 0.85;
    }

    function validar_dni($dni) {
        $letra = substr($dni, -1);
        $numeros = substr($dni, 0, -1);
        if (substr("TRWAGMYFPDXBNJZSQVHLCKE", $numeros % 23, 1) == $letra && strlen($letra) == 1 && strlen($numeros) == 8) {
            return true;
        } else {
            return false;
        }
    }

}