您的位置:首页 > 编程语言 > PHP开发

PHP面向对象的程序设计封装--php高级最详细教程

2016-08-30 22:32 761 查看
PHP面向对象的程序设计

前言:

          PHP5正式版本的发布,标志着一个全新的PHP时代的到来。PHP5的最大特点是引入了面向对象的全部机制,并且保留了向下兼容性。程序员不必再编写缺乏功能性的类,并且能够以多种方式实现类的保护。(细说PHP2 224页)

面向对象的介绍

1、面向对象的程序设计(Object Oriented Programming,OOP)是一种计算机编程架构,

2、OOP的一条基本原则是:计算机程序是由单个能够起到子程序作用的单元或对象组合而成的,为了实现整体运算,每个对象都能够接受信息、处理数据和向其他对象发送信息。

3、OOP达到了软件工程的三个目标:重用性、灵活性和扩展性。

4、建议学习PHP面向对象的两个方向:

面向对象技术的语法

面向对象的编程思想

5、OOP面向对象编程的特点:封装、继承、多态

6、面向对象和面向过程之间的区别  

      最小的单位: 函数

      最小的单位: 对象

7、类和对象之间一个关系

 声明类-->实例化对象(创建对象)--->用对象

8.基本概念:

对象:客观存在的任何一个物体

类:对对象的一个描述

先有类 然后 通过类 实例化对象

如果抽象一个类

类的声明:

[一些修饰类的关键字] class 类名{
[成员属性]
[成员方法]

                                }

说明:

在类中声明成员属性时: 前面必须有修饰词,当不知道使用那个时,就使用var,如果知道使用那一个修饰关键字,就不使用var了

 

类中的成属性,如果创建多个对象时,每个对象有不同的属性值时,不要直接给出值 在创建好对象之后再给值

在类里面,只能有成员属性和成员方法,但是不能出现过程化的代码

  echo 'hello';

类的命名规则:

aaa bbb ccc 

 变量: aaaBbbCcc

 函数:aaaBbbCcc

 常量:AAABBBCCC

 类名:AaaBbbCcc

 

 使用的名称一定要有意义

建议要求: 一个文件只保存一个类, 文件名中包含类名, 文件:类名.class.php (为了自动加载)

类实例:

文章:

      标题、作者、来源、访问数

 

        添加、修改、删除 。。。。。 。。。 

     

 电子商城: 用户、购物车、商品、分类、定单、图片、文件对象 ... 

成员属性:

成员属性==变量==定义对象的外观和状态(名词)

成员方法:

成员方法==函数==定义对象的功能的(动词)

通过类实例化对象

实例化对象:

声明一个类

class Proson{
//类里面,不能使用函数作为值
//类里面,不能使用变量作为值
//类里面,可以使用常量作为值
 var $name = ’小伟‘;  //一种赋默认值的方式
 var $sex;
 var $age;

 function say(){

             echo "我的名字是:{$this->name},我的性别是:{$this->sex},我的年龄是:{$this->age}。<br>";
 }

 function run(){

 }

 function eat(){

 }

}

实例化对象语法:

 通过类来实例化对象

  1. 使用的是new 新建一个对象,加上类名,就是创建那个类的对象

  $对象引用=new 类名;
$对象名称 = new 类名称();

                       $对象名称 = new 类名称(构造参数);

  2. 只要有一个new 关键字就是创建一个对象,创建一个对象就在内存中分配了一个空间

  只有对象才在内存有存储空间

把此类实例化对象

//实例化多个对象$p、$p1、$p2

$p = new Proson;

$p1 = new Proson;

$p2 = new Proson;

$p3 =$p1;

//对象成员属性赋值 

$p->name = "vilin"; //$p对象赋值

$p->sex = "男神";  //$p对象赋值

$p->age = 19;  //$p对象赋值

对象类型在内存中的分配:

对象中成员的访问:

//对象访问自身对象的成员属性和成员方法(取值)

//后面的成员属性前面不要加 $符号,否则就变成了可变变量。

echo $p->name;  //vilin

echo $p->sex;  // 男神

echo $p->age; //19

$p->say(); //调用成员方法

echo $p1->name; //使用默认值  小伟

echo $p1->sex; //var_dump($p1->sex) 为NULL,因为没有赋值

对象比较:

 //在用逻辑运算来判断对象的时候,只要所有成员属性全相等,那么用 == 来判断则返回 true

    //如果用 === 来判断则返回 false

    // === 在对象的判断上,意思是,逻辑运算符两边是不是同一个对象

    if($p1 === $p3){

        echo 'Y';   // $p1和$p3是同一个对象

    }else{

        echo 'N';

    }

特殊的对象引用 $this :

 特殊对象的引用$this就是在对象内部的成员方法中,代表本对象的一个引用,但只能在对象的成员方法中使用,不管是在对象内部使用$this访问自己对象内部成员。还是在对象外部通过对象的引用名称访问对象中的成员,都需要使用特殊的运算符“->”来完成访问。

构造方法和析构方法

构造方法

说明:

构造方法, 构造器

 

     1. 是对象创建完成以后,“第一个” “自动调用”的方法

    2. 构造方法的定义, 方法名一个固定的,

      在PHP4中 和类名相同的方法就是构造方法

    在PHP5中 构造方法选择使用 魔术方法 __construct() 所有类中声明构造方法都使用这个名称

          优点: 在改变类名时,构造方法不用改变 

       作用:就是为成员属性初使化;

格式:

格式: [修饰符] function __construct ( [参数] ) { 
... ... 
  }

析构方法

 析构方法:

 

    1. 当对象被释放之前最后一个 “自动”调用的方法

 

  使用垃圾回收器(java PHP)而C++手动的释放

 

  作用:关闭一些资源, 作一些清理的工作

 

       __destruct();

对象释放方法:

 unset($p)

$p = null

页面结束时释放

实例:

<?php

header('content-type:text/html;charset=utf-8');

class Preson{
public $name;
public $sex;
public $age;

// function Preson($name = '神仙',$sex = '男神',$age = 1000){
// $this->name = $name;
// $this->sex = $sex;
// $this->age = $age;
// }

function __construct($name = "女神",$sex = '软妹子',$age = 18){
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}

function say(){
echo '我的名字叫'.$this->name.',我的年龄是'.$this->age.'岁,我是个'.$this->sex.'<br>';
}

function __destruct(){
echo $this->name.'再见<br>';
}



$p = new Preson;

$p1 = new Preson();

$p2 = new Preson('小丽','女汉子',25);

$p3 = new Preson;

$p3->name = 'vilin';

//访问成员属性

echo $p->name;

echo '<br>';

echo $p1->name;

echo '<br>';

echo $p2->name;

echo '<br>';

echo $p3->name;

echo '<hr>';

//访问成员方法

$p->say();

$p1->say();

$p2->say();

$p3->say();

echo 'hello world<br>';

?>

魔术方法:

魔术方法:

 *     在类中写出了某个魔术方法, 这个方法对象的功能 就会添加上

 *

 *     方法名称都固定的(都是系统给我们提供好),没有自己定义的, 

 *

 *     每一个魔术方法, 都是在不同时刻为了完成某一功能自动调用的方法

 *     不同的魔术方法有不同调用 时机

 *

 *     都是以 __开头的方法(两个下划线)

 *

 *     __construct(); 构造方法

 *     __destruct();  析构方法

 *

 *     __set();       封装

 *     __get();

 *     __isset();

 *     __unset();

 *

 *     __clone();

 *

 *     __call();

 *

 *     __sleep();

 *

 *     __weakup();

 *

 *     __toString()

 *

 *     ... 

 *

 *              __autoload();

封装性

封装性:面向对象的三大特性之一

概念:就是把对象中的成员(属性、方法)结合成一个独立的相同单位,并尽可能隐藏对象的内部细节

封装中用到的三个修饰词:public(公有的)、 protected(受保护的)、private(私有的)

被这个三个词修饰的属性或方法的被访问范围

                              public         protected           private

        外面           Y                 N                     N

        子类           Y                 Y                      N

        自己           Y                 Y                      Y

说明:外面指的是父类或者子类的花括号外面统称为外面,子类指的是子类的花括号

内部,自己指的就是父类本身的花括号内。

    //protected

    class A{

        protected $name = 'test';

        public function ziji(){

            return $this->name;

        }

    }

    class B extends A{

        public function getname(){

            return $this->name;

        }

    }

    $b = new B;

    echo $b->ziji();

    

    //protected  外面不能访问   子类里面可以访问   自己里面也可以访问

    //private

    class A{

        private $name = 'test';

        public function ziji(){

            return $this->name;

        }

    }

    class B extends A{

        public function getname(){

            return $this->name;

        }

    }

    $b = new B;

    echo $b->ziji();

    //private  外面访问不到   子类里面也访问不到  自己里面是可以的

    //public 

    class A{

        public $name = 'test';

        public function ziji(){

            return $this->name;

        }

    }

    class B extends A{

        public function getname(){

            return $this->name;

        }

    }

    $b = new B;

    //echo $b->name;

    //echo $b->getname();

    $a = new A;

    echo $a->ziji();

    //public  外面可以访问   子类里面也可以访问  自己里面也可以

为什么要封装?(封装的作用)

属性封装:

只要一个变量,需要在多个方法中使用,就将这个变量声明成成员属性,可以直接在这个对象中的所有方法中使用

成员属性,就相当于这个对象中的全局变量

成员属性都会在方法中使用,成员属性值的变化其实就是在改变方法的执行行为,也就是改变对象的功能。

成员属性的不正常方法执行的功能也就不正常。

构造方法会正常使用$p = new Person('vilin',19,'男');

封装的作用:

不需要在对象外部改变或读取属性值

对需要读取或改变的值使用方法加以控制

使用魔术方法__set() __get()  设置或读取值进行操作(使用自定义的方法调用属性太多的时候要声明很多方法,太复杂。)

方法封装作用:

一个类中有100个方法, 封装了95个(为另外的5个服务的方法), 只有5个方法可以使用

供用户调用的功能方法只有5个就够了,封装起来,让用户知道私有的方法,不需要调用。

和封装有关的魔术方法:

 __set():是直接设置私有成员属性值时,自动调用的方法

 __get():是直接获取私有成员属性值时,自动调用的方法

 __isset(); 是直接isset查看对象中私有属性是否存时自动调用这个方法

 __unset(); 是直接unset删除对象中私有属性时,自动调用的方法

//用到的词 $this class function construct destruct private protected public

实例:关于封装相关的魔术方法

<?php

header('content-type:text/html;charset=utf-8');

class Person {

        private $name;

        private $age;

        private $sex;

        

        //封装后可以通过内部构造方法赋默认值

        function __construct($name="", $age=0, $sex="男"){

            $this->name=$name;

            $this->age=$age;

            $this->sex=$sex;

        }

        //封装成私有属性后,通过echo $p->age; 取值时通过此魔术方法(可以对属性进行修饰)对用户来说是透明的。

        public function __get($proName){

            if($proName=="age"){

                if($this->age>=0 && $this->age<=20){

                    return $this->age;

                }elseif($this->age<=30){

                    return $this->age-3;

                }elseif($this->age<=40){

                    return $this->age-5;

                }elseif($this->age<=50){

                    return $this->age-10;

                }else{

                     return "保密";

                }

            }

            return $this->$proName;

        }

       

      //

      public function __set($proName,$proValue){  //这个变量名可以是任意的

              if($proName=="age"){

                if($proValue>=0 && $proValue<=100){

                    return $this->$proName=$proValue; //这里使用$this->age也是可以的

                }else{

                    return;

                }

              }

              if($proName=="sex"){

                if($proValue=="男" || $proValue=="女" || $proValue=="保密"){

                    return $this->$proName=$proValue; //这里使用$this->sex也是可以的

                }

              }else{

                    return;

              }

      }

        function say(){

            echo "我的名子:{$this->name},我的年龄:{$this->age},我的性别:{$this->sex}。<br>";

        }

        function run(){

            $this->left();

            $this->left();

            $this->right();

            $this->right();

            $this->gogo();

            $this->gogo();

            $this->gogo();

        }

        private function left(){

            echo "LLLLLLLLLLLLL<br>";

        }

        private function right(){

            echo "RRRRRRRRRRRRRR<br>";

        }

        private function gogo(){

            echo "GGGGGGGGGGGGGGGGG<br>";   

        }

        public function __isset($proName){

            if($proName=="age")

                return false;

            return isset($this->$proName);

        }

        public function __unset($proName){

            unset($this->$proName);

        }

        function eat(){

        

        }

        //function __destruct(){

        //    echo $this->name."再见!<br>";

        //}

    }

$p1=new Person("zhangsan", 80, "女");

$p2=new Person("lisi", 25);

$p3=new Person("wangwu");

echo $p3->name."<br>";

echo $p3->age."<br>";

echo $p3->sex."<br>";

$p1->name="潘小亮";

$p1->age=120;

$p1->sex="保密";

$p1->say();

//当外部使用unset函数时,将触发对象内部查找相应魔术方法__unset()

unset($p1->name);

//在外部使用isset函数时,将触发对象内部查找相应魔术方法__isset()

if(isset($p1->name)){

    echo "存在<br>";

}else{

    echo "没有这个成员 <br>";

}

使用自定义的方法来控制属性的赋值和取值(请使用魔术方法)

class Preson{

    private $name;

    private $age;

    private $sex;

    function Preson($name="vilin",$age=26,$sex="保密"){

             $this->name=$name;

             $this->age=$age;

             $this->sex=$sex;

    }

    function __construct($name="pan",$age=30,$sex="神"){

             $this->name=$name;

             $this->age=$age;

             $this->sex=$sex;

    }

     function setage($age){   //用来控制赋值 年龄限制的。

            if($age>=0 && $age<100)

                return $this->age=$age;

                else

                return;                      

      }

    function getage(){

            if($this->age>=0 && $this->age<=20){

                return $this->age;

            }elseif($this->age<=30){

                return $this->age-3;

            }elseif($this->age<=40){

                return $this->age-5;

            }elseif($this->age<=50){

                return $this->age-10;

            }else{

                echo "保密";

            }

      }

    function setsex($sex){

              if($sex=="男" || $sex=="女" || $sex=="保密")

                return $this->sex=$sex;

              else

                return;

      }

      

    function getsex(){

             return $this->sex;

      }

    //function __set(){

    //  echo "---------------";

    //}

    

    function say(){

              echo "我的名字是:{$this->name},我的年龄是:{$this->age},我的性别是:{$this->sex}。<br>";

    }

    function run(){

          $this->left();

          $this->left();

          $this->right();

          $this->right();

          $this->go();

          $this->go();

          $this->go();

    }

    private function eat(){

    }

    private function left(){

        echo "LLLLLLLLLL";

    }

    private function right(){

        echo "RRRRRRRRRR";

    }

    function go(){

        echo "gogogogogogogo";

    }

    //function __destruct(){

    //  echo $this->name."再见!<br>";

    //}

}

$p1=new Preson("小丽",47,"女");

$p2=new Preson("小罗");

$p3=new Preson;

$p1->say();

$p2->say();

$p3->say();

$p1->newage(55);

$p1->say();

echo $p1->getage();

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息