class — 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...
}

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

РЕДАКТИРОВАНИЕ

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

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!
}

РЕДАКТИРОВАТЬ 2

Существуют разные алгоритмы решения ваших проблем, которые зависят от вашего сценария. Я не могу представить весь сценарий, но из вашего вопроса. Вы хотите, чтобы тип Customer был общим в двух разных деревьях (Person и 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

Другие решения

ХОРОШО. Наконец-то я понял!

    Trait CustomerTrait {

}

interface Customer {

}

class CustomerCompany extends Company implements Customer {

use CustomerTrait;
}

class CustomerPrivate extends ContractorPrivate implements Customer {

use CustomerTrait;
}
0