简体   繁体   中英

php abstract classes and interfaces

I have the following scenario:

    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
    }

And the same happens with suppliers and dealers, which can be private persons or companies. The problem now is the following: how to force object of class CustomerPrivate and CustomerCompany to be, at the same time, of class Customer (which I have not defined yet) and the same for suppliers and dealers. It is a good practice to use interfaces in such a case?

    interface Customer {
    }

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

Thanks for any suggestion!

METHOD 1

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

METHOD 2

$obj = new CustomerPrivate();

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

You can do this for any class you want

EDITED

Yes you can you interfaces, as you posted

interface Customer
{
}

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

OR

You can use traits. Traits are very flexible but they are only supported in PHP 5.4 or higher

trait Customer
{

}

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

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

EDIT 2

There are different algorithm for solving your problems which depends on your scenario. I cant imagine whole scenario but from your question. you want to have Customer type common in two different tree ( Person and Company ), in this context linear hierarchy is a problem, so i might have used something like this.

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);
        }
    }
}

OK. I got it finally!

    Trait CustomerTrait {   

    }

    interface Customer {    

    }

    class CustomerCompany extends Company implements Customer { 

       use CustomerTrait;
    }   

   class CustomerPrivate extends ContractorPrivate implements Customer { 

       use CustomerTrait;
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM