【一】目标
1.类声明语法------试声明student类,有score属性和study方法
2.权限封装---------知道public、protected、private各自的可见范围
3.继承---------------写A类,再写B类继承自A类,且要重写A类中的某个方法
4.静态属性与静态方法-----知道static静态方法需要用类名..方法名0调用
5.魔术方法--------了解常用魔术方法分别在什么时间被调用
6.写一个抽象类,并用2个子类分别继承实现分析这2个子类有什么共同特点?
7.写一个接口,并用2个类分别继承实现分析这2个类有什么共同点?
基本语法:声明,权限,继承,静态属性和方法,魔术方法,抽象类,接口
【二】基础
<?php //对象的声明,将函数放到对象里 class oneclass{
//方法 function one(){ echo "666"; } } //实例化对象 $class = new oneclass(); // 函数调用 $class -> one(); ?>
(1)属性和方法
将变量赋值放到类中,便成为了属性;将函数放到类里,便成了方法
属性和方法的调用:
<?php //放到对象里 class oneclass{ public $name = ‘我是属性‘; function one(){echo "我是方法";} } //实例化对象 $class = new oneclass(); // 方法调用 $class -> one(); //属性调用 echo $class->name;//调用属性时可以不加$ ?>
注意:方法和属性加到类里时前面要加入权限声明,否则默认public
(2)类的声明
语法:class 类名{...}
注意:类名不区分大小写,但是Linux下区分,所以要保持一致。且命名采用驼峰法,一般首字母大写
<?php //类的声明 class person{ //属性声明 public $name = ‘wang‘; //方法声明 public function man(){ echo "1111"; } } //调用类的话,要先new一个对象,且实例化时不区分大小写,但在Linux下严格区分大小写,所以要避免不一致的情况。命名时用驼峰法 $person = new PERSON(); $person -> man(); echo $person->name; ?>
(3)属性赋值的变化
属性不能赋值表达式?
5.6版本开始支持表达式,例如public $rand = 1+1;
(4)类与对象关系
类是同类事物共同特点的抽象描述;而对象是以类作为模板,形成的具体实例
所以当new + 类名时,便成为new一个对象,即实例化对象
<?php //类的声明 class person{ //属性声明 public $name = ‘tony‘; //方法声明 public function man(){ echo "1111"; } } //实例化一个对象,赋值给变量 //new类名时,内存便会产生一个对象,开辟新空间存放属性和方法名 $person = new PERSON(); $person1 = new PERSON(); echo $person->name; $person1 ->name = ‘tony1‘; echo $person1->name; ?>
注意:
①这里改变的属性值不是类里的属性值,而是开辟出的新空间的值;
②开辟的新空间只存放属性和属性值,至于方法只存放方法名,不存放函数
(5)this
$this是伪变量,谁实例化对象就是谁。简单理解谁调用就是谁
<?php class Person{ public $name = ‘tony‘; public $goods = ‘dogs‘; public function buy(){ echo "拍电影吧".$this->name; } } $person = new Person();
//调用new出来的对象中的方法,所以this指的是new出来的对象。而不是类本身 $person -> buy(); ?>
(6)封装MySQL类
注意:原生MySQL的api自5.0版本开始逐渐废弃,在将来预计会完全移除。虽然有向下兼容特效,但开发中还是推荐使用mysqli
用封装MySQL连接数据库
<meta charset="utf-8"> <?php class Mysql{ public $link; //连接数据库 public function coon(){ $cfg = array( ‘host‘ => ‘localhost‘, ‘user‘ => ‘root‘, ‘password‘ => ‘root‘, ‘db‘ => ‘user‘, ‘charset‘ => ‘utf8‘ ); //连接数据库(地址,用户,密码,选库) $this ->link = mysqli_connect($cfg[‘host‘],$cfg[‘user‘],$cfg[‘password‘],$cfg[‘db‘]); if(!$this ->link){ die("连接失败:".mysqli_error()); }else{ echo "连接成功"; } } //发送查询 public function query($sql){ return mysqli_query($this->link,$sql); } //查询获取所有数据,返回数据 public function getAll($sql){ $array = array(); $res = $this ->query($sql); // mysqli_fetch_assoc($res);//数组 while ($row = mysqli_fetch_assoc($res)) {//遍历数组 $data[] = $row; } return $data; } } $sql = new Mysql(); $sql -> coon(); var_dump($sql->getAll(‘select* from user‘)); ?>
注意:每连接一次(刷新页面),便会增加一次连接数Connection id
(7)构造方法和析构方法----------(简单即为构造和销毁construct和destruct)
①构造方法(construct构造)
与面向对象调用方式不同,构造方法的类,一旦被实例化,就会被调用
②析构方法(destruct销毁)
同样也是实例化后便被调用
③构造方法传参:直接在调用时传入即可
注意:析构方法对象销毁时被调用
<?php class Human{ public function __construct(){ echo "构造方法"; }
public function __destruct(){
echo"析构方法";
} } new Human();//调用执行 ?>
构造函数与析构函数调换位置后输出顺序依然不变,因为实例化对象时会先执行构造函数
案例:
<?php class Human{ public function __destruct(){ echo "调用2<br>"; } public function one(){ echo "调用One函数<br>"; } public function __construct(){ echo "调用1<br>"; } } $a = new Human(); $a -> one(); ?>
输出顺序:1,one,2
③析构函数销毁时间:变量赋其他值;被人工销毁unset();页面结束
④构造方法的旧式声明:一个和类名同名的方法,被理解为构造方法。老旧的PHP代码会遇到,遇到时认识即可(可以传参)
<?php class Human{ //方法名和类名一致时会被理解为构造方法 public function Human($a){ echo "调用"; } } $a = new Human(‘形参‘); ?>
(8)类的封装性
封装性:类中的某些方法或属性不允许外部调用
可以通过开放部分接口来间接调用,写个简单例子
<?php class Human{ //方法名和类名一致时会被理解为构造方法 public function aa(){ echo "调用1"; } public function __construct(){//通过调用构造函数来间接调用方法aa() $this -> aa();//我是内部调用 } } $a = new Human();//我是外部调用 ?>
类似于ATM机,只能输入密码,而不能查询。因为这里只开放了输入对比的接口
不封装的缺点:可以在外部调用获取内部函数或变量,安全性差
<?php class Atm{ //返回数据库存储的密码 public function getPwd(){ return ‘123456‘; } //对比密码 public function checkPwd($pwd){ return $this -> getPwd() == $pwd; } } $atm = new Atm(); //不封装时在外部会可以调用到内部函数,获取密码 echo ‘存储密码为‘.$atm->getPwd()."<br>"; if($atm -> checkPwd(‘123456‘)){ echo "密码输入正确"; }else{ echo "密码输入错误"; } ?>
为了封装函数,保护重要数据。将返回数据库存储密码的行的权限改为protected(保护),则该函数便被封装了起来
通过调用公共接口即可间接调用方法
//返回数据库存储的密码 protected function getPwd(){ return ‘123456‘; }
(9)类的继承
语法:extends继承、扩展
class ParClass{} class SubClass extends ParClass{}
接下来,首先看个问题
<?php include ‘footer.php‘;//不存在会继续终止 require ‘header.php‘;//不存在会终止执行 function check(){...} ?>
引入的文件里可能会有函数名与check相同,导致运行出现问题
详解:结合下面代码进行解析
继承的好处:
①子类可以继承父类的方法和属性,例如底下案例里通过实例化调用子类来调用继承自父类的函数method;
②允许覆盖和修改父类的方法属性或新增方法,例如check函数的覆盖重新;
案例:
<?php class one{ function check(){ echo "检查1"; } function method(){ echo "方法1"; } } //two相对于one 来说是子类,此时one类里的方法可用,比如通过子类two调用父类的method方法 class two extends one{ function check(){ echo "检查2"; } } $three = new two(); $three -> check();//这里会输出“检查2”,因为two对one进行了继承修改 $three -> method();//通过子类two调用父类的method方法 ?>