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

来源:互联网 发布:会声会影 mac版 编辑:程序博客网 时间:2024/05/21 04:20
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();





0 0
原创粉丝点击