PHP面向对象的程序设计关键字 原创
关键字
final
final不能修饰成员属性(类中声明常量不是用这个词,与JAVA不同)
final只能修饰类和方法
作用:
使用final修饰的类,不能被子类继承
使用final修饰的方法,不能被子类去覆盖
用来显示类不能被继承,方法不被覆盖就使用final
static
1.使用static可以修饰成员属性和成员方法,不能修饰类
2.用static修饰的成员属性,可以被同一个类的所有对象共享
3.静态的数据是存在 内存中的 数据段中(初始化静态段)
4.静态的数据时在类每一次加载时,分配到内存中的,以后用到类时就直接从数据段中获取
5.什么是类被加载?只要在程序中使用到这个类(有这个类名出现)
注意:静态的成员都是使用类名去访问,不用创建对象,不用对象去访问
类名::静态成员 类名::静态方法 self::静态成员/方法 parent::静态成员/方法
如果在类中使用静态成员,可以使用self 代表本类($this)
6.静态方法(static修饰的方法),不能访问非静态的成员(在非静态的方法中可以访问静态成员)
因为非静态的成员,就必须用对象来访问,访问内部的成员使用的就是$this
静态方法 不用使用对象来调用,也就是没有对象,$this也就不能代表什么对象,非静态的成员还必须使用对象
如果你确定一个方法不使用非静态的成员,则可以将这个方法声明为 静态方法(不能创建对象,直接使用类名就可以访问)
单态实例:使用static 静态成员属性和方法
//单态模式
//为了不能在外面 new 使用private封装构造方法 我们提供一个方法来使用被封装的构造方法
//我们没有对象,没法使用里面的提供的方法,我们想到了static
//将我们建立连接的方法用静态修饰,可以在没有对象的时候就调用
//有了方法,我们就可以做逻辑判断,判断谁? 静态方法里面只能有静态的东西,所以我们整了一个静态的属性
//我们判断这个属性是否为null ,如果为空 new 一个新对象,并返回,如果存在,直接返回
//保证了多次调用,只会 new 一次,也就是只会得到一个对象,可以使用 === 来验证
class DB{
public static $link = null;
private function __construct(){
echo '连接数据库<br>';
}
public static function getconnect(){
if(is_null(self::$link)){
self::$link = new DB;
return self::$link;
}else{
return self::$link;
}
}
}
//$db = new DB;
$db = DB::getconnect();
$mysql = DB::getconnect();
const
define 定义常量,可以使用表达式,不能写在类里面
const 定义常量,不能使用表达式,可以写在类里面
类里面常量的访问方式,和静态一致,使用范围操作符来访问 如: A::USER;
魔术方法
__call()
__callstatic()
__call
触发时机 调用一个不存在的方法的时候 两个参数 第一个是方法名 第二个是所有参数组成的数组
__callStatic
触发时机 调用一个不存在的静态方法的时候两个参数 第一个是方法名 第二个是所有参数组成的数组
//这个魔术方法也必须是静态的
在$obj->say()调用对象中不存在的方法时如果不是使用此魔术方法就会出现系统报错,然后程序退出。
__tostring()
触发时机 使用echo输出一个对象变量时候 没有参数 返回值必须是字符串
class A{
public function __toString(){
return '你个傻X,干啥直接echo对象呢?';
}
}
$a = new A;
echo $a;
__clone()
触发时机 在使用clone关键字克隆对象时触发__clone()进行克隆对象的成员初始化 没有参数
class B{
public $name;
private $age;
private $sex;
public function __construct($name = 'vilin',$age = 18,$sex = '男'){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
public function __clone(){
//里面如果不给属性赋值,默认克隆原对象所有属性
//如果给出部分属性值将覆盖原来的同名属性值,没有给出的属性继续克隆原属性。
/* $this->name = "小哥哥";
$this->age = 16;
$this->sex = '男孩'; */
$this->name = "new {$this->name}"; //'new'.$this->name
$this->age = $this->age+1;
}
public function say(){
echo "我的姓名是{$this->name},我的年龄是{$this->age}岁,我的性别是{$this->sex}<br>";
}
}
$b = new B('小南神');
$b->say();
//进行克隆工作了
$c = clone($b);
$c->say();
var_dump($c);
__autoload()
触发时机 在使用new 关键字实例化对象时 在找不到类时触发 一个参数类名
function __autoload($className){
echo '我好惨<br>';
echo $a;
include './model/'.$className.'.class.php';
}
//include './model/Model.php';
$user = new Model('user');
$userlist = $user->select();
echo "<pre>";
print_r($userlist);
echo "</pre>";
__sleep() 触发时机 无参数 在使用serialize 串行化(序列化)对象时触发,如果没有__sleep(),将序列化所有成员属性,如果有__sleep() 按照返回的数组值 进行属性序列化
__wake() 触发时机 无参数 在使用unserialize反串行化(反序列化)对象时触发,将进行反序列化初始化。
serialize()
unserialize()
__wakeup()
是在反序列化时自动调用的方法
使用unserialize反串行化字符串到对象时候 就会唤醒该该类中的该魔术方法
也是对象重新诞生的一个过程(__construct(), __clone(),__wakeup())
对象串行化(序列化): 将一个对象转为二进制串 (对象是存储在内存)
1. 将对象长时间存储在数据库或文件中时
2. 将对象在多个PHP文件中传输时
子主题 1class B{
public $name;
public $age = 18;
private $sex = 1;
public function __sleep(){
return array('name','sex');
}
public function __wakeup(){
echo '我睡醒了<br>';
}
}
$b = new B;
$b->name = '娘娘';
$b->age = 28;
//var_dump($b);
$str = serialize($b);
//echo $str;
$obj = unserialize($str);
var_dump($obj);
__autoload 实例:
//开启session
session_start();
//设置页面以utf-8编码格式显示
header('content-type:text/html;charset=utf-8');
//开始所有错误提示除了notice级别的错误
error_reporting(E_ALL & ~E_NOTICE);
//包含通用的全局配置文件
//require('config.inc.php');
//设置中国所在的東八区时间
date_default_timezone_set('PRC');
//设置自动加载的类配置文件
function __autoload($className){
if(substr($className,-6))=="Action"){
include(APP_CLASS_PATH.'Action/'.$className.".class.php");
}elseif(substr($className,-5) == "Model"){
include(APP_CLASS_PATH.'Model/'.$className.".class.php");
}elseif($className == "Smarty"){
include CMS_ROOT."Smarty/Smarty.class.php";
}else{
include(APP_CLASS_PATH.'Public/'.$className.".class.php");
}
}