Home > Backend Development > PHP Tutorial > (2) PHP object-oriented theory 2

(2) PHP object-oriented theory 2

WBOY
Release: 2016-08-08 09:19:57
Original
900 people have browsed it

一. 魔术方法:
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;
Copy after login
若类中定义了__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);
Copy after login
使用__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);
Copy after login
实际上,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)
 */
Copy after login

在继承中,以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();
Copy after login
使用继承的场景:
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());
Copy after login
通过接口可以实现多态。
总结:
a.    多态指同一类对象在运行时的具体化
b.    PHP语言是弱类型的,实现多态更简单、更灵活
c.    类型转换不是多态
d.    PHP中父类和子类被看作是‘继父’和‘继子’的关系,存在继承关系。子类无法向上转型为父类。
e.    多态的本质就是if...else,但实现的层级不同。

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

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

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template