示例代码(先看个大概)
<?php
class Person{
const MAX_AGE = 130; // 类常量:假设人的最长年龄为130
var $name; // 普通属性:姓名
public $age; // 普通属性:年龄,public和var是一样的
static $resource = 100; // 静态属性:人类某种共同的资源,假设总量为100
// 构造方法
function __construct($name,$age){
$this->name = $name;
$this->age = $age;
}
// 普通(实例)方法
function say(){
echo $this->name."说了一句话!<br />";
}
// 静态方法
static function useResource(){
self::$resource--;
echo "资源被使用,现在的资源容量为:".self::$resource."<br />";
}
// 析构方法
function __destruct(){
echo $this->name."死了!<br />";
}
}
// 访问类常量
echo "人类的最长寿命为:".Person::MAX_AGE."<br />";
// 创建对象,这里系统会调用构造方法
$person = new Person("张三",100);
// 调用普通方法,这里张三说了一句话
$person->say();
// 访问普通属性,张三的年龄
echo "张三的年龄:".$person->age."<br />";
// 调用静态方法
Person::useResource();
// 访问静态属性
echo "现在资源的容量:".Person::$resource."<br />";
?>
面向对象
概念(先有类才能有对象)
- 类:描述一类事物的一个总称,是具有相同特性的该类事物的一个通用名称(chenghu!),如人类,教师,动物,狗…;
- 对象:万物皆对象!,如张三(人类这个类的实物)。
类
定义形式:
class 类名{ 常量定义 ... 属性定义 ... 方法定义 ... }
创建一个对象的四种形式:
形式1:
$person1 = new Person();
形式2:
$person2 = new Person();
形式3(可变类):
$str = "Person"; // 只是一个字符串变量而已 $person3 = new $s(); // 这就是所谓的“可变类”--无非就是类的名字是一个变量而已(这个变量的值就是某个类的名字字符串)
形式4(局限):
$person = new self(); // self表示“当前类本身”,它只能出现在一个类的方法中。
类中成员:
- 类常量
- 属性:
- 普通属性
- 静态属性
- 方法:
- 普通方法
- 静态方法
- 构造方法
- 析构方法
类常量:
当在一个类种定义一个常量时,该常量就称为“类常量”–本质其实还是常量。
定义形式:
class 类名{ const 常量名 = 常量值; // 类常量只能通过const定义,不能和普通常量一样通过define定义且定义的同时必须赋值 }
使用类常量:(通过类名或$对象名+范围解析符(::)来使用类常量)
- 形式1: 类名::类常量名 如:
Constants::PI;
形式2:$对象名::类常量名 如:
$constants::PI
举例:
class Constants{ const PI = 3.14; } echo "PI = ".constants::PI; $constants = new Constants(); echo "PI = ".$constants::PI;
- 形式1: 类名::类常量名 如:
属性
普通属性(实例属性):
实例(instance)属性,就是一个在该类实例化出的对象上使用的属性(属于每一对象(实例))。
定义形式:
class 类名{ var $属性名 = 初始值; // 赋初始值 var $属性名; // 也可以不赋初始值 // 上述的var也可以用public来代替,如 public $属性名 = 初始值; // 赋初始值 public $属性名; // 也可以不赋初始值, }
使用形式:
对象名−>属性名;//注意没有 符号,如
$person->name
静态属性:
本质上也是“变量”,但其有一个特点就是,该变量属于“类”,而不只属于某个“对象”(实例),即多个实例共享这个属性,相比普通(实例属性),实例属性属于每个对象,即每个对象具有它自己的实例属性。
定义形式:
class 类名{ static $属性名 = 初始值; static $属性名; // 也可以不赋初始值 }
使用形式:(区别于类常量的使用又区别于普通属性)
使用类名或$对象名+范围解析符:
- 类名::$静态属性名; // 注意有$符,如:
Person::$resource
对象名:: 静态属性名; // 注意有$符,如
$person::$resource
对比1:区别类常量的使用:
类名::类常量名; $对象名::类常量名;
对比2:区别实例属性的使用:
对象名->实例属性名;
- 类名::$静态属性名; // 注意有$符,如:
方法
普通(实例)方法:
隶属于每个对象的方法,为每个对象(实例)所独有,不共享
定义形式:
class 类名{ function 方法名(形参列表){ // 方法体 } }
调用形式:
- 形式1:$对象名->方法名(对应实参列表);
- 形式2(局限):$this->方法名(对应实参列表); // 需要在类内部使用
静态方法:
一个类种定义的方法,只隶属于这个类本身,而不隶属于这个类的对象,即为对象(实例)所共享;
定义形式:
class 类名{ static function 方法名(形参列表){ // 方法体 } }
调用形式:
形式1:类名::方法名(对应实参列表);
形式2:$对象名::方法名(对应实参列表);
形式3(局限):self::方法名(对应实参列表); // 需要在类内部使用
构造方法(
__construct
)- 名字是国定的:
__construct
; - 该方法通常不需要自己调用,由new这个关键字调用(创建对象)
- 该方法主要的目的是为了在new 一个对象的时候,给该对象设置一些“初始值”(初始化工作)
- 该方法的参数没有规定,通常是根据实际的需要来定义,目的是为了在初始化对象的时候传入一些值该这个对象。
- 名字是国定的:
析构方法(
__destruct
)- 名字是国定的:
__destruct
; - 该方法是在一个对象被“销毁”的时候会自动被调用的方法–我们无法调用它
- 该方法不嫩带参数,但$this(当前这个实例)还可以在这里使用
- 名字是国定的:
对象的销毁:
- 程序运行结束后,所有变量都会被销毁,自然,变量所代表的对象也会被销毁;
- 当一个对象没有任何变量指向它的时候,该对象也会被销毁(即时程序没有结束,这很容易理解,因为语言内部垃圾回收机制)。
对象的值传递和引用传递:
对象变量的值传递和引用传递对于对象数据的改变都是一样的,这是因为对象变量实际上存的是对象编号,通过该对象编号就可以操作这个对象的数据,值传递直接将存储的对象编号赋值给另外一个变量,而引用传递是复制了这个变量指向对象编号的引用。
举例代码:
$v1 = new Person('李四',80);
$v2 = $v1; // 值传递,其实传递的是$v1对这个对象的对象编号,该变量通过这种对象编号操作这个对象
$v3 = & $v1; // 引用传递
原理图示:
ps:
- 可以通过unset()断开变量与对象之间的引用,此时这个变量被销毁;
- 也可以通过将指向该对象的变量赋其他值,即断开了上面的前面一条线,这时,该变量将不再指向该对象了。
初谈php与java面向对象:
相同点
- 定义类用class关键字;
- 创建类用new关键字(java还可以通过反射);
- 都是可以通过类名方法静态属性和方法。
不同点:
- 常量的定义形式不同,java用
final
关键字,且可以用static
修饰成静态的。而php常量用const
修饰,默认就是静态的,不能用static
修饰; - 构造方法形式不同,java以类名为构造方法名,php每个类的构造方法名固定都是
__construt
; - php有析构方法,而java没有,php析构方法类似对象的一个生命周期方法(原谅我学
JavaWeb
和Android
惯了); - 调用方法形式不同,java调用方法都是通过
.
(除了构造方法),而php调用普通方法用->
,调用静态方法通过::
。
- 常量的定义形式不同,java用