php-面向对象

php-面向对象

  • 函数

    // 匿名函数也叫做闭包函数,允许临时创建一个没有指定名称的函数,最经常用作回调函数参数的值。 
  • 类与对象

    // 1.类的定义 class SimpleClass { // 声明属性 public $var = 'a default value'; // 声明方法 public function displayVar() { echo $this -> var } } /* $this说明 假如类的对象去调用类里定义的方法,那么这个$this就是这个对象,如果是类去使用的话,那么这个$this是没有值的。 关于$this,在php5和php7中有部分是不一样的 假如有两个对象(a,b),这两个对象对应的类是不一样的,一个对象(a)里的方法调用了另一个类(b对象的类)里的方法,那个类里的方法有一个$this这个属性,那么此时这个$this的值应该是什么呢? 1.在php5中,这个$this就是a这个对象 2.在php7中,这个$this是没有值的 */ // 对象的创建,也就是类的实例 $zhuyu = new People(); // 也可以这样 $className = 'People'; $zhuyu = new $classNanme(); // 对象赋值 $zhuyu = new $People(); $zhuchunyu = $zhuyu; $zhu = &$zhuyu; $zhuyu -> var = 'var'; $zhuyu = null; var_dump($zhuyu); // 输出值为null var_dump($zhu); // 输出值为null var_dump($zhuchunyu); // 有输出值 /* 简化上面的结论,大概就是这样一段代码 $b = $a; $c = &$a; $a = null; 首先$b = $a;这行代码就是一个普通的赋值,那么$b所对应的$a所对应的值的内存地址,它和$a是是没有丝毫关系的 再看$c = &$a;这是引用赋值吧,所以说$c对应的值的内存地址和$a所对应的值的内存地址是息息相关的,它是跟着$a所变换的 最后$a = null;这也是一个普通的赋值,那么$a对应的是null的内存地址,之前$c的值是个$a的值是有关系的,所以$c也变成了null,$b的内存地址还是对应之前的内存地址。 */ // 创建新对象 class Test { static public function getNew() { return new static; } } class Child extends Test{} $obj1 = new Test(); $obj2 = new $obj1; var_dump($obj1 !== $obj2); // ture $obj3 = Test::getNew(); var_dump($obj3 instanceof Test); $obj4 = Child::getNew(); var_dump($obj4 instanceof Child); /* 方式一:通过new一个类去创建一个对象 方式二:通过调用类里的方法,创建一个新对象 */ /* 对象属性 属性声明是由关键字开头:public protected private 访问非静态属性方式:-> 访问静态属性方式::: */ // 类常量 class A { const constant = 'constant value'; } // 构造方法 __construct() 相当于python中的__init__() class People extends BaseClass { function __construct() { // 实力对象之前,先执行偶 print '创建一个实例,先执行__construct'; $this -> name = '朱春宇' // 调用父类的__construct(), parent::__construct(); } } // 析构函数 __destruct 相对于python中 __del__方法 // 在删除一个对象之前,会先执行__destruct方法 class Test { function __destruct(){ print 'del'.$this -> name . '\n' } } // 访问控制(可见性) /* 对属性或者方法的访问控制,是通过在前面添加关键字public(公有), protected(受保护),pricate(私有)来实现的 public:可以在任何地方都可以被访问 protected:可以被自身及其子类和父类访问 private:只能被它所在的类才能访问 private相当于python中封装的思想,只能在类内部使用。 */ // 对象继承 extends /* 子类继承父类,会继承父类所有的共有方法,受保护的方法,子类也可以重写父类的方法。 */ // 范围解析操作符(::) /* 可以用来访问静态成员,类常量,还可以用于覆盖类的属性的方法和属性 比如调用父类的方法 parent::__construct */ // 静态关键字(static) /* 声明类的属性或方法为静态,就可以不实例化类而直接访问,静态属性是不能通过类实例的对象去访问的,而静态方法是可以的 访问静态属性和方法的方法都是:: */ // 抽象类实例 abstract class Test { // 强制要求子类定义这些方法 abstract public function getValue(); abstract public function prefixValue(); // 非抽象方法 public function foo(){ print '非抽象方法foo'; } } class Test1 extends Test { public function getValue() { // getvalue方法代码 } public function prefixValue(){ // prxfixValue方法代码 } } /* 对于抽象类的理解: 1.和python中abc库差不多,控制子类的一些方法属性,必须有。 2.达到上面抽象类的效果,也可以通过主动抛异常去实现,在父类定义一个函数,直接抛异常,如果继承他的类没有重写该方法,在使用到这个方法的时候,便会执行父类的方法,直接抛异常。 */ // 对象接口 /* 可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容 接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的 接口中定义的所有方法都必须是公有,这就是接口的特性 */ // 声明一个'iTemplate'接口 interface iTemplate { public function setVariable($name,$var); public function getHtml($template); } // 实现接口 class Template implements iTemplate { private $vars = array(); public function setVariable($name,$var) { $this -> vars[$name]=$var; } public function getHtml($template) { foreach($this->vars as $name=>$var){ $template = str_replace('{'.$name.'}',$value,$template); } return $template; } } // 接口之间的继承, interface a { public function faa(); } interface b extends a { public function fbb(); } class c implements b { // 这个c如果想要实现a,b接口,那么必须要有a,b接口里的所有方法 public function faa(); public function fbb(); } /* 抽象类与接口之间相同之处和不同之处 1.相同点 - 两者都是抽象类,不能进行实例化 - interface实现类及abstract class的子类都必须实现已经声明的抽象方法 2.不同点 - 接口实现需要implements,抽象类实现需要继承(extends) - 接口中声明的方法都必须是public(公有的),而抽象类声明的方法(这个方法带有abstract),可以是public,protected,但绝不能是private。如果抽象类中的方法是public类型的话,那么继承它的类的这个方法必须是public,如果抽象类中的方法是protected类型,那么 继承它的类的方法应该是public或者protected类型。 - 接口中声明的方法,只能是方法名,方法里面不能有代码块。抽象类中声明的方法可以有 - 一个类可以实现多个接口,但是只能继承一个抽象类 */ // trait 一种代码复用的方法 tarit speak { public function speakHello(){ print 'hello'."\n"; } $name = 'zhuyu'; } class A { $name = 'zhuchunyu'; } class B extends A{ use speak; } b = new B(); print b->name; // 匿名类 /*比如一些函数需要的参数需要传递类,那么可以直接new 类名()*/ // 重载: /* 定义:是指动态地创建类属性和方法,我们是通过魔法方法来实现 注意:1.所有重载方法都必须声明为public 2.这些魔法方法的参数都不能通过引用传递 3.php中的重载与其他绝大多数面向对象语言不同。传统的“重载”是用于提供多个同名的类方法,但各方法的参数类型和个数不同 */ // 属性重载 /* - 在给不可访问属性赋值时,__set(%name,$value)会被调用。 - 读取不可访问属性的值时,__get(%name)会别调用。 - 当对不可访问属性调用isset()或empty()时,__isset()会被调用。 - 当对不可访问属性调用unset()时,__unset()会被调用。 */ // 方法重载 /* - __call:在对象中调用一个不可访问的方法时,被调用 - __callStatic:在静态上下文中调用一个不可访问方法时,被调用 */ // 遍历对象 foreach class A { public $name = '朱宇'; public $age = 18; public $sex = '男'; protected $top = '1.71'; private $a = 'aa'; public function myForEach() { foreach ($this as $key=>$value){ echo $key.'='.$value."\n"; } } } $a = new A(); foreach ($a as $item=>$value){ echo $item.'='.$value."\n"; } $a->myForEach(); /* - 外面这个foreach的输入结果是没有protected,private的值的 - 函数内部里的foreach可以显示所有的属性的 - foreach它只能循环它能访问的属性 */ // 魔法方法 /* 1.__construct(),它会在new一个对象之前触发执行 2.__destruct(),它会在del一个对象之前,运行。 3.__call,它会在调用一个方法,并且这个方法不存在的时候执行 4.__callStatic,它会在调用一个静态方法,并且这个方法不存在的时候执行 5.__get(),获取一个对象的属性,并且这个属性不存在的话,那么便会执行这个魔法方法 6.__set(),再给对象的一个属性赋值时,并且这个属性不能访问,那么就会执行这个方法 7.__isset,执行isset()函数的时候,先执行 8.__unset,执行unset()函数的时候,先执行 9.__sleep(),在执行serialize()这个函数的时候,会检查类中是否存在该魔法方法,有的话,会先调用__sleep()这个方法,然后在执行序列化操作。这个方法的返回值应该是一个数组,如果这个方法没有返回值的话,那么null则会被序列化,并且产生一个E_noteic级别的错误。 10.__wakeup(),会在执行unserialize这个函数的,会先执行该魔法方法。 11.__toString(),这个方法在打印一个对象的时候,自动触发,返回值必须是字符串,和python中的__str__ 12.__invoke(),当尝试以调用函数的方法调用一个对象时,__invoke()自动触发,和python中__call__ 13.__set_state(), 14.__clone(), 15.__debuginfo(), 16.__autoload(), */ // final关键字 // 如果父类中的方法被声明为final,则子类无法覆盖该方法,如果一个类被声明为final,则不能被继承 // final方法示例 class BaseClass { public function faa(){ print 'faa'."\n"; } final public function fbb(){ print 'fbb'."\n"; } } class AClass extends BaseClass { public function fbb(){ print 'AClass fbb'."\n"; } } $a = new AClass(); $a->fbb(); // final类实例 final class BaseClass { public $name; } class AClass extends BaseClass{} $a = new AClass(); echo $a ->name; // 对象复制 __clone方法 class SubObject { static $instances = 0; public $instance; public function __construct() { $this->instance = ++self::$instances; } public function __clone() { $this->instance = ++self::$instances; } } class MyCloneable { public $object1; public $object2; function __clone() { // 强制复制一份this->object, 否则仍然指向同一个对象 $this->object1 = clone $this->object1; } } $obj = new MyCloneable(); $obj->object1 = new SubObject(); $obj->object2 = new SubObject(); $obj2 = clone $obj; print("Original Object:\n"); print_r($obj); print("Cloned Object:\n"); print_r($obj2); /* 上面的打印的效果为 $obj -> object1为 1 ,$obj -> object2为 2 $obj2 -> object1为 3 ,$obj -> object2为 2 首先__clone方法只有调用clone这个方法,才会去执行 在执行$obj2 = clone $obj这行代码之前,$obj这个对象的的属性值为 object1为1,object2为2, 在执行$obj2 = clone $obj这行代码的时候,首先会去执行$obj这个对象里的__clone方法,这个$obj是类MyCloneable的对象,那么就去看这个类里的__clone方法,这个方法执行这行代码$this->object1 = clone $this->object1;首先会执行clone $this->object1这行代码,$this->object1对应的是SubObject类的对象,便会执行该类里的__clone方法,此时$instances的值为2,那么执行__clone之后的话,$instance的值就是3了,最终的代码为 $this->object1 = 一个SubObject的对象,对象里$instance的值为3。 */ // 对象比较 /* 1.使用(==)双等号进行比较的话,比较的原则是:如果两个对象的属性和属性值都相等,并且两个对象是同一个实例,那么这两个对象变量相等。 2.如果使用(===)全等符号,这两个对象变量一定要指向某个类的同一个实例(即同一个对象) 思考 $a=$b它是怎么个过程,$a,$b都是一个对象 */ // 类型约束:在方法或者函数的参数之前,加一个类型,就是对参数的类型约束了。 // 后期静态绑定 /* 用法:self::对当前类的静态引用,__CLASS__是当前对象的类名 static:: parent::执行器父类的方法 */ // 对象和引用 /* 关于这行代码 $a = $b,($b只是一个类的对象),在php的对象编程中,我觉得就是引用传递,$a,$b它们指向的内置地址都是同一个,所有一旦其中一个改变属性,对应的它对应的内存地址的值发生改变,所有另一个变量也会进行改变。 */ // 对象序列化 /* php里面的值,都可以使用函数serialize()来返回一个包含字节流的字符串来表示,unseralize()函数则是能够把字符串重新转换为原来的php值。序列化一个对象会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字 */

转载于:https://www.cnblogs.com/zhuchunyu/p/10648676.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101004.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 利用iframe技巧获取訪问者qq

    利用iframe技巧获取訪问者qq

  • 一文读懂C++虚继承的内存模型

    一文读懂C++虚继承的内存模型一文读懂C++虚继承的内存模型1、前言2、多继承存在的问题3、虚继承简介4、虚继承在标准库中的使用5、虚继承下派生类的内存布局解析6、总结1、前言C++虚继承的内存模型是一个经典的问题,其具体实现依赖于编译器,可能会出现较大差异,但原理和最终的目的是大体相同的。本文将对g++中虚继承的内存模型进行详细解析。2、多继承存在的问题C++的多继承是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。从概念上来讲这是非常简单的,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突

  • nginx中location的使用

    nginx中location的使用

  • redis客户端连接(error) NOAUTH Authentication required「建议收藏」

    redis客户端连接(error) NOAUTH Authentication required「建议收藏」redis客户端连接成功,但是操作报异常——(error)NOAUTHAuthenticationrequired错误的含义是说你没有认证,说明没有使用密码连接查看密码:进入redis的安装目录(是安装目录的),查看redis.config文件viredis.config打开配置文件后,输入#requirepassfoobared(快速定位的命令)然后回车红框里的就是密码使用密码连接.

  • MySQL重设密码_mysql重置密码命令

    MySQL重设密码_mysql重置密码命令1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的状态下,其他的用户也可以任意地登录和修改MySQL的信息。可以采用将MySQL对外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全状态。最安全的状态是到服务器的Console上面操作,并且拔掉网线。2.修改MyS…

    2022年10月16日
  • MATLAB实现线性插值interp1的功能

    MATLAB实现线性插值interp1的功能1.关于插值插值,它根据已知的数据序列(也可以理解为坐标中一连串离散的点),找到其中的规律;然后根据找到的这个规律,来对其中尚未有数据记录的点进数值的估计。2.关于线性插值线性插值是一种针对一维数据的插值方法,它根据一维数据序列中需要插值的点的左右邻近两个数据点来进行数值的估计。当然了它不是求这两个点数据大小的平均值(当然也有求平均值的情况),而是根据到这两个点的距离来分配它们的比重的。而对于一些边缘处的点也需要使用到外插:即通过找出最近的两个点,通过建立该两点之间的一元一次线性方程通过带入x即可以得

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号