设为首页 收藏本站
查看: 1379|回复: 0

[经验分享] PHP面向对象总结

[复制链接]

尚未签到

发表于 2018-12-22 08:03:59 | 显示全部楼层 |阅读模式
    调用父类构造函数,调用其他类的构造函数:
public function __constuct(){
parent::__constuct();
classname::__construct();
}  如果想要依次调用几个父类的构造函数,可以使用类名直接调用构造函数
  

  2.析构函数__destuct()
  这个主要是对象在销毁时自动调用的函数,一个对象在数去引用时,会自动销毁。
  $a=$b=$c=new Person();
  $a = null;
  unset($b);
  一个对象三个引用,失去了两个还有一个,程序加载完成后会自动销毁最后一个。
  

  3.赋值函数__set()
  __set( $property, $value ) 给一个未定义的成员属性赋值时调用,(私有成员)
  

  4.取值函数__get()
  __get( $property ) 获取成员属性的值(私有成员)
  先可以判定下是否有这个成员
  return isset($this->$property) ? $this->$property : null;
class Person{
    private $name;
    private $age;
    private $sex;
    public function __construct($name,$age,$sex){
        $this->name=$name;
        $this->age=$age;
        $this->sex=$sex;
        $this->run();
    }
    private function run(){
        echo $this->name."在跑步".$this->age;
    }
    public function say(){
        echo $this->name."在说话";
    }
    public function say1($name){
        echo $name."在说话";
    }
    public function __set($field,$value){
        if($field=="age"){
            if($value>200){
                // return "非法数据";
                $value="非法数据";
            }
        }
        $this->$field=$value;
    }
    public function __get($field){
        return $this->$field;
    }
}
$person = new Person("东方不败",210,'不详');
$person->say();
// $person->run();
$person->say1("nihao");
echo "---------------------我是华丽丽的分界线---------------------";
$person->age=220;
echo $person->age;  

  

  

  

  5.__isset()方法用于检测私有属性值是否被设定。
  

  如果对象里面成员是公有的,可以直接使用 isset() 函数。如果是私有的成员属性,
  那就需要在类里面加上一个 __isset() 方法,然后再使用isset()函数如下
  public function __isset($property_name)
  {
  return isset($this->$property_name);
  }
  这样当在类外部使用 isset() 函数来测定对象里面的私有成员是否被设定时,就会自动调用 __isset() 方法来检测。
  

  

  6.__unset()方法用于删除私有属性。
  同 isset() 函数一样,unset() 函数只能删除对象的公有成员属性,当要删除对象内部的私有成员属性时,
  需要使用__unset() 方法:
  public function __unset($property_name)
  {
  unset($this->$property_name);
  }
  

  7.__call() 方法用于监视错误的方法调用。
  为了避免当调用的方法不存在时产生错误,可以使用 __call() 方法来避免。该方法在调用的方法
  不存在时会自动调用,程序仍会继续执行下去。语法:
  public function __call($function_name, $arguments)
  {
  ......
  }
  该方法有两个参数,
  第一个参数 $function_name 会自动接收不存在的方法名。
  第二个 $args 则以数组的方式接收不存在的方法的多个参数。
  

  8.__toString()方法用来输出对象的引用
  这个方法也是一样自动被调用的,是在 直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,
  比如说:“$p=new Person()”中,$p 就是一个引用,我们不能使用echo 直接输出$p,这样会输出"Catchable fatal
  error: Object of class Person could not be converted to string"这样的错误,如果你在类里面定义
  了"__toString()"方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用了 "__toString()"方法,
  输出"__toString()"方法中返回的字符,所以"__toString()"方法一定 要有个返回值(return 语句)。
  

  9.__autoload()方法用于自动加载其他文件中的类。
  这个方法是唯一一个不在类中写的方法。
  function __autoload($classname){
  include_once ucfirst($classname)."Controller.php";
  }
  

  10.__sleep()方法是对象在序列化时执行的方法
  注意了,对象在序列化后里面保存的只是他的属性(初始化的时候赋值了),函数和方法都是类的,不是对象的。这点要明确
  11.__wakeup()方法是对象在反序列化时执行的方法.
  在wake.php中
class db {
    private $host;
    private $user;
    private $pwd;
    private $dbname;
    private $mysqli;
    function __construct($host, $user, $pwd, $dbname) {
        $this->host = $host;
        $this->user = $user;
        $this->pwd = $pwd;
        $this->dbname = $dbname;
        $this->db();
    }
    function db() {
        $this->mysqli = new mysqli ( $this->host, $this->user, $this->pwd, $this->dbname );
    }
    function select() {
        $this->mysqli->query("SET CHARSET GBK");
        $sql = "SELECT * FROM ams_archives_rs LIMIT 0,4";
        $result = $this->mysqli
            ->query ( $sql );
        $rows = array ();
        while ( $row = $result->fetch_assoc () ) {
            $rows [] = $row;
        }
        ECHO "";
        print_r ( $rows );
    }
    function __sleep(){
        return array_keys(get_object_vars($this));
    }
    function __wakeup(){
        $this->db();
    }
}
session_start();
$chanel = new db("localhost",'root','admin888','ams');
//$chanel->select();
$_SESSION['channel_obj'] = serialize($chanel);  

  在wakeupa.php中
session_start();
include 'wakeup.php';
$channel_obj=unserialize($_SESSION['channel_obj']);
$channel_obj->select();
//如果在59.php中不写上__wakeup()方法会连接不上
11.__clone()这个使用关键字clone时自动运行的方法
public function __clone(){
    $this->class=2;
}
$person1=clone $person;
echo $person1->class;  

  二、这几个关键字我们挑选几个不常用的看看
  

  1.const
  他在类的内部使用的方法如下
  self::常量名大写;
  他在类的外部使用方法
  类名::常量名大写;
  

  2.extends 英文extend的第三人称单数是扩展继承的意思
  

  3.final
  可以修饰类和方法
  修饰类,这个类不能被继承
  修饰方法,这个方法不能被重写
  

  

  

  4.static
  翻译中文是静态的意思
  用来修饰成员属性和方法
  

  如果用来修饰成员属性,初始化后的所有对象都是共用这个成员属性。
  他在类的内部使用方法如下
public function getName(){
    //return 类名::静态变量;
    //return self::静态变量;
    //return Person::$name;
    return self::$name;
}
public function setName($val){
    Person::$name=$val;
    //self::$name=$val;
}  $p->setName('东方不败');
  //这里设置后所有的对象name都是东方不败了
  

  他在类的外部使用的方法如下
  Person::$name;//只能用类名::方法名
  

  如果是用来修饰成员方法,他就不能访问非静态成员,因为非静态的成员必须用对象的引用来访问。
  因此,用static修饰的方法里面就一定不使用非静态成员
  

  5.instanceof
  这个是用来判断一个对象是不是某个类实例化出来的
  $p=new Person();
  echo intval($p instanceof Person);
  //还有一个函数也可以
  echo intval(is_a($p,'Person');//PHP官方不建议使用
  还有一个函数是用来判断一个对象是不是某个类的子类实例化出来的(父亲级别)
  is_subclass_of($p,'Pseson');
  

  6.abstract
  中文意思是抽象的意思
  这个关键字既可以修饰类也可以修饰方法
  

  关于抽象方法:没有方法体的方法称作抽象方法,注意在类中声明抽象方法必须有abstract修饰
  function fun();
  

  关于抽象类:如果一个类中有abstract修饰的方法那么这个类就是抽象类
  abstract class Person{
  abstract function fun();
  }
  抽象类是为了规定一些共性的成员,一般是给了N个抽象类,抽象类自己不
  被实例化,必须由子类继承过来(所以子类就不能再是抽象类了,而且非抽象方法和成员属性的访问
  权限也就必须得protected和public),而且子类必须逐一实现这N个抽象方法;而且实现的方法必须
  是public 或者不写;
  

  7.interface
  中文意思为接口
  PHP是单继承,每个类只能继承一个父类
  

  他是一种特殊的类,
  接口里面的成员必须全是public权限,
  接口里面的方法全都是抽象方法,并且不能用abstract修饰,
  接口里的成员属性只能是常量(const NAME='hby');
  

  可以写另外一个接口来继承(extends)一个接口,用来扩展里面的方法。
  可以写一个抽象类来实现(implements)一个接口,用来实现里面的部分方法
  可以写一个普通类来实现(implements)一个接口,用来实现里面的全部方法
  一个类可以同时继承父类还实现N个接口.
  class 类名 extends 父类名 implements 接口1,接口2,...接口n{
  //实现所有接口中的抽象方法;
  }
  

  三、单例模式
  网上说的意思归结到一点就是:让一个类只有一个实例.
  如何做到呢?
  1.前面学过,每次用 new 类名 的方式,就可以创建一个对象。我们必须禁止
  外部程序用 new 类名的方式来创建多个实例。
  解决办法是:我们将构造函数设置成 private ,让构造函数只能在内部被调用,
  而外部不能调用。这样,这个类就不能被外部用 new 的方式建立多个实例了。
  class A{
  private function __construct(){}
  }
  $a = new A();
  

  2.我们已经禁止外部用new实例化这个类,我们改如何让用户访问这个类呢?前门堵了,
  我们需要给用户留个后门。
  解决办法是:static 修饰的方法,可以不经实例化一个类就可以直接访问这个方法。
class A{
    private function __construct(){}
    static function getClassA(){
        return "这里是后门,可以通过这里进入类内部..";
    }
}
echo A::getClassA();  

  3.虽然我们已经进入类内部,但我们要的是这个类的唯一实例?先不管别的,
  我们先需要一个实例。通过这个static的方法返回这个实例,如何做呢?
  下面的例子我们确实返回了A类的实例,但注意两次执行返回的不是同一个实例。
class A{
    private function __construct(){}
    static function getClassA(){
        $a = new A();
        return $a;
    }        
}  // 看到这里确实返回的是 A 的实例.但不是同一个对象.
$a1 = A::getClassA();
$a2 = A::getClassA();
echo "\$a1 的类是 ".get_class($a1)." , \$a2 是 ".get_class($a1);
if($a1 === $a2){
   echo " \$a1 \$a2 指向同一对象.";
}else{
   echo " \$a1 \$a2 不是一个对象.";
}  

  4.我们已经通过static方法返回了A的实例。但还有问题。我们如何保证我们
  多次操作获得的是同一个实例的呢?解决办法:static的属性在内部也只有一个。
  static 属性能有效的被静态方法调用。将这个属性也设置成private,以防止外部调用。
  先将这个属性设置成 null。每次返回对象前,先判断这个属性是否为 null 。
  如果为 null 就创建这个类的新实例,并赋值给这个 static 属性。如果不为空,
  就返回这个指向实例的 static 属性。
class A{
    private static $a = null;
    private function __construct(){}
    static function getClassA(){
        if( null == self::$a){
            self::$a = new A();
        }      
        return self::$a;
    }        
}
// 看到这里确实返回的是 A 的实例.但不是同一个对象.
$a1 = A::getClassA();
$a2 = A::getClassA();
echo "\$a1 的类是 ".get_class($a1)." , \$a2 是 ".get_class($a1);
if($a1 === $a2){
   echo " \$a1 \$a2 指向同一对象.";
}else{
   echo " \$a1 \$a2 不是一个对象.";
}  最终这里无论是多少次都是同一个对象。
  

  下面给一个例子
  

  

  代码从这开始
  **/
class Person{
    const HIGH='170';
    private $name;
    private $age;
    private $sex;
    public $class;
    public function __construct($name,$age,$sex,$class){
        $this->name=$name;
        $this->age=$age;
        $this->sex=$sex;
        $this->class=$class;
        $this->run();
    }
    private function run(){
        echo $this->name."在跑步".$this->age;
    }
    public function say(){
        echo $this->name."在说话";
    }
    public function say1($name){
        echo $name."在说话";
    }
public function __set($field,$value){
if($field=="age"){
if($value>200){
// return "非法数据";
                $value="非法数据";
}
}
$this->$field=$value;
}
    public function __get($field){
        return $this->$field;
    }
    public function __isset($property_name){
        return isset($this->$property_name);
    }
    public function __unset($property_name){
        unset($this->$property_name);
    }
    public function __call($function_name,$arguments){
        echo "您所调用的方法".$function_name."参数";
        echo var_dump($arguments)."不存在";
    }
    public function __toString(){
        return $this->name."qwertyuiop";
    }
    public function __clone(){
        $this->class='2';
    }
    public function tellhigh(){
        echo "身高是".self::HIGH;
    }
}
$person = new Person("东方不败",210,'不详','大学');
$person->say();
// $person->run();
$person->say1("nihao");
echo "---------------------我是华丽丽的分界线---------------------";
$person->age=220;
echo $person->age;
echo "---------------------我是华丽丽的分界线---------------------";
echo isset($person->class) ? "存在":"不存在";
echo "---------------------我是华丽丽的分界线---------------------";
unset($person->age);
echo isset($person->class) ? "存在":"不存在";
echo isset($person->age) ? "存在":"不存在";
echo "---------------------我是华丽丽的分界线---------------------";
$person->age=80;
echo isset($person->age) ? "存在":"不存在";
echo "---------------------我是华丽丽的分界线---------------------";
$person->drink(123,"we");
echo "---------------------我是华丽丽的分界线---------------------";
echo $person;//输出对象的引用
echo "---------------------我是华丽丽的分界线---------------------";
//下面写一个自动加载函数
function __autoload($classname){
    include_once ucfirst($classname)."Controller.php";
}
$mx=new Phone(1999,'4.5英寸','2200mah','魅族MX2','MX2');
$mx->tell();
echo Phone::FUNC;
echo "---------------------我是华丽丽的分界线---------------------";
$person1=clone $person;
echo intval($person1===$person);
echo $person1->class;
echo "---------------------我是华丽丽的分界线---------------------";
$person->tellhigh();
echo "---------------------我是华丽丽的分界线---------------------";
echo Person::HIGH;
echo "---------------------我是华丽丽的分界线---------------------";
abstract class Student{
    abstract function say();
    abstract function study();
    public function tell(){
        echo "这是个抽象类里面的普通方法";
    }
}
class LStudent extends Student{
    public function a(){
        echo "我是LStudent类中的a方法";
    }
    public function say(){
        echo "重写抽象类中的say方法";
    }
    function study(){
        echo "重写抽象类中的study方法";
    }
}
$LS=new LStudent();
$LS->a();
echo "---------------------我是华丽丽的分界线---------------------";
$LS->say();
echo "---------------------我是华丽丽的分界线---------------------";
interface PS{
    const NAME='串口';
    function start();
    function work();
}
interface PS1 extends PS{
    function stop();
}
abstract class PS2 implements PS{
    function start(){
        echo "抽象类实现部分方法这里是start方法";
    }
}
class PS3 implements PS1{
    function start(){
        echo "抽象类实现全部方法这里是start方法";
    }
    function work(){
        echo "抽象类实现全部方法这里是work方法";
    }
    function stop(){
        echo "抽象类实现全部方法这里是stop方法";
    }
}
$ps=new PS3();
$ps->start();
echo "---------------------我是华丽丽的分界线---------------------";
echo PS::NAME;
?>  





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-654209-1-1.html 上篇帖子: php+sqlServer2005的配置 下篇帖子: php面向对象教程
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表