0

I'm following along with some learning material on PHP and am now into abstract classes and methods as well as interfaces. While implementing interfaces I've encountered an error on first run-through. It happens while the classes and interfaces are being defined. I apologize in advance for the size of the code sample but I'd like to be circumspect.

The error I receive is:

'Fatal error: Declaration of DinnerMenu::setDinnerPortion() must be compatible with DinnerPortion::setDinnerPortion() in ... Menu.php on line 85'.

Menu.php follows:

<?php

abstract class Menu {   // can't be instanciated, only extended from

    private $_menuid,
            $_menuitemid,
            $_menuname,
            $_description;

    public function setMenuID($menuid) {$this->_menuid = $menuid;}
    public function getMenuID() {return $this->_menuid;}

    public function setMenuItemID($menuitemid) {$this->_menuitemid = $menuitemid;}
    public function getMenuItemID() {return $this->_menuitemid;}

    public function setMenuName($menuname) {$this->__menuname = $menuname;}
    public function getMenuName() {return $this->_menuname;}

    public function setDescription($description) {$this->_description = $description;}
    public function getDescription() {return $this->_description;}

}

class MenuItem {

    private $_menuitemid,
            $_itemname,
            $_description,
            $_price,
            $_servingsize,
            $_picture;

    public function setID($menuitemid) {$this->_menuitemid = $menuitemid;}
    public function getID() {return $this->_menuitemid;}

    public function setItemName($itemname) {$this->_itemname = $itemname;}
    public function getItemName() {return $this->_itemname;}

    public function setDescription($description) {$this->_description = $description;}
    public function getDescription() {return $this->_description;}

    public function setPrice($price) {$this->_price = $price;}
    public function getPrice() {return $this->_price;}

    public function setServingSize($servingsize) {$this->_servingsize = $servingsize;}
    public function getServingSize() {return $this->_servingsize;}

    public function setPicture($picture) {$this->_picture = $picture;}
    public function getPicture() {return $this->_picture;}

}

class MainMenu extends Menu {

}

class DrinkMenu extends Menu {

}

class LunchMenu extends Menu {

}

final class KidsMenu extends Menu {     // final keyword stops inheritance: cannot have sub-classes or child classes, cannot be overridden

}

final class DessertMenu extends Menu {

}

interface DinnerPortion {
    public function setDinnerPortion();
}

interface DinnerPrices {
    public function setDinnerPrices();
}

interface HappyHourDrinkPrices {
    public function setHappyHourDrinkPrices();
}

final class DinnerMenu extends LunchMenu implements DinnerPortion, DinnerPrices {
    public function setDinnerPortion($menuitemObject) {
        $adjusted_servingsize = 1;
        $base_servingsize = $menuitemObject->getServingSize();
        // dinner portion 50% bigger than lunch portion
        $adjusted_servingsize = $base_servingsize * 1.5;
        return $adjusted_servingsize;
    }

    public function setDinnerPrices($menuitemObject) {
        $adjusted_price = 1;
        $base_price = $menuitemObject->getPrice();
        // dinner price 25% more than lunch price
        $adjusted_price = $base_price * 1.25;
        return $adjusted_price;
    }
}

final class HappyHourMenu extends DrinkMenu implements HappyHourDrinkPrices {
    public function setHappyHourDrinkPRices($drinkObject) {
        $adjusted_price = 1;
        $base_price = $drinkObject->getPrice();
        // happy hour drink prices 30% less than regular prices
        $adjusted_price = $base_price * 0.7;
        return $adjusted_price;
    }
}

?>

3 Answers 3

3

setDinnerPortion in the interface doesn't have an argument, while the same method in the class DinnerMenu (which implements the interface) has the argument $menuitemObject.

An interface describes rules that a class must obey. In this case it defines that the class needs to implement this method without arguments.

Sign up to request clarification or add additional context in comments.

2 Comments

I threw a '$p' in each and it loads successfully now, thanks. I wonder why the text would be represented this way then! Amazing, but having an argument in the interface makes perfect sense.
The message says 'Should be compatible', and that's basically what it means: their declarations should match. That means at least the same number of arguments, but also no mixing of static/non-static and having the same type-hinting (if any) for the arguments.
0

If you want to use interfaces with their methods, you have to take over the methods which are described in the interface.

From your interface ;

 public function setDinnerPortion($menuitemObject)

The above method requires an argument while the method in your class which implements the interface doesn't have it

 public function setDinnerPortion()

Solution : add an argument.

Comments

0

in your class the signature is :

 public function setDinnerPortion($menuitemObject)

although in your interface the function signature is :

public function setDinnerPortion(); 

These function signatures must be the same !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.