John Hunt
John Hunt

Reputation: 4072

Overriding grandparent methods in php

I'm currently writing a set of skeleton classes for an application, starting with a base class called StoreLogic which holds tax rules, discounting rules etc. The classes Cart, Order, Quote etc.. will extend StoreLogic as they'll all use the same set of methods StoreLogic provies.

Once those core classes are finished I'll implement them by extending Cart, Order, Quote AND StoreLogic as each application of those classes will be different depending on our various clients needs. Overriding methods from parent classes is easy, but overriding grandparent classes before their children have extended them seems...impossible? I get the feeling I'm doing this the wrong way(tm).. and I think someone more experienced like you might be able to point me in the right direction. Take a look at the code and see what you think!

/* My core classes are something like this: */
abstract class StoreLogic
{
    public function applyDiscount($total)
    {
        return $total - 10;
    }
}

abstract class Cart extends StoreLogic
{
    public function addItem($item_name)
    {
        echo 'added' . $item_name;
    }
}

abstract class Order extends StoreLogic
{
    // ....
}

/* Later on when I want to use those core classes I need to be able to override
 * methods from the grandparent class so the grandchild can use the new overriden
 * methods:
 */
class MyStoreLogic extends StoreLogic
{
    public function applyDiscount($total) {
        return $total - 5;
    }
}

class MyOrder extends Order
{
    // ...
}

class MyCart extends Cart
{
    public $total = 20;

    public function doDiscounts()
    {
        $this->total = $this->applyDiscount($this->total);
        echo $this->total;
    }
}

$cart = new MyCart();
$cart->doDiscounts(); // Uses StoreLogic, not MyStoreLogic..

Upvotes: 4

Views: 469

Answers (1)

Baba
Baba

Reputation: 95101

I think you are missing a very basic logic here

- MyCart extends Cart
- Cart extends StoreLogic

If you want to use MyStoreLogic then cart should be defined as

 abstract class Cart extends MyStoreLogic

If you don't want to do that then you can have

$cart = new MyCart();
$cart->doDiscounts(new MyStoreLogic()); // output 15

Class Modification

class MyCart extends Cart {
    public $total = 20;
    public function doDiscounts($logic = null) {
        $this->total = $logic ? $logic->applyDiscount($this->total) : $this->applyDiscount($this->total);
        echo $this->total;
    }
}

Upvotes: 3

Related Questions