Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
200 views
in Technique[技术] by (71.8m points)

php - How to solve method overloading in subclass (Declaration of ... should be compatible with )?

The example should demonstrate it best:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($a,$b);
    }


}

class Wanter extends Generic {
    public static function create($b) {
        return parent::create("I want",$b);
    }
}

Generic::foo("I need","coffee!");
Wanter::foo("coffee!");

Expected output:

I need coffee!I want coffee!

Actual output:

Warning: Declaration of Wanter::create($b) should be compatible with Generic::create($a, $b) in [...][...] on line 25 I need coffee!I want coffee!

It is obvious what this should do (as it does). However I want to run this without throwing warnings of course. How to implement this without warning?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It should be obvious but the child method definition must match that of the parent, so you are missing an argument.

What I would do is this:

class Generic {
    protected $a;
    protected $b;

    protected final function __construct($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

    public static function create($a,$b) {
        return new self($b,$a); //reverse arguments
    }


}

class Wanter extends Generic {
    public static function create($a, $b="I want") {
        return parent::create($b,$a);
    }
}

Note that I changed the order of the arguments, this way the one with the default is the second argument.

You could do this just in the child, but it might be somewhat confusing, if the order is different then the parent class.

That said, something like a factory method may be more appropriate in this instance.

https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)

Besides a factory pattern I am not sure how important it is for you to have the static Create method. The constructor offers more flexibility when needing things like polymorphism. For example something like this would be acceptable

abstract class Generic {
   protected $a;
   protected $b;

   protected function create($a,$b) {
        $this->a = $a;
        $this->b = $b;
        echo $this->a." ".$this->b;
    }

}

class Wanter extends Generic {
    public function __construct($a) {
        return $this->create("I want",$a);
    }
}

Then each child can define it's own constructor, with its own set of required arguments.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...