<?phpclass X {private $non_static_member = 1;private static $static_member = 2;
function __construct() {echo $this->non_static_member . ' '. self::$static_member;}}
new X();?>
下面是不正确对非静态和静态成员变量使用$this和self的示例:
<?phpclass X {private $non_static_member = 1;private static $static_member = 2;
function __construct() {echo self::$non_static_member . ' '. $this->static_member;}}
new X();?>
这是一个多态和$this的成员函数示例:
<?phpclass X {function foo() {echo 'X::foo()';}
function bar() {$this->foo();}}
class Y extends X {function foo() {echo 'Y::foo()';}}
$x = new Y();$x->bar();?>
下面是一个使用self作为成员函数的抑制多态行为示例:
<?phpclass X {function foo() {echo 'X::foo()';}
function bar() {self::foo();}}
class Y extends X {function foo() {echo 'Y::foo()';}}
$x = new Y();$x->bar();?>
public static function prettyName($first_name, $last_name){echo ucfirst($first_name).' '.ucfirst($last_name);}
echo Person::prettyName($derek->first_name, $derek->last_name);
class Person{private $name;private $address;
public function __construct($new_name,$new_address){$this->name = $new_name;$this->address = $new_address;}}
class Person{private $name;private $address;public function __construct($new_name,$new_address){self::$name = $new_name;self::$address = $new_address;}}
class Person {private $name;
public function __construct($name) {$this->name = $name;}
public function getName() {return $this->name;}
public function getTitle() {return $this->getName()." the person";}
public function sayHello() {echo "Hello, I'm ".$this->getTitle()."<br/>";}
public function sayGoodbye() {echo "Goodbye from ".self::getTitle()."<br/>";}}
class Geek extends Person {public function __construct($name) {parent::__construct($name);}
public function getTitle() {return $this->getName()." the geek";}}
$geekObj = new Geek("Ludwig");$geekObj->sayHello();$geekObj->sayGoodbye();
<?php
class A {
public static function newStaticClass(){return new static;}
public static function newSelfClass(){return new self;}
public function newThisClass(){return new $this;}}
class B extends A{public function newParentClass(){return new parent;}}
$b = new B;
var_dump($b::newStaticClass()); // Bvar_dump($b::newSelfClass()); // A because self belongs to "A"var_dump($b->newThisClass()); // Bvar_dump($b->newParentClass()); // A
class C extends B{public static function newSelfClass(){return new self;}}
$c = new C;
var_dump($c::newStaticClass()); // Cvar_dump($c::newSelfClass()); // C because self now points to "C" classvar_dump($c->newThisClass()); // Cvar_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
Static Properties - Think of these as variables that are shared at the class level. Meaning that they are never copied by each instance.
class Foo {public static $bar = 1;}
Methods - These are functions which each instance will contain (and operate on instances).
class Foo {public function bar() {}}
Static Methods - These are functions which are shared across the entire class. They do not operate on instances, but instead on the static properties only.
class Foo {public static function bar() {}}
Constants - Class resolved constants. Not going any deeper here, but adding for completeness:
class Foo {const BAR = 1;}
So basically, we're storing information on the class and object container using "hints" about static which identify whether the information is shared (and hence static) or not (and hence dynamic).
State and Methods
Inside of a method, an object's instance is represented by the $this variable. The current state of that object is there, and mutating (changing) any property will result in a change to that instance (but not others).
If a method is called statically, the $this variable is not defined. This is because there's no instance associated with a static call.
The interesting thing here is how static calls are made. So let's talk about how we access the state:
Accessing State
So now that we have stored that state, we need to access it. This can get a bit tricky (or way more than a bit), so let's split this into two viewpoints: from outside of an instance/class (say from a normal function call, or from the global scope), and inside of an instance/class (from within a method on the object).
From Outside Of An Instance/Class
From the outside of an instance/class, our rules are quite simple and predictable. We have two operators, and each tells us immediately if we're dealing with an instance or a class static:
-> - object-operator - This is always used when we're accessing an instance.
class Foo{const NAME = 'Foo';
//Always Foo::NAME (Foo) due to selfprotected static $staticName = self::NAME;
public function __construct(){echo $this::NAME;}
public function getStaticName(){echo $this::$staticName;}}
class Bar extends Foo{const NAME = 'FooBar';
/*** override getStaticName to output Bar::NAME*/public function getStaticName(){$this::$staticName = $this::NAME;parent::getStaticName();}}
$foo = new Foo; //outputs Foo$bar = new Bar; //outputs FooBar$foo->getStaticName(); //outputs Foo$bar->getStaticName(); //outputs FooBar$foo->getStaticName(); //outputs FooBar
class ParentClass {function test() {self::who(); // will output 'parent'$this->who(); // will output 'child'}
function who() {echo 'parent';}}
class ChildClass extends ParentClass {function who() {echo 'child';}}
$obj = new ChildClass();$obj->test();
class cars{var $doors = 4;static $car_wheel = 4;
public function car_features(){echo $this->doors . " Doors <br>";echo self::$car_wheel . " Wheels <br>";}}
class spec extends cars{function car_spec(){print(self::$car_wheel . " Doors <br>");print($this->doors . " Wheels <br>");}}
/********Parent class output*********/
$car = new cars;print_r($car->car_features());
echo "------------------------<br>";
/********Extend class from another class output**********/
$car_spec_show = new spec;
print($car_spec_show->car_spec());