Why trait does not override method in class? - php

I wonder if my php interpreter doesn't work correctly or if I'm understanding Traits wrong. Here's my piece of code:
<?php
trait ExampleTrait{
public function foo()
{
echo 'y';
}
}
class ExampleClass
{
use ExampleTrait;
public function foo()
{
echo 'x';
}
}
$exCl = new ExampleClass();
$exCl->foo();
I assume this should show "y", but it shows "x" instead. Why?

Read this carefully Trait documentation I recommend to try out every example and make your own modifications to be sure you understand it. There is my example, hope it helps:
<?php
class A {
public function foo() {
echo "x";
}
}
class B extends A {}
$test = new B();
$test->foo();
// result X
This is pretty clear I think, so now lets use a Trait:
<?php
class A {
public function foo() {
echo "x";
}
}
trait T {
public function foo() {
echo "y";
}
}
class B extends A {
use T;
}
$test = new B();
$test->foo();
// result y
As you can see the Trait method overwrites the base class method. And now lets create a foo method in the B class
<?php
class A {
public function foo() {
echo "x";
}
}
trait T {
public function foo() {
echo "y";
}
}
class B extends A {
use T;
public function foo() {
echo "z";
}
}
$test = new B();
$test->foo();
// result z
An inherited member from a base class is overridden by a member inserted by a Trait. The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.

Related

How to make an abstract variable static to a sub class

<?php
abstract class A {
public static $var = "A";
public function setVar() {
}
public function test() {
$this->setVar();
echo static::$var;
}
public function returnVar() {
return static::$var;
}
}
class B extends A {
public function setVar() {
static::$var = 'B';
}
}
class C extends A {
public function setVar() {
static::$var = 'C';
}
}
$class = new B();
$class->test();
$class2 = new C();
$class2->test();
echo "</br>";
echo $class->returnVar();
echo $class2->returnVar();
?>
What I'm trying to do is make the variable $var static to the class that extends abstract class A without having to re-declare it else where.
So say perhaps I create multiple objects from class B that extends A, I want all objects made from class B to share the same $var value.
Say I then create objects based on class C, they should all share the same value of $var...
This is the result I'm currently getting:
BC
CC
However, what I'm looking for is:
BC
BC
Thanks
Try it like that:
#setting
public function setVar() {
static::$var[get_class($this)] = 'B';
}
#getting in abstract
public function returnVar() {
return static::$var[get_class($this)];
}
#add this in the abstract class
public function setVar();

What is different between $this-> and parent:: in OOP PHP?

I code something like this to give you an example
This is using "$this->"
<?php
class A{
public function example(){
echo "A";
}
}
class B extends A{
public function example2(){
$this->example();
}
}
$b = new B();
echo $b->example2();
?>
and This is using parent::
<?php
class A{
public function example(){
echo "A";
}
}
class B extends A{
public function example2(){
parent::example();
}
}
$b = new B();
echo $b->example2();
?>
What is different between $this-> and parent:: in OOP PHP?
The difference is that you can access a function of a base class and not of the currient implementation.
class A {
public function example() {
echo "A";
}
public function foo() {
$this->example();
}
}
class B extends A {
public function example() {
echo "B";
}
public function bar() {
parent::example();
}
}
And here some tests:
$a=new A();
$a->example(); // echos A
$a->foo(); // echos A
$b=new B();
$b->example(); // echos B
$b->foo(); // echos B
$b->bar(); // echos A
parent::example() calls the parent class method, where $this->example() call the current class method.
In your example there's no difference, since class B doesn't override example() method. It is common to write something like this (maybe it will help you to understand better this concept):
class A {
public function example(){
echo 'A';
}
}
class B extends A {
public function example(){
echo 'B';
}
public function example2(){
$this->example();
}
public function example3() {
parent::example();
}
}
$b = new B();
$b->example2();//print B
$b->example3();//print A
In simple words
$this is an instance reference, so whenever you use $this it starts referencing current class methods and properties.
parent is a parent reference which can be used to access parent class properties and methods with public or protected access modifier.
parent:: will call a method or an attribute of the parent. However, since this is refering to the class and not any kind of instance, you can only call a static method or attribute.
$this-> refers to the current instance of the object you call this in.
You could also want to refer to self:: which refers to the current class (once again, no instance involved here) within an object or a static method.

How to make the inherited class run a method from same class in PHP

Whats wrong with me OOP here.
I want to inherit from Class A
The return_output method will do something common so I don't want to write that in the inherited classes.
However when I do B->return_output() I want it to run the do_something method in Class B, but I see that it always runs the method from Class A.
Should I replace $this with something else?
class A {
private function do_something() {
// do something
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
private function do_something() {
// do something different
}
}
var newClass = new B;
echo B->return_output();
use protected and not private since you are running it inside of scope a and scope b can't access private scope a:
class A {
protected function do_something() {
echo('ado_something');
}
public function return_output() {
$op = $this->do_something();
// add some wrappers to $op
return $op;
}
}
class B extends A {
protected function do_something() {
echo('bdo_something');
}
}
$newClass = new B;
echo $newClass->return_output();

Calling extended class function from parent class

I'm new to OO PHP. Got some questions.
class a {
protected function a1() {
...
}
}
class b extends a {
public function b1() {
...
}
}
Let's say we have 2 classes like explained above. I'm calling b's method like example below
class a {
var $b;
function __construct()
{
$b = new b();
}
protected function a1() {
$b->b1();
}
}
class b extends a {
public function b1() {
...
}
}
I know that, it's possible to call parent class'es method from extended class, but I wonder if reverse way is possible? I mean, calling extended classes method from inside parent class (in this case, class b's method from class a) without declaring in __contruct, simply by $this->b();?
Yes, you can call a method in the extending class.
<?php
class a
{
public function a1 ()
{
$this->b1();
}
protected function b1()
{
echo 'This is in the a class<br />';
}
}
class b extends a
{
protected function b1()
{
echo 'This is in the b class<br />';
}
}
class c extends a
{
protected function b1()
{
echo 'This is in the c class<br />';
}
}
$a = new a();
$a->a1();
$b = new b();
$b->a1();
$c = new c();
$c->a1();
?>
This will result in:
This is in the a class
This is in the b class
This is in the c class
You may also be interested in abstract classes http://us3.php.net/manual/en/language.oop5.abstract.php
use Magic methods of PHP __call or __callStatic
Reference

class initiation with php

I have a class which initiates another class, i'm not concerned with having a reference to the object i only need the method and have to pass in new parameters.
class A {
__set .....
}
class B extends A {
$anotherA = new A;
$anotherA->myName = 'stackoverflow';
}
in short i'd like to have class B extend A, init a new instance of A but i don't want to have to type "new" everytime, i've seen the following syntax:
B::A // something like that
but not sure if how to use it or if that would do what i'm trying to do?
What you could do is define a static method on the class that returns the new instance. It's basically a 'shortcut', but it does exactly the same in the background.
class C {
public static function instance()
{
return new C();
}
public function instanceMethod()
{
echo 'Hello World!';
}
}
Now you can call it like:
C::instance()->instanceMethod();
Here are some examples of static functions - they can be called without using 'new A' or 'new B'.
class A {
static function message($msg = 'I am Alpha') {
echo "hi there, $msg\n";
}
}
class B {
static function message() {
A::message("I am Beta");
}
}
A::message();
B::message();
I would create the instance of A in B's constructor, then you can instantiate B using either its constructor or static B::create(), which just acts as a shortcut. You could make the constructor private if you wanted all instantiation go through create().
class A {
// __set .....
}
class B extends A {
public function __construct() {
parent::__construct();
$anotherA = new A;
$anotherA->myName = 'stackoverflow';
}
public static function create() {
return new self();
}
}
new B();
B::create();
Since you are extending A in B, you could call the method of class A:
class B extends A {
public function someMethod() {
parent::someMethodName();
}
}
Alternatively, you could create a static method in the class:
class A {
public static function someStaticMethod() { ... }
}
A::someStaticMethod();
If you really want a new instance of A, you have to use the new operator. That's what it is for.

Categories