抽象类和接口的概念和区别
1. 概念:
抽象类:是一种特殊的,不能被实例化的类,只能作为其他类的父类使用。使用abstract关键字声明。
接口:是一种特殊的抽象类,使用interface声明。
2. 区别:
(1). 抽象类的操作通过继承关键字extends实现,而接口的使用是通过implements关键字来实现。
(2). 抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员。
(3). 抽象类可以有构造方法,但是接口没有构造方法。
(4). 抽象类的方法可以通过private, protected, public关键字修饰(抽象方法不能是private),而接口中的方法只能使用public关键字。
(5). 一个类只能继承于一个抽象类,而一个类可以同时实现多个接口。
(6). 抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。
什么是构造函数,什么是析构函数,作用是什么?
构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。php中使用__contruct()声明构造方法,并且只能声明一个。
析构函数(方法)和构造函数刚好相反,是对象被销毁之前最后一个被对象自动调用的方法。是php5中新添加的内容,作用是用于实现再销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。
PHP中常用的魔术方法
PHP将所有以__(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,建议不要以__为前缀。
1. __construct():PHP允许开发者在一个类中定义一个方法作为构造函数,具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。如果子类中定义了构造函数,则不会隐式调用其父类的构造函数,要执行父类的构造函数,需要在子类的构造函数中调用parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承。在php中每个class只能有一个构造器。然而有些情况下,需要用不同的输入实现不同方式构造对象。这种情况下推荐使用static方法包装构造。
2. __destruct():PHP引入了析构函数的概念,这类似于其它面向对象的语言,如C++。析构函数会在某个对象的所有引用都被删除或者当对象被显式销毁时执行。和构造函数一样,如果子类中定义了析构函数,则不会隐式调用其父类的析构函数,要执行父类的析构函数,需要在子类的析构函数中调用parent::__destruct()。此外,子类如果没有定义析构函数,则会继承父类的。析构函数即使在使用exit()终止脚本运行时也会被调用。在析构函数中调用exit()将会终止其余关闭操作的运行。析构函数在脚本关闭时调用,此时所有的HTTP头信息已经发出。脚本关闭时的工作目录可能和在SAPI(如apache)中时不同。试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。
3. __call():在对象中调用一个不可访问方法时,__call()会被调用。
4. __callStatic():在静态上下文中调用一个不可访问方法时,__callStatic()会被调用。
5. __get():读取不可访问属性的值时,__get()会被调用。
6. __set():给不可访问属性赋值时,__set()会被调用。
7. __isset():当对不可访问属性调用isset()或empty()时,__isset()会被调用。
8. __unset():当对不可访问属性调用unset()时,__unset会被调用。
9. __sleep():serialize()函数会检查类中是否存在一个魔术方法__sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则null被序列化,并产生一个E_NOTICE级别的错误。注意,__sleep()不能返回父类的私有成员的名字。这样做会产生一个E_NOTICE级别的错误。可以用Serializable接口来替代。__sleep()方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。
10. __wakeup():unserialize()会检查是否存在一个__wakeup()方法。如果存在,则会先调用__wakeup()方法,预先准备对象需要的资源。__wakeup()经常用在反序列化操作中,例如重新创建数据库连接,或执行其他初始化操作。
11. __serialize():serialize()函数会检查类中是否存在一个魔术方法__serialize()。如果存在,该方法将在任何序列化之前优先执行。它必须以一个代表对象序列化形式的键值对的关联数组形式来返回,如果没有返回数组,将会抛出一个TypeError错误。注意,如果类中同时定义了__serialize()和__sleep()两个魔术方法,则只有__serialize()方法会被调用。__sleep()方法会被忽略掉。如果对象实现了Serializable接口,接口的serialize()方法会被忽略,作为代替类中的__serialize()方法会被调用。
12. __unserialize():如果类中同时定义了 __unserialize() 和 __wakeup() 两个魔术方法,则只有 __unserialize() 方法会生效,__wakeup() 方法会被忽略。
13. __toString():方法用于一个类被当成字符串时应怎么回应。例如echo $obj;应该显示什么。此方法必须返回一个字符串,否则将发出E_RECOVERABLE_ERROR级别的致命错误。不能在__toString()中抛出异常。这么做会导致致命错误。需要指出的是在PHP5.2.0之前,__toString()方法只有在直接使用于echo或print时才能生效。PHP5.2.0之后,则可以再任何字符串环境生效。自PHP5.2.0之后,如果一个未定义__toString()方法的对象转换成字符串,会产生E_RECOVERABLE_ERROR级别的错误。
14. __invoke():当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用。本特性只在 PHP 5.3.0 及以上版本有效。
15. __set_state():自PHP5.1.0起调用var_export()导出类时,此静态方法会被调用。本方法的唯一参数是一个数组,其中包含按array('property'=>value,...)格式排列的类属性。
16. __clone():当使用clone复制一个对象时候调用。
17. __debugInfo():打印所需调试信息。该方法在使用 var_dump()是被调用。如果该方法没有被定义,则所有的public, protected和private属性都会被显示出来。该方法在PHP 5.6.0及其以上版本才可以用。
参考链接:https://www.php.net/manual/zh/function.isset.php
$this和self,parent这三个关键词分别代表什么?在哪些场合使用?
1. $this:当前对象。在当前类中使用,使用->调用属性和方法。
2. self:当前类。self也在当前类中使用,不过需要使用::调用。
3. parent:当前类的父类。在类中使用。
网友评论