欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP - 面向对象

程序员文章站 2022-04-29 12:27:27
...
PHP -- 面向对象
PHP – 面向对象

PHP – 面向对象

Table of Contents

  • 函数调用
  • 有 __clone 和无 __clone
  • 继承
  • protected
  • static
  • final
  • const
  • 后期绑定, 又叫延迟绑定
  • 单例模式 instanceof
  • 魔术方法
  • 重载 覆盖
  • 魔术常量
  • 抽象类和接口
  • 命名空间
  • 其他对象方法
  • 自动加载
  • TODO SPL 函数

函数调用

class test {    public function f1() {        echo 'you call me!';    }    public function f2() {        f1();    }}$t = new test();$t->f2();                  // 报错// public function f2() {  // 正确//     self::f1();// }// public function f2() {  // 正确//     static::f1();// }

有 __clone 和无 __clone

一个值得注意的地方 __clone() cannot accept any arguments
  1. 直接赋值 (复制), 不会产生新的对象
    class test {    public function __construct() {        echo 'ok';    }    public function __destruct() {        echo 'fail', '
    '
    ; }}$a = new test();$b = $a; // 指向同一个内存空间echo '
    '
    ;// ok// -----// fail
  2. clone 会生成一个新的对象, 但不会调用构造函数
    class test {    public function __construct() {        echo 'ok';    }    public function __destruct() {        echo 'fail', '
    '
    ; }}$a = new test();$b = clone $a; // 指向不同的 内存空间echo '
    '
    ;// ok// ---------------// fail// fail
  3. __clone 调用析构函数
    class test {    public function __construct() {        echo 'ok', '
    '
    ; } public function __destruct() { echo 'fail', '
    '
    ; } public function __clone() { return self::__construct(); }}$a = new test();$b = clone $a; // 指向不同的 内存空间echo '
    '
    ;// ok// ok// -----// fail// fail

    继承

    class A {    function foo() {        if (isset($this)) {            echo 'this is defined (',  get_class($this), ')', '
    '
    ; } else { echo 'this is not defined', '
    '
    ; } }}class B { function bar() { A::foo(); }}$a = new A(); // this 变成 A$a->foo();A::foo();// this is defined (A)// this is not defined$b = new B(); // this 变成 B$b->bar();B::bar();// this is defined (B)// this is not defined

    继承的时候权限只能越来越大, 不能变小

    class A {    protected $a = 'a';    protected function f() {        echo $this->a, '
    '
    ; }}class B extends A{ private function f() { echo $this->a, '
    '
    ; }}$b = new B();$b->f(); // 报错

    protected

    class A {    protected $a = 'a';    public function f() {        echo $this->a, '
    '
    ; }}class B extends A{ public function f() { echo $this->a, '
    '
    ; }}$b = new B(); // 可以继承 protected$b->f();

    static

    static 变量
    所有实例化的实例化的类共享的变量, 其中一个改变了, 其他的也跟着改变

    class stu {    public static $fee;    function f($fee) {        self::$fee += $fee;    }}

    static 方法
    不可以操作 $this 变量, 使用 static 方法的情景, 一般的原则是某个方法中不包含 $this 变量

    calss stu {    static function func1() {        static::func2();    }    static function func2() {         ...    }}

    调用: stu::func2();, stu::func1();

    final

    使用 finnal 的场景:

    1. 出于安全的考虑, 某个类的方法不允许被修改
    2. 不希望被其他的类继承

    final 不能修饰成员属性 (变量)

    final 方法, 表示此方法不能被重写

    class BaseClass {   public function test() {       echo "BaseClass::test() called\n";   }   final public function moreTesting() {       echo "BaseClass::moreTesting() called\n";   }}class ChildClass extends BaseClass {   public function moreTesting() {       echo "ChildClass::moreTesting() called\n";   }}// Results in Fatal error: Cannot override final method BaseClass::moreTesting()

    final 类, 表示此类不能被继续被 extends

    final class BaseClass {   public function test() {       echo "BaseClass::test() called\n";   }   // 这里无论你是否将方法声明为 final,都没有关系   final public function moreTesting() {       echo "BaseClass::moreTesting() called\n";   }}class ChildClass extends BaseClass {}// 产生 Fatal error: Class ChildClass may not inherit from final class (BaseClass)

    const

    class  MyClass {    const  constant  =  'constant value' ;    function  showConstant () {        echo   self :: constant  .  "\n" ;    }}echo  $class :: constant . "\n" ;  // 自 PHP 5.3.0 起

    后期绑定, 又叫延迟绑定

    延迟绑定的意思, self 的绑定是运行时候计算, 看下面

    class Par {    public static function whoami() {        echo 'parent', '
    '
    ; } public static function say() { self::whoami(); } public static function say2() { static::whoami(); }}class Sun extends Par { public static function whoami() { echo 'sun', '
    '
    ; }}Sun::say(); // parent, 因为执行环境变成了 parentSun::say2(); // sun, 保持静态

    单例模式 instanceof

    class mysql {    public static $ins;    private function __construct() {        /* do something */    }    private function __clone () {}      // 禁止继承的类修改自身, 也可以使用 final    public static function getIns() {        if (!(self::$ins instanceof mysql)) {            self::$ins = new self();        }        return self::$ins;    }}$a = mysql::getIns();$b = mysql::getIns();var_dump ($a === $b);              // true

    魔术方法

    1. __get
      class test {    public $hello = 'normal hello';    public function __get($args) {        if ($args == 'hello') {            echo 'from get: hello';        } else if ($args = 'other') {            echo 'from get: other';        }    }}$t = new test();echo $t->hello, '
      '
      ; // normal hello, 如果存在不会调用 魔术方法echo $t->other; // 不能调用, 调用魔术方法
    2. __set
      class test {    public $hello = 'normal hello';    public function __set($k, $v) {        echo 'you want to set me! ', $k, '
      '
      ; $this->$k = $v; }}$t = new test();$t->ttt = 222;echo $t->ttt; // 可以设置$t->hello = 'another hello';print_r($t);// you want to set me! ttt// 222// test Object// (// [hello] => another hello// [ttt] => 222// )
    3. __isset
      class test {    public function __isset($v) {        return false;        .....        return true;    }}
      $t = new test();if (isset($t->value)) {    echo 'isset';} else {    echo 'noset';}
    4. __unset
      调用的属性不存在, 就会调用此函数, 主要用于友好操作
    5. __call
      无权调用的时候, 传递两个参数, (function_NAME, array function_ARGS)
      class test {    public function func_empty() {        echo 'nothing here';    }    public function __call ($func, $args) {        self::func_empty();    }}$t = new test();
      class test {    public function func_empty() {        echo 'nothing here';    }    public function __call ($func, $args) {        print_r($args);        self::func_empty();    }}$t = new test();$t->abc('abc', 'def');// Array ( [0] => abc [1] => def )
    6. __callStatic
      public static function  __callStatic ( $name ,  $arguments ) { ... }
    7. 重载 覆盖

      覆盖: override 指的是子类覆盖父类的方法, 在 PHP 中, 如果 子类和父类的参数不一样会有警告
      重载: redeclare 指的是同一个类中包含两个相同名字的方法, PHP 不支持

      实现重载的方法

      func_num_args()           返回数据的参数的个数$arr = func_get_args()    让参数以数组的形式返回func_get_arg(0)           返回第一个参数func_get_arg(1)           返回第二个参数
      public function f() {    $arr = func_get_args();    foreach($arr as $v) {        ....   }}

      魔术常量

      __LINE____FILE____DIR____FUNCTION____CLASS____METHOD__

      抽象类和接口

      abstract

      abstract class Car {   abstract function func1();}class Fastcar extends Car {   public function func1() {     ...   }}
      1. 继承类必须实现抽象类的 所有 方法
      2. 抽象类可以有自己的属性
      3. 抽象类可以有自己的实现方法, 也叫具体方法, interface 没有
      4. 可以有 protected 方法, interface 不可以

      interface

      interface iUsb {    public function f();}class phone implements iUsb {    public function f() {        ..    }}

      定义规范

      当多个类, 之间平级的, 有相同的方法, 但是实现不同

      类可以实现多个接口, 接口可以实现多个接口

      class t1 implements i1, i2, i3 { }interface i1 extends i2, i2, i3 {}
      1. 继承类要实现 接口的全部方法
      2. interface 不能有 private 的方法
      3. interface 里面的属性只能是 常量
      4. interface 里面不能实现方法, 抽象类可以, (可以理解接口里面全都是抽象方法)
      5. interface 可以定义常量
      class Monkey {    public function climb() { ... }}interface iBirdable {    public function fly();}interface iFishable {    public function swim();}class NewMonkey extends Monkey implements iBirdable, iFishable {    public function fly()  { ... }    public function swim() { ... }}

      抽象类和接口的区别我不是 很熟悉 T_T, mark 个 todo 以后再来补充

      1. 如果要创建一个模型, 这个模型将由一些紧密的对象采用, 就可以使用抽象类. 如果要创建由一些不相关对象采用的功能, 使用接口
      2. 如果必须从多个来源继承行为, 就使用接口. 接口可以实现多个, 不可以继承多个抽象类
      3. 如果所有的类会有共享一个公共的行为实现, 就使用抽象类, 并在其中的实现该行为, 在接口中无法实现具体方法

      命名空间

      如果文件 1 有 test 对象, 文件 2 也有 test 对象
      在文件 3

      require 'file1.php';require 'file2.php';

      那么就会出现冲突

      test1.php

      namespace test\file1;class test {    public $val = 'this is file 1';}

      test2.php

      namespace test\file2;      # 也可以使用别的命名空间 ...\...\...\...class test {    public $val = 'this is file 2';}

      test.php 用于加载访问

      require 'test1.php';require 'test2.php';$t1 = new test\file1\test();$t2 = new test\file2\test();echo $t1->val, '
      '
      ; // this is file1echo $t2->val, '
      '
      ; // this is file2use test\file1 as file1;use test\file2 as file2;$t3 = new file1\test();$t4 = new file2\test();echo $t3->val, '
      '
      ; // this is file1echo $t4->val, '
      '
      ; // this is file2

      其他对象方法

      class_alias(class_name, new_classname)get_class (OBJ)$arr = get_declared_classes()       # 返回已经定义了的类get_parent_class (OBJ)interface_exists (INTER)            # 是否存在接口method_exists (OBJ, FUNC_NAME)      # 是否存在某个方法

      自动加载

      function  __autoload ( $class_name ) {    require  $class_name  .  '.php' ;}$obj   = new  MyClass1 ();      // 自动会调用上面的哪个函数, 参数名是 MyClass1$obj2  = new  MyClass2 ();      // 自动会调用上面的哪个函数, 参数名是 MyClass2

      为什么函数里面的 require class 的生活周期可以到外层, 原因像下面的,
      __autoload 被执行之后, 就相当于把函数里面的代码展示出来

      function well() {    function test() {        echo 'inside ', '
      '
      ; }}well(); // 一定要先调用test(); // inside
      __autoload 的实现spl_autoload_register —— 注册给定的函数作为 __autoload 的实现
      function func() {    require '...';}spl_autoload_register(func);

      TODO SPL 函数

      PHP - 面向对象

      声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

      相关文章

      相关视频


      网友评论

      文明上网理性发言,请遵守 新闻评论服务协议

      我要评论
    8. PHP - 面向对象
    9. 专题推荐

      作者信息
      PHP - 面向对象

      认证0级讲师

      推荐视频教程
    10. PHP - 面向对象javascript初级视频教程
    11. PHP - 面向对象jquery 基础视频教程
    12. 视频教程分类
相关标签: function public test class echo

上一篇: JavaScript插件化开发教程 (四)_javascript技巧

下一篇: HTTP服务器是如何实现对PHP的支持的?

推荐阅读