php_object={
public protected private
类外部 √ × ×
继承类 √ √ ×
本类 √ √ √
$this和self区别
self是类范畴(指向类)
$this是对象实例(指向对象实例)
property_exists(对象名,属性)
# class Obj{
# public $is_public;
# protected $is_protected;
# private $is_private;
# public static $is_public_static;
# }
# $obj = new Obj();
# var_dump(property_exists('Obj','is_public')); //true;
# var_dump(property_exists($obj,'is_public')); //true;
# var_dump(property_exists($obj,'is_protected')); //true;
#先判断对象是否有这属性,如果有则返回真。
#如果没有,则继续判断该对象对应的类是否定义过这个属性,如果定义则为真,否则为假
method_exists($this,$methName)
#判断类中是否有$methName方法
class_exists('cat')
#判断某个类是否存在,一般在类外面判断
get_class($cat)
#通过类对象返回类名
构造方法
__contruct(){ #系统调用,没有返回值,既没有return
} #在创建一个类的新对象时,系统会自动调用,完成对象初始化
#在类中,类的构造方法只有一个
析构函数
class 类{
public function __destruct(){
#会在到某个对象的所有引用都被删除或者
#当对象被显式销毁时执行会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行
} #没有形式参数
} #记住,析构函数都是public
$b=$a;
#$a==$b;$a===$b
#对象赋值,是值拷贝,拷贝的不是数据本身,而是对象标识符,也就是$a(或$b)改变,$b(或$a)也会变;
#但$a="",unset($a)或者$b时,另外一方都不会改变
# 面向对象的三大特征
# 封装 、继承、多态
封装就是用访问修饰符来修饰成员方法和成员属性。从而达到对成员方法和成员属性的隐藏和访问控制。
访问修饰符
public:#被public修饰的成员方法和成员属性,在类里和类外都可以被访问。(公有)
protected:#被public修饰的成员方法和成员属性,在类里和子类中都可以被访问。(受保护)
private:#私有化的成员属性在类外不可以访问。(私有)
私有化的成员属性在类里可以被访问。
私有化的成员方法在类外不可以被访问。
私有化的成员方法在类里可以被访问。
魔术方法
__get($属性名)
#当在类外访问一个私有化成员属性(protected,private)时或该属性不存在时,魔术方法__get会被自动访问。因为公有可以直接访问
__set($属性名,$属性值)
#在类外给私有化成员属性(protected,private)赋值时。魔术方法__set会被自动调用。
__isset($属性名){
return isset($this->$属性名);
}
#用于检测私有属性值是否被设定。如果是公有的,直接可以用isset($对象->属性);
#当在类外部使用 isset() 函数来测定对象里面的私有成员是否被设定时,就会自动调用 __isset() 方法来检测。
__unset($属性名){
unset($this->$属性名);
}
#方法用于删除私有属性。
#同 isset() 函数一样,unset() 函数只能删除对象的公有成员属性,当要删除对象内部的私有成员属性时,需要使用__unset() 方法:
__toString(){
}
# 一定要有个返回值(return 语句),无参数
#在以字符串形式输出类对象时,魔术方法__toString()会被自动调用。
# 在__toString()要return一个字符串。return的字符串可以作为对当前类的说明。
# $a= new Person('WBlog'); echo $WBlog;//直接输出对象引用则自动调用了对象中的__toString()方法
__call()
#在调用类中不存在的成员方法时,魔术方法__call()会被自动调用。当我们希望在类的外部调用不可访问的成员方法
#魔术方法__call()需要两个参数。第一参数是访问的不存在的成员方法的名称。第二个参数是访问不存在的成员方法的参数。第二个参数格式是数组。将多个功能相似的成员方法写入到__call()。
#method_exists($this,$methName)判断类中是否有$methName方法
__clone()
#当我们$对象1=clone $对象2;时,对象1和对象2对象标识符不一样,$对象1改变属性(或者unset),$对象2不会改变;属性值一样,但数据空间不一样
#$对象1==$对象2 正确;$对象1===$对象2 错误
#在应用关键词clone时,魔术方法__clone()会被自动访问。给成员属性赋初值。
#当我们希望阻止克隆时,则可用 private
4、static关键词 静态方法
#静态属性,是该类的所有对象共享的变量,任何一个类的对象去访问它时,取到的都是相同的值
#任何一个类去修改它时,修改的也是同一个变量
# - static 不可以用来声明类
# - static 可以用来修饰成员属性
# - static 可以用来修饰成员方法
定义:
1:static 属性名;
2:static (public/protected/private)属性名;
访问:
类内部:self::$属性名 或 类名::$属性名
类外部:静态属性必须为public,否则不然直接访问; 类名::$属性名
方法定义: static public function tell(){
}
在类外:类名称::成员方法#只能调用static定义的方法,成员方法里面不能出现关键词$this,只能用self访问静态属性
# 静态方法不能访问非静态属性,也就是说不能$this->属性名
在类里面:self::成员方法#只能调用static定义的方法,成员方法里面不能出现关键词$this,只能用self访问静态属性
# 静态方法不能访问非静态属性,也就是说不能$this->属性名
__autoload()
#在类被实例化时会被自动访问。autoload魔术方法必须要求一个参数。当使用到一个未定义的类时,就会自动触发
#作用:自动加载类。
#继承
一、概念
用一个已经定义好的类,继承先前定义的类。
先前定义好的类:父类
已经定义好的类:子类
PHP中的继承是单继承的。
并不是复制,只是建立了查找关系
作用:解决代码复用性,减少冗余度rǒng yú,有利于类的维护
class 子类名称 extends 父类名称{#子类就自动拥有父类定义的属性和方法
}
子类访问父类方法:父类::方法名(或parent::方法名)
#在创建某个子类对象时,也就是new ();默认情况会调用父类的构造函数(子类不定义构造函数 __construct()时),如子类定义了构造函数 __construct(),则先访问子类,
#这时如果要在子类里执行父类的构造函数parent::__construct();
#并不是父类的方法和属性,子类都可以访问,只能访问父类public和protected属性和方法
#子类可以访问父类public属性和方法(子类内部和子类外部)
#子类访问父类protected属性和方法(子类内部)
#访问规则:当我们访问子类属性和方法时,先到子类查找,没有再到父类,如果父类还有父类,以此类推
#重载
在子类中重新定义父类中的成员方法。
在子类中访问父类中被重载的成员方法:
parent::被重载的成员方法
# 面向对象的关键词
1、final
final public function moreTesting() {#如果父类中的方法被声明为 final,则子类无法覆盖该 方法。如果一个类被声明为 final,则不能被继承。
echo "use moreTesting\n";
}
- 被final修饰的类不能被继承。# final class BaseClass {)
- 被final修饰的成员方法不能被重写。
- final不能用来修饰成员属性。
2、a instanceof b
- 判断变量a是否为b类的实例
# class A { }
# class B { }
# $a = new A;
# $b = new B;
# $a2 = new A;
# echo $a instanceOf $a; // true
# echo $a instanceOf $b; // false
# echo $a instanceOf $a2; // true
3、const
- 定义常量(除对象外的其他类型)
- 语法:
变量名字母一般都大写,可以被子类继承
const 常量名称=常量值
- 访问
类外:类名称::常量名称
类里:self::常量名称
注: define同样用于定义常量,但是在类中不能使用
define定义常量在同一作用域下,define()常量名和const定义的常量名不能相同.
命名空间不支持define。不建议使用。
单例模式
1、用途:
防止内存空间浪费
2、实际应用
数据库类实例化。
3、单例模式实现过程
- 禁止类对象在类外被实例化。
将构造方法私有化
- 定义静态化成员方法,在类里面实例化类,获取类对象
- 在类中声明静态化成员属性$obj.
- 在静态化成员方法中对静态化成员属性是否为空进行判断。
若为空,则实例化类。将实例化后的类对象赋值给静态化成员属性
若不为空,则直接返回静态化成员属性。
#抽象类
#作用:让其他人来继承抽象类,并实现抽象方法
abstract class AbstractClass#不能被实例化,也就是不能new,只能被继承,
{
abstract protected function getValue();#强制要求子类定义这些方法,且不能有函数体
abstract protected function prefixValue($prefix);#参数可以增加
// 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "\n";
}
}
class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
}
public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
}
#接口
接口(interface)#定规范,保持统一性;
# 接口不能实例化
# 接口的属性必须是常量
# 接口的方法必须是public【默认public】,且不能有函数体
# 类必须实现接口的所有方法
# 一个类可以同时实现多个接口,用逗号隔开
#可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
interface usb{
const brand = 'siemens'; # 接口的属性必须是常量
public function connect(); #接口的方法必须是public【默认public】,且不能有函数体
}
## new usb(); // 接口不能实例化
#类实现接口
class Android implements usb{
public function connect(){ # 类必须实现接口的所有方法
echo '实现接口的connect方法';
}
}
interface usbA{
public function connect();
}
interface usbB{
public function contact();
}
# 类可以同时实现多个接口
class mi implements usbA,usbB{
public function connect(){
}
public function contact(){
}
}
#类命名空间
#解决类名的重命名
namespace my;#命名空间,防止重复,就像一个包厢,之前是客厅
#如需在其他文件使用该类,两种写法:
1:
use my\name;#name是类名,有命名空间的一定要写,否则报错,use只能引用一个类
$obj=new name();
2:
$obj=new my\name(); # 和上面一样
#两种方法都需要首先引入类文件,原始方法include_once "类.php";
# spl_autoload_register(function ($class_name) {
# include_once $class_name . '.php';
# });
# 更简单的方法,自动加载类文件
}