Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <blockquote> <p>Now I've heard over and over again that a parent class should NOT rely on the child class to implement functionality </p> </blockquote> <p>Exactly. And your <code>switch</code> would be such an unwanted dependency, while a call to <code>getPrice</code> would not, as long as it's defined as an abstract method in the parent and overridden in the children. Then the parent class does not need to know the concrete child classes and still can call their methods. If that sounds strange to you, read about polymorphism, it's important to understand this concept to understand OOP.</p> <p>But your problem goes deeper:</p> <blockquote> <p>Here is the main point: How do I call a child method if have only a productid? (In the above scenario, the Product class retrieves the type from the database in the constructor and populates the $type property accordingly.</p> </blockquote> <p>Obviously you don't ever create instances of Chainsaw or Toothbrush. You can't create a product with <code>new Product</code> and afterwards tell it "now you are a chainsaw". <strong>The actual type of an object is immutable.</strong> You tried to get around that with creating a new chainsaw inside of the product that was supposed to be a chainsaw just to have access to its price. This is horribly wrong and I think you already realized it.</p> <p>This is why the factory pattern was suggested in the comments. A factory is a class that instantiates objects and decides which subtype is used based on parameters. Also it is a valid place for such a switch statement.</p> <p><strong>Example:</strong></p> <pre><code>class ProductFactory { public function makeProduct($id) { $record = perform_your_database_lookup_here(); switch ($record['type']) { case 'toothbrush': return new Toothbrush($id, $record); case 'chainsaw': return new Chainsaw($id, $record); } } } $factory = new ProductFactory(); $product = $factory-&gt;makeProduct(123); echo $product-&gt;getPrice(); </code></pre> <p>For simplicity I put the database lookup in the factory. A better solution would be to have it completely separated from both classes, for example in a <code>ProductTableGateway</code> class that would be responsible for all database queries related to the products table. The factory then would only recieve the result.</p> <p>By the way, I'd also recommend to get rid of these subclasses in the end. No serious online shop has hard coded classes for each product type, instead different attribute sets are created dynamically and different price calculations are delegated to other classes. But this is an advanced topic, which would go too far now.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload