Can php class extend two classes?

EDIT: 2020 PHP 5.4+ and 7+

As of PHP 5.4.0 there are "Traits" - you can use more traits in one class, so the final deciding point would be whether you want really an inheritance or you just need some "feature"[trait]. Trait is, vaguely said, an already implemented interface that is meant to be just used.

Currently accepted answer by @Franck will work but it is not in fact multiple inheritance but a child instance of class defined out of scope, also there is the `__call[]` shorthand - consider using just `$this->childInstance->method[args]` anywhere you need ExternalClass class method in "extended" class.

Exact answer

No you can't, respectively, not really, as manual of extends keyword says:

An extended class is always dependent on a single base class, that is, multiple inheritance is not supported.

Real answer

However as @adam suggested correctly this does NOT forbids you to use multiple hierarchal inheritance.

You CAN extend one class, with another and another with another and so on...

So pretty simple example on this would be:

class firstInheritance{}
class secondInheritance extends firstInheritance{}
class someFinalClass extends secondInheritance{}
//...and so on...

Important note

As you might have noticed, you can only do multiple[2+] intehritance by hierarchy if you have control over all classes included in the process - that means, you can't apply this solution e.g. with built-in classes or with classes you simply can't edit - if you want to do that, you are left with the @Franck solution - child instances.

...And finally example with some output:

class A{
  function a_hi[]{
    echo "I am a of A".PHP_EOL."
".PHP_EOL; } } class B extends A{ function b_hi[]{ echo "I am b of B".PHP_EOL."
".PHP_EOL; } } class C extends B{ function c_hi[]{ echo "I am c of C".PHP_EOL."
".PHP_EOL; } } $myTestInstance = new C[]; $myTestInstance->a_hi[]; $myTestInstance->b_hi[]; $myTestInstance->c_hi[];

Which outputs

I am a of A 
I am b of B 
I am c of C 

Inheritance is a well-established programming principle, and PHP makes use of this principle in its object model. This principle will affect the way many classes and objects relate to one another.

For example, when extending a class, the subclass inherits all of the public and protected methods, properties and constants from the parent class. Unless a class overrides those methods, they will retain their original functionality.

This is useful for defining and abstracting functionality, and permits the implementation of additional functionality in similar objects without the need to reimplement all of the shared functionality.

Private methods of a parent class are not accessible to a child class. As a result, child classes may reimplement a private method themselves without regard for normal inheritance rules. Prior to PHP 8.0.0, however, final and static restrictions were applied to private methods. As of PHP 8.0.0, the only private method restriction that is enforced is private final constructors, as that is a common way to "disable" the constructor when using static factory methods instead.

The visibility of methods, properties and constants can be relaxed, e.g. a protected method can be marked as public, but they cannot be restricted, e.g. marking a public property as private.

Note:

Unless autoloading is used, the classes must be defined before they are used. If a class extends another, then the parent class must be declared before the child class structure. This rule applies to classes that inherit other classes and interfaces.

Note:

It is not allowed to override a read-write property with a readonly property or vice versa.

Example #1 Inheritance Example

Return Type Compatibility with Internal Classes

Prior to PHP 8.1, most internal classes or methods didn't declare their return types, and any return type was allowed when extending them.

As of PHP 8.1.0, most internal methods started to "tentatively" declare their return type, in that case the return type of methods should be compatible with the parent being extended; otherwise, a deprecation notice is emitted. Note that lack of an explicit return declaration is also considered a signature mismatch, and thus results in the deprecation notice.

If the return type cannot be declared for an overriding method due to PHP cross-version compatibility concerns, a #[ReturnTypeWillChange] attribute can be added to silence the deprecation notice.

Example #2 The overriding method does not declare any return type

Example #3 The overriding method declares a wrong return type

Example #4 The overriding method declares a wrong return type without a deprecation notice

jackdracona at msn dot com

12 years ago

Here is some clarification about PHP inheritance – there is a lot of bad information on the net.  PHP does support Multi-level inheritance.  [I tested it using version 5.2.9].  It does not support multiple inheritance.

This means that you cannot have one class extend 2 other classes [see the extends keyword].  However, you can have one class extend another, which extends another, and so on.

Example:

Mohammad Istanbouly

5 years ago

I think the best way for beginners to understand inheritance is through a real example so here is a simple example I can gave to you

strata_ranger at hotmail dot com

12 years ago

I was recently extending a PEAR class when I encountered a situation where I wanted to call a constructor two levels up the class hierarchy, ignoring the immediate parent.  In such a case, you need to explicitly reference the class name using the :: operator.

Fortunately, just like using the 'parent' keyword PHP correctly recognizes that you are calling the function from a protected context inside the object's class hierarchy.

E.g:

niemans at pbsolo dot nl

2 years ago

Inheritance works at create time, i.e. using the keyword 'new'. Static properties confused my understanding, so in order tho show the effect of visibility to inherintence I've created a simple demo script along with some set and get magic:



This outputs:

set e=constructed
B:c=public
get d set d=dynamic B:d=dynamic
set e=constructed2
A Object
[
    [a:A:private] => private
    [b:protected] => protected
    [c] => public
    [e] => constructed
]
B Object
[
    [a:A:private] => private
    [b:protected] => protected
    [c] => public
    [d] => dynamic
]
C Object
[
    [a:A:private] => private
    [b:protected] => protected
    [c] => public
    [e] => constructed2
]
staticstaticstaticA class: Array
[
    [d] => static
    [a] => private
    [b] => protected
    [c] => public
]
Array
[
    [d] => static
]
B class: Array
[
    [d] => static
    [b] => protected
    [c] => public
]
Array
[
    [d] => static
]

This shows how private variables [$a] are inherited, how static variables [$d] are inherited [by the class, not by the object] and that changing or adding variables in the parent [$e, $d] are not inherited by the child.

jarrod at squarecrow dot com

12 years ago

You can force a class to be strictly an inheritable class by using the "abstract" keyword. When you define a class with abstract, any attempt to instantiate a separate instance of it will result in a fatal error. This is useful for situations like a base class where it would be inherited by multiple child classes yet you want to restrict the ability to instantiate it by itself.

Example........

Anonymous

3 years ago

PHP7 gives you a warning if you redeclare a function in a child class with different parameters. For example:

class foo {
     function print[$text=''] {
          print text;
     }
}

class bar extends foo {
      function print[$text1='',$text2=''] {
           print text1.text2
      }
}

will give a PHP Warning:  Declaration of bar::print[$text1 = '', $text2 = ''] should be compatible with foo::print[$text= ''].

Sam Tigall

3 years ago

Overriding a method which is called from base class works like this:

sibian0218 at gmail dot com

4 years ago

I've noticed one thing concerning inheritance...
When declaring an abstract class with a private method,
which is overridden by a sub-class, private takes precedence over public for child class...
[in the case you're redeclaring a method with a different signature in fact].

Hope this helps

nemanja

5 years ago

Even when autoloading [SPL] is used, class inheritance does not seem to work. Simply the PHP engine is unable to find parent [inherited] class. PHP 5.6 and 7.0 behave exactly same on this, which beats the purpose of autoloading.

And IMHO it's easy to fix as the autoloader is able to find all first level classes w/o problems, it just needs to follow same path recursively on parents too.

Chủ Đề