Not when the child has its own constructor. Only one construct will be called. EDIT: This is the case for any magic method (destruct, etc)
class Parent {
public function __construct() {
echo "I'm a parent.\
";
}
}
class Child extends Parent {
public function __construct() {
echo "I'm a child.\
";
}
}
$t = new Child(); // I'm a child.
This is why you’ll see your class calling parent construct…
class Parent {
public function __construct() {
echo "I'm a parent.\
";
}
}
class Child extends Parent {
public function __construct() {
parent::construct();
echo "I'm a child.\
";
}
}
$t = new Child();
// I'm a parent.
// I'm a child.
So with that being said, I’m not sure I’d say that :: is used for static methods as you can call any public function in the parent in the same way I just called the constructor.
Thanks. Your example makes sense, I think I’m getting tripped up on the syntax itself.
Here’s the original question and answer that got me Googling before posting:
Q. What’s the difference between accessing a class method via -> and via ::?
A. :: is allowed to access methods that can perform static operations, i.e. those, which do not require object initialization.
So is :: only used inside of classes to call other public functions? Or is it possible to see it in general script logic, outside of classes? And is the above answer accurate?
Well honestly I’m not an expert on it, to be able to perfectly explain the difference. The only time I use :: is to access a class name explicitly (shouldn’t be needed unless you’ve poorly named your functions to close together), call the parent, or call a static variable within that class, which is the one I commonly use:
MyClass {
private static $var = 'foo';
public function bar() {
echo self::$var;
}
}
To answer one of your questions. I believe you will ONLY see :: related to classes. Either accessing a function/method, a variable, or a constant. I have not seen :: used outside of an OOP approach (but that’s not to say it doesn’t exist there).
The :: is just a mechanism to separate the class name from the method/function, variable, and/or constant that is being referenced in that class. Just like -> is used to separate the class reference variable from the method/function or variable of that given reference. Or \ is used to identify Namespace separation: \Namespace\ClassName::MethodName for example.
class A {
public function foo {
echo 'Bah';
}
}
class B extends A {
public function foo {
parent::foo();
echo 'Bah!';
}
}
$a = new A();
$a->foo(); // Bah
$b = new B();
$b->foo(); // Bah Bah
So with that being said, I’m not sure I’d say that :: is used for static methods as you can call any public function in the parent in the same way I just called the constructor.
parent::method isn’t the same thing as Class::method. Confused? Welcome to PHP.
Parent is a magic invocation to call the copy of the method in the parent class. For sanity reasons it should only be used by overriding method calls, though nothing in PHP stops you from using it incorrectly you will be very, very sorry if you do (I learned this one from experience. Talk about nightmare to debug code).
Outside of a child method calling the parent in an override situation, the Paamayim Nekudotayim or :: is only used in a static context as was pointed out previously in the thread.
class A {
public function foo() { return 1; }
public function bar() { return 2; }
public function mar() { return 3; }
}
class B extends A {
public function foo() { return parent::foo(); }
public function bar() { return 10; }
public function lambda() { return 4; }
}
class C extends B {
public function foo() { return parent::mar(); }
}
Now, months later, a maintanence programmer goes in and adds a mar method to B. That’ll mess up C->foo unexpectedly. As projects grow so to does the complexity of their interactions, and allowing class methods to bypass their sister methods opens up an enormous can of worms and makes code go spaghetti crazy in short order. I know this one particularly because I made that mistake in my first year. Don’t do it.
That’s a very good example. However the same thing can happen even if you’re using parent::method() calls “correctly”.
Consider this:
class A {
public function foo() { return 1; }
public function bar() { return 2; }
public function mar() { return 3; }
}
class B extends A {
public function bar() { return 10; }
public function lambda() { return 4; }
}
class C extends B {
public function foo() { return parent::foo(); }
}
C::foo() is expecting to call A::foo(). If B::foo() is defined at a later date, the behaviour of C::foo() may change unexpectedly. This may or may not be desirable. The problem the person who is making changes to the class B has, is that they don’t know whether or not any classes are extending it and what effect evenly seemingly safe changes may have on subclasses. This is an example of the Fragile base class problem
If you need complex inheritance trees it’s more likely there’s a poor separation of concerns. Do the subclasses really use all those inherited behaviours? Probably not! The real answer is to favour composition over inheritance or use interfaces.
I hardly consider that to be an unexpected change. Also, composition has problems of its own. To me its a matter of right tool for the job, and includes design patterns.
For classes which can be instantiated, you do so by assigning the instance to a variable.
class thing{}
$a= new thing();
Non-static methods/ properties will be changed within the instance alone.
$a->someProp=$newval;
so essentially you use -> to reach a non-static method/or property.
on the other hand static methods and properties, which by their definition cannot be instantiated , you are actually dealing directly with the CLASS itself and not an instance of the class. to reach these you use ::.
:: can be used out side the class definition, accessing a singleton object, for example. or inside a class, you may have even seen :: parent as a way to access a property at the PARENT LEVEL of a class.