<?php

/**
 * (1)抽象类:象类不能直接被实例化,你必须先继承该抽象类,然后再实例化子类。
 * (2)任何一个类, 如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
 * (3)如果类方法被声明为抽象的, 那么其中就不能包括具体的功能实现。
 */

abstract class Calculator
{
    private $num1;
    private $num2;
    public  $result;
    
    public function getNum1()
    {
      return $this->num1;
    }
    
    public function setNum1($num1)
    {
       $this->num1 =$num1;
    }
    
    public function getNum2()
    {
      return $this->num2;
    }
    
    public function setNum2($num2)
    {
       $this->num2 =$num2;
    }
    
    abstract function getResult($num1,$num2);
}

/**
 * (1)继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法;
 * (2)另外,这些方法的可见性 必须和抽象类中一样(或者更为宽松)。如果抽象类中某个抽象方法被声明为protected,
 *  那么子类中实现的方法就应该声明为protected或者public,而不 能定义为private。
 */

class Add extends Calculator
{
   
    function getResult($num1,$num2)
    {
        return $num1 + $num2;
    }
}

class Sub extends Calculator
{
     
     function getResult($num1,$num2)
    {
        return $num1 - $num2;
    }
}
class Mul extends Calculator
{
     
     function getResult($num1,$num2)
    {
        return $num1 * $num2;
    }
}

class Div extends Calculator
{
    
     function getResult($num1,$num2)
    {
        if($num2==0)
        {
             return false;
        }else{
             return $num1 / $num2;
        }
    }
}

/**
 *工厂模式(Factory)允许你在代码执行时实例化对象。
 *它之所以被称为工厂模式是因为它负责“生产”对象。
 *工厂方法的参数是你要生成的对象对应的类名称
 */

class CalculatorFactory
{
    
    public function createFactory($operate)
    {
        switch($operate)
       {
          case "+":
            $ope = new Add();
            break;
          case "-":
            $ope = new Sub();
            break;
          case "*":
            $ope = new Mul();
            break;
          case "/":
            $ope = new Div();
            break;
       }
       return $ope;
    }
}

$operate="*";
$num1=2;
$num2=3;
$obj= CalculatorFactory::createFactory("*");
var_dump($obj->getResult($num1,$num2));

?>