PHP面向对象编程入门

1、常用术语说明

class 类
object 对象
new 实例化
member 类成员
method 方法,成员函数
property 属性,成员变量
constant 类常量

2、类的构造

class ClassName{            //class关键字加类名
    //类中只能有三种成员:属性、类常量、方法,不限数量
    //成员变量(属性)
    public $var;            //普通属性,只能通过对象访问,声明时必须使用访问控制修饰符
    public static $s_var = 0;    //静态属性,使用static关键字修饰的属性
    const PI  = 3.14;        //类常量,声明时必须使用const关键字修饰并赋值,其值不可修改

    //成员方法
    function fn0(){
        //普通成员方法
        echo '普通成员方法运行了<br>';
    }
    static function fn1(){
        //静态方法
        echo self::$s_var.'静态方法运行了<br>';    //类似$this,在类内部使用self关键字代表当前类名
    }
    public function __construct($var){
        //构造方法,对象实例化时自动调用该方法
        $this->var = $var;    //$this表示当前对象
        echo '构造方法运行了<br>';
    }
    public function __destruct(){
        //析构方法,对象销毁时自动调用该方法
        echo '析构方法运行了<br>';
    }
    public function __clone(){
        //克隆方法,克隆对象时自动调用该方法
        echo '克隆方法运行了<br>';
    }
}


$c = new ClassName('test');        //对象实例化
echo $c->var.'<br>';            //访问对象属性$obj->var
$c->var = 'update';                //修改对象属性
$c->new_var = 'add';            //新增对象属性
var_dump($c);echo '<br>';        
unset($c->new_var);                //删除对象属性
var_dump($c);echo '<br>';        
$c->fn0();                        //调用成员方法
echo ClassName::PI.'<br>';         //访问类常量,使用:类名::类常量名
echo ClassName::$s_var.'<br>';    //访问静态属性,使用:类名::$静态属性名
ClassName::fn1();                //调用静态方法

3、成员修饰符

3.1、关键字:

类常量,不可修改性const(修饰属性),类常量只能通过类访问:类名加范围解析操作符(双冒号::)
静态成员-static(修饰属性和方法),静态成员只能通过类访问
不可继承性final(修饰类和方法)

3.2、访问控制符

public:表示公有的,其修饰的属性和方法可以在类内和类外访问,可以被继承
protected:表示受保护的,,其修饰的属性和方法只可以在类内访问,可以被继承
privated:表示私有的,其修饰的属性和方法只可以在类内访问,不可以被继承

属性前一定要加一个访问控制修饰符,类常量不用加访问控制修饰符,方法前可以不加访问控制修饰符,默认是public

4、对象值传递

对象的赋值操作是引用赋值,即:当将对象a的值赋值给对象b时,a和b指向内存中同一个地址

如果需要实现真正的复制,可以使用对象克隆方法:$b = clone $a;

私有化__clone方法可以禁止对象被克隆:private function __clone(){}

5、类的加载

类的访问必须保证类在内存中已经存在,所有在使用类之前需要将包含类的PHP文件加载到内存,本质是文件加载。

手动加载:

if(!class_exists('Man')){
    //类不存在,加载
    include_once 'Man.php';
}
new Man();

自动加载:

php7以前:

function __autoload($class_name){
    //假设有多个类放在多个文件夹中
    //先尝试去a文件夹中寻找类
    $file = 'a/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
        exit;
    }
    //再尝试去b文件夹中寻找类
    $file = 'b/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
        exit;
    }
    //以此类推,直到找到类或找完所有包含类的文件夹为止
}
$d = new Dog();   //实例化Dog类,系统自动调用__autoload函数

php7以后:

function my_autoload($class_name){
    $file = 'a/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
        exit;
    }
    $file = 'b/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
        exit;
    }
}
spl_autoload_register('my_autoload');
$d = new Dog(); 

也可以分开多个加载函数:

function a_autoload($class_name){
    $file = 'a/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
    }
}
function b_autoload($class_name){
    $file = 'b/'.$class_name.'.class.php';
    if(file_exists($file)){
        include_once $file;
    }
}
spl_autoload_register('a_autoload');
spl_autoload_register('b_autoload');
$d = new Dog();   

自动加载类:

class Autoload{
    public static function loadA($class_name){
        $file = 'a/'.$class_name.'.class.php';
        if(file_exists($file)){
            include_once $file;
        }
    }
    public static function loadB($class_name){
        $file = 'b/'.$class_name.'.class.php';
        if(file_exists($file)){
            include_once $file;
        }
    }
}
spl_autoload_register(array('Autoload','loadA'));
spl_autoload_register(array('Autoload','loadB'));
$d = new Dog(); 

6、设计模式

单例模式:一个类有且仅有一个对象,例如操作系统中的资源管理器,目的是为了保护资源的唯一性

class Singleton{
    //使用一个静态属性保存生产出来的对象
    private static $object = NULL;
    //私有化构造方法
    private function __construct(){}
    //类入口
    public static function getInstance(){
        if(!(self::$object instanceof self)){
            self::$object = new self();
        }
        return self::$object;
    }
    //私有化克隆方法,防止克隆产生新对象
    private function __clone(){}
}
//实例化两个对象
$s = Singleton::getInstance();
$s1 = Singleton::getInstance();
var_dump($s,$s1);    //检测到是同一个对象

工厂模式factory:

由一个地方生产对象,其他位置就不需要额外实例化对象,从而可以方便后期代码统一维护(改名),方便隐藏真实的类结构。

工厂模式针对相似模型的统一产出,要有一批具有类似功能的类,其本质是相似的大类下的小类

静态工厂(生产对象时需要知道类名):

class Man{
    public function display(){
        echo 'Man<br>';
    }
}
class Woman{
    public function display(){
        echo 'Woman<br>';
    }
}
class Child{
    public function display(){
        echo 'Child<br>';
    }
}
class HumanFactory{
    public static function getInstance($class_name){
        return new $class_name();
    } 
}
$m = HumanFactory::getInstance('Man');
$w = HumanFactory::getInstance('Woman');
$c = HumanFactory::getInstance('Child');
$m->display();
$w->display();
$c->display();

匿名工厂(生产对象时需要知道类名对应的符号):

class HumanFactory{
    public static function getInstance($flag){
        switch ($flag) {
            case 'm':
                return new Man();
            case 'w':
                return new Woman();
            case 'c':
                return new Child();
            default:
                return null;
        }
        
    } 
}
$m = HumanFactory::getInstance('m');
$w = HumanFactory::getInstance('w');
$c = HumanFactory::getInstance('c');

 

7、对象属性遍历:foreach(略)

 

posted @ 2019-02-14 20:29  chuanzi  阅读(390)  评论(0编辑  收藏  举报