2016-05-29 6 views
0

У меня есть следующий сценарий:PHP абстрактные классы и интерфейсы

abstract class Contractor { 
    // Generic contractor methods...   
    } 

    abstract class PrivatePerson extends Contractor { 
    // Adds methods specific to private contractors 
    } 

    abstract class Company extends Contractor { 
    // Adds methods specific to Company contractors 
    } 

    class CustomerPrivate extends PrivatePerson { 
    // Customers that are contractors, but physical persons 
    } 

    class CustomerCompany extends Company { 
    // Customers that are contractors, but companies 
    } 

И то же самое происходит с поставщиками и дилерами, которые могут быть частные лица или компании. Теперь проблема заключается в следующем: как заставить объект класса CustomerPrivate и CustomerCompany быть в то же время класса Customer (который я еще не определил), а также для поставщиков и дилеров. В этом случае рекомендуется использовать интерфейсы?

interface Customer { 
    } 

    class PrivateCustomer extends PrivatePerson implements Customer { 
    // Customers that are physical persons, but are CUSTOMERS! 
    } 

Спасибо за предложение!

ответ

0

МЕТОД 1

class CustomerPrivate extends PrivatePerson 
{ 
    public function __construct() 
    { 
     if($this instanceof Customer) 
     { 
      //CODE 
     } 
     else 
     { 
      throw new \Exception("YOU ERROR MESSAGE", 1); 
      # code... 
     } 
    } 
} 

МЕТОД 2

$obj = new CustomerPrivate(); 

if ($obj instanceof Customer) 
{ 
    //CODE 
} 
else 
{ 
    # code... 
} 

Вы можете сделать это для любого класса, который вы хотите

EDITED

Да, вы можете вы интерфейсы, как вы размещены

interface Customer 
{ 
} 

class PrivateCustomer extends PrivatePerson implements Customer 
{ 
    // Customers that are physical persons, but are CUSTOMERS! 
} 

ИЛИ

Вы можете использовать черты. Черты характера является очень гибким, но они поддерживаются только в PHP 5.4 или выше

trait Customer 
{ 

} 

class PrivateCustomer extends PrivatePerson 
{ 
    use Customer; //trait customer 
    use OtherTrait; 

    // Customers that are physical persons, but are CUSTOMERS! 
} 

EDIT 2

Есть другой алгоритм для решения ваших проблем, зависит от сценария. Я не могу представить весь сценарий, но из вашего вопроса. вы хотите, чтобы тип клиента был общим в двух разных деревах (Person and Company), в этом контексте линейная иерархия является проблемой, поэтому я мог бы использовать что-то вроде этого.

abstract class Contractor 
{ 
    public function isCustomer() 
    { 
     return FALSE; 
    } 
} 


trait Customer 
{ 
    public function isCustomer() 
    { 
     return TRUE; 
    } 
} 

class CustomerCompany extends Company 
{ 
    \\use Customer; 

    public function __construct() 
    { 
     if(!$this->isCustomer()) 
     { 
      throw new \Exception('ERROR', 1); 
     } 
    } 
} 
+0

Но как объекты класса CustomerPrivate могут быть экземплярами клиента одновременно? Как я должен определить класс Customer? – mlattari

+0

Спасибо вам большое! Вы мне очень помогли. – mlattari

+0

I jus попробовал с чертами, но частично решает проблему. Я могу использовать свойства и методы в чертах для объектов, но объекты не являются экземплярами черт ... С интерфейсами у меня противоположная ситуация ;-) – mlattari

0

ОК. Я получил это наконец!

Trait CustomerTrait { 

    } 

    interface Customer {  

    } 

    class CustomerCompany extends Company implements Customer { 

     use CustomerTrait; 
    } 

    class CustomerPrivate extends ContractorPrivate implements Customer { 

     use CustomerTrait; 
    } 
Смежные вопросы