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
929 views
in Technique[技术] by (71.8m points)

oop - Why does PHP allow "incompatible" constructors?

Here's a couple of snippets:

  1. Overriding constructor method has an extra parameter.

    class Cat {
        function __construct() {}
    }
    
    class Lion extends Cat {
        function __construct($param) {}
    }
    
  2. Overriding (regular) method has an extra parameter.

    class Cat {
        function doSomething() {}
    }
    
    class Lion extends Cat {
        function doSomething($param) {}
    }
    

The first would work, while the second would throw Declaration of Lion::doSomething() should be compatible with that of Cat::doSomething().

Why the special attitude towards constructor methods?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

To understand why they are treated differently, you have to understand Liskov's Substitution Principle, which states

If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T." - BarbaraLiskov, Data Abstraction and Hierarchy, SIGPLAN Notices, 23,5 (May, 1988).

In a nutshell this means any class using your Lion or Cat should be able to reliably call doSomething on it, regardless of the class being one or the other. If you change the method signature, this is no longer guaranteed (you may widen it, but not narrow it though).

Very simple Example

public function doSomethingWithFeline(Cat $feline)
{
    $feline->doSomething(42);
}

Since Lion extends Cat, you established an is-a relationship, meaning doSomethingWithFeline will accept a Lion for a Cat. Now imagine you add a required argument to doSomething in Lion. The code above would break because it is not passing that new param. Hence, the need for compatible signatures.

LSP does not apply to constructors though, because subtypes might have different dependencies. For instance if you have a FileLogger and a DBLogger, the ctors (constructors) of the first would require a filename, while the latter would require a db adapter. As such, ctors are about concrete implementations and not part of the contract between classes.


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

...