1:static访问符
2:static后期静态绑定
什么是静态绑定?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
abstract class U { } class u1 extends U { public static function create() { return new u1(); } } class u2 extends U { public static function create(){ return new u2(); } } |
这段代码正常工作是没问题,但大量重复的代码会很烦人
我不想在每个子类中添加create方法,如果把create方法放在超类U中,代码可能是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
abstract class U { public static function create() { //return new self(); //self 会报错,self对该类所起的作用与$this对对象所起的作用并不完全相同。self指的不是调用上下文,他指的是解析上下文,<br>//因此如果运行上面的列子,将会得到<br>//Fatal error: Cannot instantiate abstract class U in D:wampwwwtestoopstatic.php on line 21<br>//因此self被解析为定义create的U,而不是解析为调用self的u1类。<br><br> //static不仅可以用于实例化,和self,parent一样还可以作为静态方法的调用标识符,甚至是从非静态上下文中调用<br> return new static(); } } class u1 extends U{ } class u2 extends U{ } $res = u1::create(); var_dump( $res ); |
static不仅可以用于实例化,和self,parent一样还可以作为静态方法的调用标识符,甚至是从非静态上下文中调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
abstract class U { private $group ; public function __construct() { $this ->group = static ::getGroup(); } public static function create() { return new static (); } static function getGroup() { return 'default' ; } } class u1 extends U { } class u2 extends U { static function getGroup() { return 'u2' ; } } class u3 extends u2 { } print_r(u1::create()); |
u1 Object ( [group:U:private] => default )
u3 Object ( [group:U:private] => u2 )
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
class A { public static function foo() { static ::who(); } public static function who() { echo __CLASS__ . "\n" ; } } class B extends A { public static function test() { A::foo(); //如果换成static,则向后绑定,如果是A,则最底层的类是A parent::foo(); self::foo(); } public static function who() { echo __CLASS__ . "\n" ; } } class C extends B { public static function who() { echo __CLASS__ . "\n" ; } } C::test(); |
输出:A C C
3: 属性不能被定义为 final,只有类和方法才能被定义为 final。
如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。
4:对象复制
5:对象继承
parent能调用父类的非静态方法吗?
self能调用父类的静态方法吗?
php支持继承多个类吗?
父类调用之类怎么调用?
子类调用父类怎么调用?
$this能调用静态方法吗?
同样的类名和接口名可以放在一起吗?
子类的同名访问符可以小于父类的吗?
php支持多态吗?
1> parent能调用父类的非静态方法吗?
parent既能调用父类的静态方法,也可以调用父类的非静态方法; parent不可以调用子类,只能调用父类的; parent关键字解决的就是调用父类的方法;
self无论父类还是子类的静态方法,非静态方法都可以调用(对所有的无限制)
parent常用于构造函数中调用父类的构造函数
2>self能调用父类的静态方法吗?
3>父类调用之类怎么调用?
静态方法,属性用static,$this(虽然可以访问,但是不建议这样来做)
非静态方法,属性用$this, static
4>子类调用父类怎么调用?
用$this, parent, static
5>如果子类和父类有相同的方法,但是父类的是private方法,父类调用的时候调用的是哪个方法?
父类调用的是他自己的,而不是子类的。对于私有方法(private)修饰的方法,$this找的方法是先找本类里的。 protect,public都可以被覆盖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
class Child { public function __construct() { $this ->setInstance( $this ); } private function setInstance( $instance ) { echo 'Child' ; } } class ChildChild extends Child { public function __construct() { parent::__construct(); } public function setInstance( $instance ) { echo 'ChildChild' ; } } $obj = new ChildChild(); |
输出:Child 【因为他是private,$this调用的时候调用它】
如果改成public,或protected,则返回ChildChild
5>子类的同名访问符可以小于父类的吗?
子类的修饰符号不能小于父类的
3>同样的类名和接口名不能放在一起。
同样的类名和接口名可以放在一起吗?
Class and Interface share SAME namespace!
class k{}
interface k {} // Fatal error: Cannot redeclare class k
6:$this, self,parent,static
1> $this访问变量不加$, self:: 访问需要加
$this->name; self::$sName;
2>
$this能访问静态变量,静态方法,但是不能访问常量;
而self, parent, static 不能访问非静态变量,只能访问静态的变量或常量; 但是self,parent,static都能访问非静态方法。self也能访问父类的非静态方法和静态方法。
php支持多态吗?
多态:多个函数用同一个名字,但参数表,即参数的个数或(和)数据类型可以不同,调用的时候,虽然方法名字相同,但根据参数表可以自动调用对应的函数。
PHP只支持覆盖(override),而不支持重载(overload)。
PHP5 中重载可以通过 __get, __set, and __call 几个特殊方法来进行。当 Zend 引擎试图访问一个成员并没有找到时,PHP将会调用这些方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public function __call( $method , $p ) { print ( "Invoking $method()<br>\n" ); if ( $method == 'display' ) { if ( is_object ( $p [0])) $this ->displayObject( $p [0]); else if ( is_array ( $p [0])) $this ->displayArray( $p [0]); else $this ->displayScalar( $p [0]); } } |
__CLASS__, __FUNCTION__ 在哪个类里,就显示哪个,而不管$this是谁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Child { public function __construct() { static ::setInstance( $this ); } } class ChildChild extends Child { public function __construct() { parent::__construct(); } public function setInstance( $instance ) { echo __CLASS__ . ' || ' . __FUNCTION__ ; echo 'childChild' ; } } $obj = new ChildChild(); |
返回: ChildChild || setInstance childChild
static访问符号的顺序为: 从后往前
子类 > 本类 > 父类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Base { protected static $instances ; public function setInstance( $instance ) { echo 'Base' ; } } class Child extends Base { public function __construct() { static ::setInstance( $this ); } public function setInstance( $instance ) { echo 'Child' ; } } class ChildChild extends Child { public function setInstance( $instance ) { echo 'ChildChild' ; } } $obj = new ChildChild(); |
输出: ChildChild
总结:
访问静态方法,静态属性:static,parent,self, $this
访问常量: self, parent, static
访问非静态方法,属性: $this, static, parent, self
子类访问父类: $this, parent, self, static
父类访问子类: static, $this
相关阅读