PHP面向对象编程
创建类
语法:
class 类名{
//属性
//方法
//常量
}
类名的命名规则:
- 以字母、下划线开头、后面跟的是字母、数字、下划线
- 不能用PHP关键字做类名
- 类名不区分大小写(变量名区分,关键字、类名不区分大小写)
- 类名用帕斯卡命名法(大驼峰 单词的首字母大写)
对象的实例化
- 创建对象的过程称为实例化
- 通过new关键字实例化对象
<?php
class Student{
}
$stu1=new Student;
$stu2=new Student;
var_dump($stu1);echo'<br>';
var_dump($stu2);
属性
通过"->"调用对象的成员(属性和方法)
<?php
class Student{
public $name; //公有的属性
public $age; //属性
}
//实例化对象
$stu=new Student;
//1.给属性赋值
$stu->name='tom'; //将tom'赋给name属性
$stu->age=20;
var_dump($stu);echo'<hr>';
//2.取值
echo '姓名:',$stu->name,'<br>';
echo'年龄:',$stu->age,'<br>';
//3.给对象添加属性
$stu->add='北京';
var_dump($stu);echo'<hr>';
//4.销毁对象的属性
unset($stu->age);
var_dump($stu);
方法
方法的本质就是函数
<?php
//定义类
class Student {
//定义方法
public function show(){
echo '我是一名学生<br>';
}
}
//实例化对象
$stu=new Student();
//调用方法
$stu->show(); //输出:我是一名学生
对象的传递
对象的传递是地址传递
<?php
class Student{
public $name='tom'; //属性默认值
}
$stu=new Student;
echo $stu->name,'<br>'; //tom
//对象默认地址传递
function setInfo($stu){
$stu->name='berry';
}
setInfo($stu); //将$stu的地址传递给函数
echo $stu->name,'<br>'; //berry
访问修饰符
用来控制成员的访问权限
修饰符 | 描述 |
---|---|
public(公有的) | 在类的内部和外部都可以访问 |
private(私有的) | 只能在类的内部访问 |
protected(受保护的) | 在整个继承链上访问 |
$this
- $this表示调用当前方法的对象
- $this保存的对象的地址
<?php
class Student{
private $name; //私有的姓名
private $age; //私有的年龄
//公有的方法赋值
public function setInfo($name,$age){
//验证数据
if($name==''){
die('姓名不能为空');
}
if($age<10 || $age>30) {
die('年龄必须在10~30之间');
}
//给属性赋值
$this->name=$name; //$this表示调用所在方法的对象
$this->age=$age;
}
//公有的方法取值
public function getInfo() {
echo '姓名:',$this->name,'<br>'; //姓名:tom
echo '年龄:',$this->age,'<br>'; //年龄:20
}
}
$stu=new Student; //$stu保存的是对象的地址,将new Student()的对象地址付给$stu
$stu->setInfo('tom',20);
$stu->getInfo();
类和对象在内存中的分布
- 对象的本质是一个复杂的变量
- 类的本质是一个自定义的复杂数据类型
- 栈区:运行速度快,体积小,保存基本类型
- 堆区:运行速度稍慢,体积小,保存基本类型
- 实例化的过程就是分配内存空间的过程
- 对象保存在堆区,将堆区的地址保存到栈区
封装
- 封装就是有选择性的提供数据
- 通过访问修饰符来实现封装
构造方法
- 也叫构造函数,但对象创建的时候自动调用
- 构造函数的作用:初始化成员
- 构造函数中不可以使用return
语法
function __construct(){
}
//注意:两个下划线
构造函数初始化成员
<?php
class Student {
private $name;
private $sex;
private $age;
//构造函数初始化成员
public function __construct($name,$sex,$age) {
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//显示学生信息
public function getInfo() {
echo '姓名:',$this->name,'<br>';
echo '性别:',$this->sex,'<br>';
echo '年龄:',$this->age,'<hr>';
}
}
//实例化
$stu1=new Student('tom','男',22);
$stu1->getInfo();
$stu2=new Student('berry','女',20);
$stu2->getInfo();
析构函数
- 当对象销毁的时候自动调用的函数
- 析构函数中不能带参数
语法
public function __destruct(){
}
//注意:两个下划线
<?php
class Student{
public function __destruct(){
echo '销毁';
}
}
$stu=new Student; //页面执行完毕会销毁对象
继承
- 继承使代码具有层次结构
- 实现了代码的可重用性
- 使用extends关键字实现继承
- 父类和子类是想对的
语法:
class 子类 extends 父类{
}
继承实现
<?php
//父类
class Person {
public $name='tom';
public function show() {
echo '这是人类<br>';
}
}
//子类
class Student extends Person {
}
//测试
$stu=new Student;
echo $stu->name,'<br>'; //tom
$stu->show(); //这是人类
继承的执行过程:$stu->show(),首先先到Student类中寻找show(),如果找到就执行;如果找不到就到父类中寻找。
在子类中调用父类的普通方法
<?php
class Person {
public function show() {
echo 'i am a Person<br>';
}
}
class Student extends Person {
//调用父类的普通方法:方法一
public function test1() {
$per=new Person(); //实例化父类
$per->show();
}
//方法二:
public function test2() {
$per=new parent(); //parent表示父类的名字
$per->show();
}
//方法三:
public function test3() {
$this->show(); //通过$this调用父类的普通方法
}
}
//测试
$stu=new Student;
$stu->test1(); //i am a Person
$stu->test2(); //i am a Person
$stu->test3(); //i am a Person
调用父类的构造方法
规则:如果子类有构造函数就调用子类的,如果子类没有就调用父类的。子类的构造函数执行了,父类的构造函数就不执行了。
应用
<?php
class Person{
protected $name; //受保护的
protected $sex;
public function __construct($name,$sex){
$this->name=$name;
$this->sex=$sex;
}
}
class Student extends Person{
private $score;
public function __construct($name,$sex,$age){
parent::__construct($name,$sex); //调用父亲的构造函数
$this->age=$age;
}
}
//测试
$stu=new Student('tom','男',20);
var_dump($stu);
protected修饰符
protected修饰的成员在整个继承链上访问
<?php
class A {
public function getNum() {
echo $this->num;
}
}
class B extends A {
protected $num=10; //在整个继承链上访问
}
//测试
$obj=new B();
echo $obj->getNum(); //10