1.类与对象
类是变量与作用于这些变量的函数的集合。对象:实际存在该类事物中每个实物的个体。$a =new User(); 实例化后的$a。创建对象的过程称为实例化。
例:computer.php
class Computer{ //创建一个Computer类
var $price=3000; //成员变量 定义价格变量$price为3000 属性
function getPrice(){ //成员函数 创建一个获取价格封装在getPrice方法(函数)中
echo 'price: '.$this->price; //打印价格 this是指向当前对象的指针
}
}
$mypc = new Computer(); //创建一个实例
$mypc->getPrice ();//调用getPrice方法获取价格
?>
结果:
2.定义类
使用class关键字来创建一个类,类名的首字符一般要大写。
类定义结构如下:
class 类名 [extends 父类名]
{
成员变量列表
成员函数列表
}
方括号中的内容为可选内容。
例:class.php
class Super{ //创建 Super类
}
class Sub extends Super { //创建Sub类,并继承父类Super
var $p1 = "Hello p1!";//成员变量
function show(){ //成员函数 show方法
echo $this->p1; //$this当前对象
}
}
$print = new Sub(); //实例化
$print -> show();//调用show方法打印
?>
结果:
3.创建对象与销毁对象
例:create_destroy_obj.php
class Obj{
}
$object1 = new Obj(); //创建一个新的对象,$object1的引用计数加1
$object2 = $object1; //引用复制,$object1的引用计数等于2,$object2的引用计数等于1
unset($object1); //销毁对象$object1,$object1的引用计数减1,但引用计数并不为0,$object1中成员变量内存空间并没有释放
unset($object2); //销毁对象$object2,$object2的引用计数减1,引用计数为0,此时自动释放所有内存空间
?>
4.类的成员变量与成员函数
在类中定义成员变量(属性),只要在变量名前加public(公有)、private(私有)或者proteced(保护)类型关键词修饰。
在类中定义函数即成员函数(方法),它的定义方法和一般函数基本相同,使用function关键字声明,并在function关键字前加public(公有)、private(私有)或者proteced(保护)类型关键词修饰。
例:function.php
class Super{ //创建Super类
private $p1 = 'hello p1!'; //成员变量 私有 $p1 属性
public function show(){ //成员函数 show()方法 公有
echo $this->p1; //$this指当前对象
}
}
class Sub extends Super{//创建Sub类 并继承父类Super
private $p2 = 'hello p2!'; //成员变量 私有 $p2 属性
public function show(){//成员函数 show()方法 公有
echo $this->p2;//$this指当前对象
}
}
$s = new Sub(); //创建实例
$s->show(); //调用show()方法
?>
结果:
5.类的访问控制
作用域
全局
同一个类
子类
public
√
√
√
private
√
protected
√
√
例:access.php
class Super { //创建一个Super类
private $p1 = "Hello p1!"; //成员变量 属性 私有 $p1
protected $p2 = "Hello p2!"; //成员变量 属性 保护 $p2
public $p3 = "Hello p3!"; //成员变量 属性 公有 $p3
function show () { //成员函数 show方法
echo 'super:'.$this->p1."
"; //this指当前对象 打印super:Hello p1
echo 'super:'.$this->p2."
"; //this指当前对象 打印super:Hello p2
echo 'super:'.$this->p3."
"; //this指当前对象 打印super:Hello p3
}
}
class Sub extends Super { //创建一个Sub 父类Super
private $p4 = "Hello p4!";//成员变量 属性 私有 $p4
function show() { //成员函数 show方法
Super::show();//调用父类 show方法 打印super:Hello p1 super:Hello p2 super:Hello p3
echo 'sub:'.$this->p1."
"; // $p1未定义 无法调用父类Super 私有成员变量 打印 sub:
echo 'sub:'.$this->p2."
"; //打印sub:Hello p2
echo 'sub:'.$this->p3."
"; //打印sub:Hello p3
echo 'sub:'.$this->p4."
";//打印sub:Hello p4
}
}
$s1 = new Super();//实例化
$s1->show (); //调用show方法
$s2 = new Sub();//实例化
$s2->show();//调用show方法
//echo 'global:'.$s1->p1."
"; //访问失败 在类的外部,不能访问类的私有和保护类型的成员变量
//echo 'global:'.$s1->p2."
"; //访问失败
echo 'global:'.$s1->p3."
"; // 打印 global: Hello p3
echo 'global:'.$s2->p1."
"; //无效数据 由于类Sub中没有定义变量$p1,所以输出了空值
//echo 'global:'.$s2->p2."
"; //访问失败
echo 'global:'.$s2->p3."
"; //打印 global: Hello p3
//echo 'global:'.$s2->p4."
"; //访问失败
?>
结果:
6.类的构造函数
构造函数
void __construct ([ mixed $args [, $... ]] )
构造函数可以接受参数,能够在创建对象时赋值给对象属性
构造函数可以调用类方法或其他函数
构造函数可以调用其他类的构造函数
PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。
构造函数格式如下:
class 类名 [extends 父类名] {
[public/private/protected] function __construct()
{
}
}
之前已经知道类的成员变量和成员方法都可以被继承,类的构造函数也能被子类继承。
例:construct.php
class Super { //创建一个Super类
protected $p1; //成员变量 保护 $p1
public function __construct() //构造函数 公有 注:构造函数的关键词construct前面有两个下划线,如果只有一个下划线,将不会输出任何结果
{
$this->p1 = "Hello p1!
";//$this当前对象 Hello p1!
echo $this->p1;// Hello p1!
}
}
class Sub extends Super { //创建一个Sub类 父类Super
}
$s1 = new Super();//创建实例 打印Hello p1! 构造函数在类被实例化时调用
$s2 = new Sub();//创建实例 继承父类 打印 Hello p1!
?>
结果:
例:construct2.php
这个例子中的父类和子类都定义了构造函数,当子类的对象被创建后,将调用子类的构造函数,而不会调用父类的构造函数。
class Super { //创建一个Super类
protected $p1; //成员变量 保护 $p1
public function __construct()//构造函数 公有 注:构造函数的关键词construct前面有两个下划线,如果只有一个下划线,将不会输出任何结果
{
$this->p1 = "super::Hello p1!
";//$this当前对象 super::Hello p1!
echo $this->p1; //打印super::Hello p1!
}
}
class Sub extends Super { //创建一个Sub类 父类Super
public function __construct()//构造函数 公有
{
//parent::__construct();//调用父类构造函数 打印super::Hello p1!
$this->p1 = "sub::Hello p1!
";//$this当前对象sub::Hello p1!
echo $this->p1;//打印sub::Hello p1!
}
}
$s2 = new Sub(); //实例化 只调用子类构造函数 打印sub::Hello p1!
?>
结果:
例:construct3.php
用 parent::__construct();//调用父类构造函数,而不是parent->__construct()
就可以在子类中调用父类函数。
class Super { //创建一个Super类
protected $p1; //成员变量 保护 $p1
public function __construct()//构造函数 公有 注:构造函数的关键词construct前面有两个下划线,如果只有一个下划线,将不会输出任何结果
{
$this->p1 = "super::Hello p1!
";//$this当前对象 super::Hello p1!
echo $this->p1; //打印super::Hello p1!
}
}
class Sub extends Super { //创建一个Sub类 父类Super
public function __construct()//构造函数 公有
{
parent::__construct();//调用父类构造函数 打印super::Hello p1!
$this->p1 = "sub::Hello p1!
";//$this当前对象sub::Hello p1!
echo $this->p1;//打印sub::Hello p1!
}
}
$s2 = new Sub(); //实例化 打印super::Hello p1! 打印sub::Hello p1!
?>
结果:
7.类的析构函数
析构函数是类的一个特殊的函数,PHP将在对象销毁前调用这个函数。析构函数用于释放类中的数据资源,在默认情况下,PHP仅仅释放对象的成员变量所占用的内存。
析构函数的格式如下:
class 类名 [extends 父类名]
{
[public/private/protected] function __destruct()
{
}
}
例:destruct.php
class Super { //创建一个Super类
protected $p1; //成员变量 保护 $p1
public function __construct()//构造函数 公有
{
$this->p1 = "Hello p1!
";//$this当前对象 Hello p1!
echo $this->p1; //打印Hello p1!
}
public function __destruct()//析构函数 公有
{
echo 'desturct super
'; //打印desturct super
}
}
class Sub extends Super { 创建一个Sub类 父类Super
public function __destruct()//析构函数 公有
{
echo 'destruct sub
';//打印destruct sub
}
}
$s1 = new Super();//创建实例 //打印Hello p1!
$s2 = new Sub(); //创建实例 继承父类 打印Hello p1!
//程序结尾自动调用析构函数,首先调用的是Super析构函数 打印desturct super 然后调用Sub类析构函数 打印destruct sub 上面实例化对调,析构函数在结尾处次序也对调
?>
结果:
8.类的静态成员变量
在php中,访问类的方法/变量有两种方法:
1). 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/function,前提是该变量/方法可访问。
2). 直接调用类方法/变量:class::attribute/function,无论是静态/非静态都可以。但是有前提条件:
A. 如果是变量,需要该变量可访问。
B. 如果是方法,除了该方法可访问外,还需要满足:
b1) 如果是静态方法,没有特殊条件;
b2) 如果是非静态方法,需要改方法中没有使用$this,即没有调用非静态的变量/方法,当然,调用静态的变量/方法没有问题。
然后我们再看一下使用$object->… 和使用class::… 都有什么区别:
1). 使用$object->… ,需要执行构造函数创建对象;
2). 使用class::… 调用静态方法/变量,不需要执行构造函数创建对象;
3). 使用class::… 调用非静态方法/变量,也不需要执行构造函数创建对象。
然后奇怪的地方就出来了,既然2和3都一样,那静态方法/变量存在还有什么意义呢?
差异还是显然存在的,如下:
1. 静态变量
静态成员只保留一个变量值,而这个变量值对所有的实例都是有效,也就是说,所有的实例共享这个成员。
2. 静态方法
静态方法可以直接使用class::… 来调用,而非静态方法需要满足一定限制条件才能使用class::.. 的方法调用,如之前所述
例:static.php
class MyStatic{ //创建一个MyStatic类
private static $result = 0; //成员变量 私有 静态变量 $result为0
public function add($x){ //成员函数 公有 add函数 形参$x
MyStatic::$result = MyStatic::$result + $x; //此处为静态成员变量的调用方式,静态变量在没有实例前就可以调用
}
public function sub($x){ //成员函数 公有 sub函数 形参$x
MyStatic::$result = MyStatic::$result - $x;
}
public function getResult()//成员函数 公有 getResult函数
{
return MyStatic::$result; //返回结果
}
}
$st = new MyStatic();//创建实例
$st->add(5); //0+5=5
$st->sub(3); //5-3=2
echo 'result: '.$st->getResult();//打印result:2
?>
结果:
9.类的静态成员函数
静态成员函数的作用类似于静态成员变量,它为类的所有对象服务,而不是对仅有某个特定对象服务,它相当于全局函数作用。当一个类被创建时,静态成员函数也被创建,此时类和静态成员函数是相关联的。
例:staticfunction.php
class MyStatic{ //创建一个MyStatic类
private static $i = 1; //私有 静态成员变量 $i为1
public static function add($x){ // 公有 静态成员函数 add 形参$x
echo self::$i + $x; //自引用
}
}
$st = new MyStatic();//创建实例
$st->add(2);// 1+2=3 打印3
?>
结果:
class MyStatic{ //创建一个MyStatic类
private static $i = 1; //私有 静态成员变量 $i为1
public static function add($x){ // 公有 静态成员函数 add 形参$x
echo $this->i + $x; //在静态方法中不能调用非静态的方法。静态方法只能调用静态成员变量
}
}
$st = new MyStatic();//创建实例
$st->add(2);//
?>
结果:
注:在访问PHP类中的成员变量或方法时,如果被引用的变量或者方法被声明成const(定义常量)或者static(声明静态),那么就必须使用操作符::,反之如果被引用的变量或者方法没有被声明成const或者static,那么就必须使用操作符->。
另外,如果从类的内部访问const或者static变量或者方法,那么就必须使用自引用的self,反之如果从类的内部访问不为const或者static变量或者方法,那么就必须使用自引用的$this。
例:staticfunction2.php
class MyStatic{ //创建一个MyStatic类
private static $i = 1;//私有 静态成员变量 $i为1
private function inc(){ //私有 成员函数 inc
self::$i = self::$i + 1; //自引用 自加 1+1
}
public static function add($x){//公有 静态成员函数 add 形参$x
//$this->i; //在静态方法中不能调用非静态的方法。
self::inc();//静态函数add调用非静态函数inc时,使用self::inc格式,如果使用$this->inc()的格式,将报错不能使用$this
echo self::$i + $x; //打印 2+$x
}
}
$st = new MyStatic();//创建实例
$st->add(2);//打印 2+2 =4
?>
结果:
若$this->i; 代替self::inc();
则结果:提示不能使用$this来调用
10.类中的常量
在PHP中使用const关键字表示常量,常量一般要写大写,如果常量有多个单词组成,使用下划线分开。常量的调用方式和静态变量相同,使用::符号调用。
例:const.php
class MyConst{ //创建 MyConst类
const PI = 3.14; //定义常量PI为3.14
private $result = 0; //私有 成员变量 $result 为0
public function area($r){ //公有 成员函数area 形参$r
$this->result = self::PI*$r*$r;//如果此处表达式写为PI*$r*$r,返回结果为0。调用常量使用self::PI的方式,self表示当前的类名
echo 'area: '.$this->result; //打印结果
}
}
$cst = new MyConst(); //实例化
$cst->area(2);//3.14*2*2=12.56
?>
结果:
常量只能被赋值一次,如果再给常量赋第二次的值将会出错。
例:const2.php
class MyConst{ //创建MyConst类
const I = 1; //定义常量I为1 定义常量时,不需要在常量名前加$,这是常量和变量的区别
}
echo 'I = '.MyConst::I; //打印 I=1
//MyConst::I = 2;
?>
结果:
加上MyConst::I = 2;就会报错。
请大家多多关注,感谢!本文只供学习使用,请勿其他用途!