2014-12-04 69 views
4

所以我有2類:讓我們稱之爲人與車PHP OO - 如何建立類關係之間X有許多Ÿ

我需要之前,我可以訪問我的汽車類從我的人對象的某些屬性實例。

我只是說些什麼的順序:$car = new Car($person);
如果是,那麼我如何訪問我的汽車類中的這些對象屬性?它會是這樣的:

class Car{ 

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

} 

如果不是,將有什麼辦法實現這一點?

+5

這正是如何做到這一點。這個名稱是「依賴注入」,因此您將實例化對象傳遞給構造函數,而不是在需要它們的對象內實例化它們。你將它分配給'$ this-> person',這樣你就可以在內部像'$ this-> person-> name'那樣使用它 – 2014-12-04 18:57:25

+2

你回答了你看到的問題,儘管你沒有在你的問題中真正談論過「問題標題中提到了很多「方面。 – 2014-12-04 19:04:23

+1

@MichaelBerkowski會破壞Person封裝 – Weltschmerz 2014-12-04 19:23:20

回答

0

如果我們想從封裝的角度看它,我們需要考慮它。可以,如果一輛汽車知道一個人在裏面?也許我們需要一個採用這個參數的服務/控制器?

function processSomething(Person $person, Car $car) {} 

但是你的例子並不糟糕。這取決於用例。它的行事方式,如果一輛汽車可能知道他的人。

如果你可以有多個個人,你可以有這樣的構造:

public function __construct(array $personList) { 
    //Check for a person 
    if (count($personList) < 1) { 
     throw new Exception('No person given'); 
    } 

    //Validate list 
    foreach ($personList as $person) { 
     if (!$person instanceof Person) { 
      throw new Exception('This is not a person'); 
     } 
    } 

    //Keep persons 
    $this->personList = $personList; 
} 

另外請注意,如果我們希望有多個對象在我們班,我們可以做出一個ContainerObject:

class ContainerObject { 
    public $person; 
    public $moreInfo; 
    public $manyMoreInfo; 
} 

class Person { 
    public function sayHello() {}; 
} 

class Car { 
    private $containerObj; 

    function __construct(ContainerObject $obj) { 
     $this->containerObj= $obj; 
    } 

    function foo() { 
     $this->containerObj->person->sayHello(); 
    } 
} 
1

我們在這裏有一些困惑。現實世界中的OOP,考慮和比較:

一個或由人買:

$person->addCar($car); 

一個正在進入(以坐在左前座上):

$car->addPerson($person, Car::SEAT_FRONT_LEFT); 

其中Car::SEAT_FRONT_LEFTCarpublic const的成員。

爲了能夠構建工作對象,這些關係對於保持語義正確性很重要。

-

要實現這一點,它可能有助於查找(Aware - )的含義Interface

例類我可能會定義:

interface Person { 
    public function getHeight(); 
    public function setHeight(); 
} 

class CarOwner implements Person { 
    protected $height; 
    protected $cars = array(); 

    public function getHeight(); 
    public function setHeight(); 

    public function getCars(); 
}; 

class Driver implements Person { 
    protected $height; 

    public function getHeight(); 
    public function setHeight(); 
}; 

class Car { 
    protected $persons = array(); // @var array 
    protected $readyToDrive = false; 

    public const SEAT_FRONT_LEFT = 1; 
    public const SEAT_FRONT_RIGHT = 2; 
    // ... 

    public function addPerson(Person $person, $seat) { 
     if ($person instanceof Driver) { 
      $this->isReadyToDrive(true); 
     } 

     // I know this is stupid but you get the point: 
     if ($this->getDriver()->getHeight() < 140 && $this->getSeat()->getPosition() > 40) { 
      throw new Exception('please set the seat to fit your height!'); 
     } 

     if (!in_array($person, $this->persons)) { 
      $this->persons[$seat] = $person; 
     } 
     else { 
      throw new Exception('person is already in the car!'); 
      // Person first needs to "leave" the car! like: 
      // $car->removePerson($person)->addPerson($person, Car::SEAT_REAR_LEFT); 
     } 
    } 


    public function getDriver() { 
     if (isset($persons[self::SEAT_FRONT_LEFT]) && $persons[self::SEAT_FRONT_LEFT] instanceof Driver) { 
      return persons[self::SEAT_FRONT_LEFT]; 
     } 
     else { //... } 
    } 
};