(二)PHP物件導向理論2

WBOY
發布: 2016-08-08 09:19:57
原創
882 人瀏覽過

一. 魔术方法:
1.    魔术方法以“__”开头,是PHP的语法糖。语法糖是更实用的编码方式或技巧,使代码更易读。
2.    __set与__get

<?php
class Account{
    private $user = 1 ;
    private $pwd = 2;

    public function __set($name,$value){
        echo "Setting $name to $value \r\n";
        $this ->$name = $value;
    }
    public function __get($name){
        if (!isset($this->$name)){
            echo 'no set ';
            $this->$name = 'set default value:';
        }
            return $this->$name;
    }
}
$a = new Account();
echo $a -> user;
echo "<br /><br />";
$a->user = 5;
echo $a->$name;
echo "<br /><br />";
echo $a->big;
登入後複製
若类中定义了__set和__get魔术方法,那么当给对象赋值或取值时,既使属性不存在也不会报错。增强程序的健壮性。
2.__call和__callStatic:
(以下代码,未能执行成功)
<?php
/*
 * 本代码没有执行成功
 */
abstract class ActiveRecord{
    protected static $table;
    protected $fieldValues;
    public $select;

    static function findById($id){
        $query = "select * from "
            .static::$table
            ." where id = $id";
        echo $query;
        return self::createDomain($query);
    }

    function __get($fieldname){
        return $this->fieldvalues[$fieldname];
    }

    static function __callStatic($method,$args){
        $field = preg_replace('/^findBy(\w*)$','${1}',$method);
        $query = "select * from "
            .static::$table
            ." where $field='$args[0]";
        return self::createDomain($query);
    }

    private static function createDomain($query){
        echo "test";
        $klass = get_called_class();
        $domain = new $klass();
        $domain->fieldvalues = array();
        $domain->select = $query;
        foreach($klass::$fields as $field => $type){
            $domain->fieldvalues[$field] = 'TODO:set from sql result';
        }
        return $domain;
    }
}

class Customer extends ActiveRecord{
    protected static $table = 'custdb';
    protected static $fields = array(
        'id' => 'int',
        'email' => 'varchar',
        'lastname' => 'varchar'
    );
    public function  __construct(){
        echo "***";
    }
}

class Sales extends ActiveRecord{
    protected static $table = 'salesdb';
    protected static $fields = array(
        'id' => 'int',
        'item' => 'varchar',
        'qty' => 'int'
    );
}
assert("select * from custdb where id = 123" == Customer::findById(123) ->select);
assert("TODO: set from sql result" == Customer::findById(123)->email);
assert("select * from salesdb where id = 321"== Sales::findById(321)->select);
assert("select * from custdb where lastname = 'Denoncourt'"== Customer::findByLastname('Denoncourt')->select);
登入後複製
使用__call与__callStatic可以‘防止调用不存在的方法而报错’。还可以使得方法的动态创建变为可能。
3.__toString
<?php
header("Content-type: text/html; charset=utf-8");
class Account{
    public $user = 1 ;
    private $pwd = 2 ;
    public function __toString(){
        return "当前对象的用户是{$this->user},密码是{$this->pwd}";
    }
}
$a = new Account();
echo $a;
echo "<br /><br />";
echo PHP_EOL."===";
echo "<br /><br /><br />";
print_r($a);
登入後複製
实际上,toString方法也是序列化的一种方式。
二.继承与多态:
1.    继承:类与类之间有一种父与子的关系,子类继承父类的属性和方法,称为继承。
在继承里,子类拥有父类的方法和属性,同时子类也可以有自己的方法和属性。
<?php
header("Content-type: text/html; charset=utf-8");
class person{
    public $name = &#39;Tom&#39;;
    public $gender;
    static $money = 10000;
    public function __construct(){
        echo "这里是父类",PHP_EOL;
    }
    public function say(){
        echo $this->name,"\tis",$this->gender,"\r\n";
    }
}

class family extends person{
    public $name;
    public $gender;
    public $age;
    static $money = 100000;
    public function __construct(){
        parent::__construct();
        echo "这里是子类",PHP_EOL;
    }

    public function say(){
        echo "<br />我说".$this->name,"\tis\t",$this->gender,",and is \t",

$this->age,PHP_EOL."<br />";
    }

    public function cry(){
        echo parent::$money,PHP_EOL;
        echo "%>-<%",PHP_EOL;
        echo self::$money,PHP_EOL;
        echo "(*^_^*)";
    }

    public function read(){
        echo "<br /><br /><br />read again".parent::say()."<br />";
    }
}

$poor = new family();
$poor->name = 'Lee';
$poor->gender = 'female';
$poor->age = 25;
$poor->say();
$poor->cry();
$poor->read();

/*
 * 疑问:
 * 我在子类上加了个方法叫read
 * 结果执行结果成了:
 * 这里是父类 这里是子类
我说Lee is female,and is 25
10000 %>-<% 100000 (*^_^*)Lee isfemale


read again
为什么read again在lee is female后面……(我感觉应该先执行read again)
 */
登入後複製

在继承中,以parent指代父类,以self指代自身。以”::”(范围解析操作符)调用父类的方法。”::”操作符还用来作为类常量和静态方法的调用。
如果声明类成员或方法为static,就可以不实例化类而直接访问。
不能通过一个对象访问其中的静态成员(静态方法除外),也不能用“::”访问一个非静态方法。
继承是一种“是、像”的关系,而组合一种“需要”的关系。
从方法复用的角度考虑,如果两个类具有很多相同的代码和方法,可以从这两个类中抽象出一个父类,提供公共方法,然后两个类作为子类。提供个性方法。
继承的问题:
a. 继承破坏封装性。
b. 继承是紧耦合的。
c. 继承扩展复杂。
d. 不恰当地使用继承可能违反现实世界中的逻辑。
<?php
class car{
    public function addoil(){
        echo "Add oil\r\n";
    }
}

class bmw extends car{

}

class benz{
    public $car;
    public function __construct(){
        $this->car = new car;
    }
    public function addoil(){
        $this->car->addoil();
    }
}

$bmw = new bmw();
$bmw ->addoil();
$benz = new benz();
$benz->addoil();
登入後複製
使用继承的场景:
a.    继承树的抽象层一般不要多于三层。
b.    对于不是专门用于被继承的类使用final修饰符,可以防止重要方法被覆写。
c.    优先考虑组合关系可以提高代码的可重用性。
d.    子类是一种特殊的类型,不只是父类的一个角色。
e.    底层代码多用组合以提高效率,顶层(业务层)代码多用继承以提高灵活性。
2.    多态:
实际开发中,只要关心一个接口或基类的编程,而不必关心一个对象所属于的具体类。
<?php
header("Content-type: text/html; charset=utf-8");

class employee{
    protected  function working(){
        echo "本方法需要重载才能运行";
    }
}

class teacher extends employee{
    public function working(){
        echo "教书";
    }
}

class coder extends employee{
    public function working(){
        echo "敲代码";
    }
}

class readBooks extends employee{
    public function working(){
        echo "我不看书的!";
    }
}

function doprint($obj){
    if(get_class($obj) == &#39;employee&#39;){
        echo "error";
    }else{
        $obj->working();
    }
}

doprint(new teacher());
doprint(new coder());
doprint(new employee());

doprint(new readBooks());
登入後複製
通过接口可以实现多态。
总结:
a.    多态指同一类对象在运行时的具体化
b.    PHP语言是弱类型的,实现多态更简单、更灵活
c.    类型转换不是多态
d.    PHP中父类和子类被看作是‘继父’和‘继子’的关系,存在继承关系。子类无法向上转型为父类。
e.    多态的本质就是if...else,但实现的层级不同。

版权声明:本文为博主原创文章,未经博主允许不得转载。

以上就介绍了(二)PHP面向对象理论2,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板