php面向对象全攻略 (十) final static const关键字的使用


Posted in PHP onSeptember 30, 2009

14.final 关键字的应用
这个关键字只能用来定义类和定义方法,不能使用final 这个关键字来定义成员属性,因
为final 是常量的意思,我们在PHP 里定义常量使用的是define()函数,所以不能使用final 来
定义成员属性。
使用final 关键标记的类不能被继承;
代码片段
final class Person{
… …
}
class Student extends Person{
}
会出现下面错误:
Fatal error: Class Student may not inherit from final class (Person)
使用final 关键标记的方法不能被子类覆盖,是最终版本;
代码片段
class Person{
final function say() {
}
}
class Student extends Person{
function say() {
}
}
会出现下面错误:
Fatal error: Cannot override final method Person::say()
15.static 和const 关键字的使用
Static 关键字是在类中描述成员属性和成员方法是静态的;静态的成员好处在那里呢?
前面我们声明了“Person”的人类,在“Person”这个类里如果我们加上一个“人所属国家”
的属性,这样用“Person”这个类实例化出几百个或者更多个实例对象,每个对象里面就都
有“所属国家”的属性了,如果开发的项目就是为中国人而开发的,那么每个对象里面就都
有一个国家的属性是“中国”其它的属性是不同的,如果我们把“国家”的属性做成静态的
成员,这样国家的属性在内存中就只有一个,而让这几百个或更多的对象共用这一个属性,
static 成员能够限制外部的访问,因为static 的成员是属于类的,是不属于任何对象实例,是
在类第一次被加载的时候分配的空间,其他类是无法访问的,只对类的实例共享,能一定程
度对类该成员形成保护;
从内存的角度我们来分析一下,内存从逻辑上被分为四段,其中对象是放在“堆内存”里
面,对象的引用被放到了“栈内存”里,而静态成员则放到了“初始化静态段”,在类第一次
被加载的时候放入的,可以让堆内存里面的每个对象所共享,如下图;
php面向对象全攻略 (十) final static const关键字的使用 
类的静态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样
的,类似于全局函数。
代码片段

<? 
class Person{ 
//下面是人的静态成员属性 
public static $myCountry="中国"; 
// var $name; //人的名子 
//这是人的静态成员方法 
public static function say(){ 
echo "我是中国人<br>"; 
} 
} 
//输出静态属性 
echo Person::$myCountry; 
//访问静态方法 
Person::say(); 
//重新给静态属性赋值 
Person::$myCountry="美国"; 
echo Person::$myCountry; 
?>

因为静态成员是在类第一次加载的时候就创建的,所以在类的外部不需要对象而使用类
名就可以访问的到静态的成员;上面说过,静态成员被这个类的每个实例对象所共享,那么
我们使用对象可不可以访问类中的静态成员呢?从上图中我们可以看到,静态的成员不是在
每个对象内部存在的,但是每个对象都可以共享,所以我们如果使用对象访问成员的话就会
出现没有这个属性定义,使用对象访问不到静态成员的,在其它的面向对象的语言中,比如
Java 是可以使用对象的方式访问静态成员的,如果PHP 中可以使用对象访问静态成员的话,
我们也尽量不要去使用,因为静态的成员我们在做项目的时候目的就是使用类名去访问。
类里面的静态方法只能访问类的静态的属性,在类里面的静态方法是不能访问类的非静
态成员的,原因很简单,我们要想在本类的方法中访问本类的其它成员,我们需要使用$this
这个引用,而$this 这个引用指针是代表调用此方法的对象,我们说了静态的方法是不用对象
调用的,而是使用类名来访问,所以根本就没有对象存在,也就没有$this 这个引用了,没有
了$this 这个引用就不能访问类里面的非静态成员,又因为类里面的静态成员是可以不用对象
来访问的,所以类里面的静态方法只能访问类的静态的属性,即然$this 不存在,在静态方法
中访其它静态成员我们使用的是一个特殊的类“self”;self 和$this 相似,只不过self 是代表
这个静态方法所在的类。所以在静态方法里,可以使用这个方法所在的类的“类名”,也可以
使用“self”来访问其它静态成员,如果没有特殊情况的话,我们通常使用后者,即“self::成
员属性”的方式。
代码片段
<? 
class Person{ 
//下面是人的静态成员属性 
public static $myCountry="中国"; 
//这是人的静态成员方法, 通过self访问其它静态成员 
public static function say(){ 
echo "我是".self::$myCountry."<br>"; 
} 
} 
//访问静态方法 
Person::say(); 
?>

在非静态方法里可不可以访问静态成员呢,当然也是可以的了,但是也不能使用“$this”
引用也要使用类名或是“self::成员属性的形式”。
const 是一个定义常量的关键字,在PHP 中定义常量使用的是“define()”这个函数,但
是在类里面定义常量使用的是“const”这个关键字,类似于C 中的#define 如果在程序中改变
了它的值,那么会出现错误,用“const”修饰的成员属性的访问方式和“static”修饰的成员
访问的方式差不多,也是使用“类名”,在方法里面使用“self”关键字。但是不用使用“$”
符号,也不能使用对象来访问。
代码片段
<?php 
class MyClass{ 
//定义一个常量constant 
const constant = 'constant value'; 
function showConstant() { 
echo self::constant . "\n"; //使用self访问,不要加”$” 
} 
} 
echo MyClass::constant . "\n"; //使用类名来访问,也不加”$” 
$class = new MyClass(); 
$class->showConstant(); 
// echo $class::constant; 是不允许的
PHP 相关文章推荐
php通过文件头检测文件类型通用代码类(zip,rar等)
Oct 19 PHP
php数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系
Nov 02 PHP
单一index.php实现PHP任意层级文件夹遍历(Zjmainstay原创)
Jul 31 PHP
php调用Google translate_tts api实现代码
Aug 07 PHP
C/S和B/S两种架构区别与优缺点分析
Oct 23 PHP
Ubuntu中启用php的mail()函数并解决发送邮件速度慢问题
Mar 27 PHP
php获取网站百度快照日期的方法
Jul 29 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
Dec 14 PHP
微信接口生成带参数的二维码
Jul 31 PHP
CentOS7编译安装php7.1的教程详解
Apr 18 PHP
在laravel中使用with实现动态添加where条件
Oct 10 PHP
PHP解决高并发问题
Apr 01 PHP
php面向对象全攻略 (九)访问类型
Sep 30 #PHP
php面向对象全攻略 (八)重载新的方法
Sep 30 #PHP
php面向对象全攻略 (七) 继承性
Sep 30 #PHP
php面向对象全攻略 (六)__set() __get() __isset() __unset()的用法
Sep 30 #PHP
php面向对象全攻略 (五) 封装性
Sep 30 #PHP
php面向对象全攻略 (四)构造方法与析构方法
Sep 30 #PHP
php面向对象全攻略 (三)特殊的引用“$this”的使用
Sep 30 #PHP
You might like
PHP下操作Linux消息队列完成进程间通信的方法
2010/07/24 PHP
php数组声明、遍历、数组全局变量使用小结
2013/06/05 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
Yii调试SQL的常用方法
2014/07/09 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
JavaScript 事件冒泡简介及应用
2010/01/11 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
2011/04/08 Javascript
jQuery之日期选择器的深入解析
2013/06/19 Javascript
js渐变显示渐变消失示例代码
2013/08/01 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
Js获取数组最大和最小值示例代码
2013/10/29 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
2014/09/01 Javascript
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
2014/11/28 Javascript
javascript控制图片播放的实现代码
2020/07/29 Javascript
JS实现灵巧的下拉导航效果代码
2015/08/25 Javascript
JS实现的仿淘宝交易倒计时效果
2015/11/27 Javascript
AngularJS获取json数据的方法详解
2017/05/27 Javascript
js实现轮播图的完整代码
2020/10/26 Javascript
JavaScript Dom 绑定事件操作实例详解
2019/10/02 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
python和C语言混合编程实例
2014/06/04 Python
Python内置函数delattr的具体用法
2017/11/23 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
Python将一个CSV文件里的数据追加到另一个CSV文件的方法
2018/07/04 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
django写用户登录判定并跳转制定页面的实例
2019/08/21 Python
使用Rasterio读取栅格数据的实例讲解
2019/11/26 Python
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
通息工程毕业生自荐信
2013/10/16 职场文书
《记金华的双龙洞》教学反思
2014/04/19 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
画展观后感
2015/06/17 职场文书
使用HttpSessionListener监听器实战
2022/03/17 Java/Android
Python集合set()使用的方法详解
2022/03/18 Python
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
2022/05/25 SQL Server