-1

I have a class which implements an interface.

interface Animal {
    public static function giveHug();
}

class Dog() implements Animal {

    protected $race;

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

    public static function giveHug()
    {
        return 'Kiss my friend' . $this->race;
    }
}

I get

cannot use $this in non object context.

And I understand that, so how could I get Dog property in my redefined giveHug method ? Do someone have any trick to help? Thanks

Cutis
  • 949
  • 1
  • 13
  • 32
  • 1
    Static methods can only call static methods/properties. Thus; remove static. – Jordi Kroon Nov 19 '21 at 20:55
  • I have several classes using this interface. Do you have any trick to get this property? – Cutis Nov 19 '21 at 20:57
  • if you will create some Dogs, how a static function will understand which race you want to use? – splash58 Nov 19 '21 at 21:19
  • 1
    This is an limitation of `static` environment when you work in OOP. You should remove static from your method, but if it's mandatory for you to use it this way, so do like this (it will only show "Kiss my friend" of last `Dog` instance): `public function __construct($race) { $this->race = $race; self::$instance = $this; }` `public static function giveHug() { return 'Kiss my friend ' . self::$instance->race; }` – Lounis Nov 19 '21 at 21:31
  • `class Dog() ` -- that doesn't look like valid PHP. It would help if you extracted a [mcve] first, also to make sure you know what the problem really is. As others have mentioned, remove the `static` or describe why you think you need it. Also, I'd suggest you don't use `protected` members, make them `private` unless you have good (!) reasons. – Ulrich Eckhardt Nov 19 '21 at 22:06

1 Answers1

1

You need to change code either way.

If ::giveHug MUST be static, then you need to be able to provide the Animal to be hugged.

So this works:
but is not so nice

interface Animal
{
    public static function giveHug(Animal $animal);
}

class Dog implements Animal
{

    protected $race;

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

    public static function giveHug(Animal $animal)
    {
        return 'Kiss my friend ' . $animal->race;
    }
}

$dog = new Dog('WauWau');
echo Dog::giveHug($dog) . PHP_EOL;
// Kiss my friend WauWau

This is better:

interface Animal
{
    public static function getRace();

    public static function giveHug(Animal $animal);
}

class Dog implements Animal
{
    protected static $race;

    public function __construct($race)
    {
        self::$race = $race;
    }

    public static function getRace()
    {
        return self::$race;
    }

    public static function giveHug(Animal $animal)
    {
        return 'Kiss my friend ' . $animal::getRace();
    }
}

$dog = new Dog('WauWau');
echo Dog::giveHug($dog) . PHP_EOL;
// Kiss my friend WauWau

BUT now to the topic: does it make sense?

No.
And this is a really good example.
You do not tell a "static" animal (or dog) to give a hug.
You would want to tell a specific (object) animal to give a hug.

So this makes more sense:

interface Animal
{
    public function giveHug();
}

class Dog implements Animal
{
    protected $race;

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

    public function giveHug()
    {
        return 'Kiss my friend ' . $this->race;
    }
}

$dog = new Dog('WauWau');
// Note: we call $dog to give hug. So the ONE dog =)
echo $dog->giveHug() . PHP_EOL;
// Kiss my friend WauWau

EDIT: the example

$dog = new Dog('WauWau');
echo Dog::giveHug($dog) . PHP_EOL;

is more like a "Hey, all Dogs out there ... give a hug to this (Animal $dog)".
And there are cases this makes sense. But in this case - not =)

cottton
  • 1,522
  • 14
  • 29
  • Thanks to take time to explain this. I just create example of dog. the context is little bit different but i understand what you mean. I would still try your trick to see – Cutis Nov 19 '21 at 22:12