当前位置: 编程技术>php
本页文章导读:
▪php面向对象全攻略 (十二) 抽象方法和抽象类
抽象方法和抽象类 在OOP 语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为 外部代码访问其的接口。而抽象方法就是为了方便继承而引入的,我们先来看一下抽象.........
▪php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误
16.__toString()方法 我们前面说过在类里面声明“— ”开始的方法名的方法(PHP 给我们提供的),都是在 某一时刻不同情况下自动调用执行的方法,“__toString()”方法也是一样自动被调用的,.........
▪php面向对象全攻略 (十) final static const关键字的使用
14.final 关键字的应用 这个关键字只能用来定义类和定义方法,不能使用final 这个关键字来定义成员属性,因 为final 是常量的意思,我们在PHP 里定义常量使用的是define()函数,所以不能使用f.........
[1]php面向对象全攻略 (十二) 抽象方法和抽象类
来源: 互联网 发布时间: 2013-11-30
抽象方法和抽象类
在OOP 语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为
外部代码访问其的接口。而抽象方法就是为了方便继承而引入的,我们先来看一下抽象类和
抽象方法的定义再说明它的用途。
什么是抽象方法?我们在类里面定义的没有方法体的方法就是抽象方法,所谓的没有方
法体指的是,在方法声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后
加上分号结束,另外在声明抽象方法时还要加一个关键字“abstract”来修饰;
例如:
abstract function fun1();
abstract function fun2();
上例是就是“abstract”修饰的没有方法体的抽象方法“fun1()”和“fun2()”,不要忘记
抽象方法后面还要有一个分号;那么什么是抽象类呢?只要一个类里面有一个方法是抽象方
法,那么这个类就要定义为抽象类,抽象类也要使用“abstract”关键字来修饰;在抽象类里
面可以有不是抽象的方法和成员属性,但只要有一个方法是抽象的方法,这个类就必须声明
为抽象类,使用“abstract”来修饰。
例如:
代码片段
abstract class Demo{
var $test;
abstract function fun1();
abstract function fun2();
function fun3(){
… .
}
}
上例中定义了一个抽象类“Demo”使用了“abstract”来修饰,在这个类里面定义了一
个成员属性“$test”,和两个抽象方法“fun1”和“fun2”还有一个非抽象的方法fun3();那
么抽象类我们怎么使用呢?最重要的一点就是抽象类不能产生实例对象,所以也不能直接使
用,前面我们多次提到过类不能直接使用,我们使用的是通过类实例化出来的对象,那么抽
象类不能产生实例对象我们声明抽象类有什么用呢?我们是将抽象方法是做为子类重载的模
板使用的,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守,子类继函抽象
类之后,把抽象类里面的抽象方法按照子类的需要实现。子类必须把父类中的抽象方法全部
都实现,否则子类中还存在抽象方法,那么子类还是抽象类,还是不能实例化对;为什么我
们非要从抽象类中继承呢?因为有的时候我们要实现一些功能就必须从抽象类中继承,否则
这些功能你就实现不了,如果继承了抽象类,就要实现类其中的抽象方法;
代码片段
<?
abstract class Demo{
var $test;
abstract function fun1();
abstract function fun2();
function fun3(){
… .
}
}
$demo=new Demo(); //抽象类为能产生实例对象,所以这样做是错的,实例化对象交给子类
class Test extends Demo{
function fun1(){
…
}
function fun2(){
…
}
}
$test=new Test(); //子类可以实例化对象,因为实现了父类中所有抽象方法
?>
在OOP 语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为
外部代码访问其的接口。而抽象方法就是为了方便继承而引入的,我们先来看一下抽象类和
抽象方法的定义再说明它的用途。
什么是抽象方法?我们在类里面定义的没有方法体的方法就是抽象方法,所谓的没有方
法体指的是,在方法声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后
加上分号结束,另外在声明抽象方法时还要加一个关键字“abstract”来修饰;
例如:
abstract function fun1();
abstract function fun2();
上例是就是“abstract”修饰的没有方法体的抽象方法“fun1()”和“fun2()”,不要忘记
抽象方法后面还要有一个分号;那么什么是抽象类呢?只要一个类里面有一个方法是抽象方
法,那么这个类就要定义为抽象类,抽象类也要使用“abstract”关键字来修饰;在抽象类里
面可以有不是抽象的方法和成员属性,但只要有一个方法是抽象的方法,这个类就必须声明
为抽象类,使用“abstract”来修饰。
例如:
代码片段
代码如下:
abstract class Demo{
var $test;
abstract function fun1();
abstract function fun2();
function fun3(){
… .
}
}
上例中定义了一个抽象类“Demo”使用了“abstract”来修饰,在这个类里面定义了一
个成员属性“$test”,和两个抽象方法“fun1”和“fun2”还有一个非抽象的方法fun3();那
么抽象类我们怎么使用呢?最重要的一点就是抽象类不能产生实例对象,所以也不能直接使
用,前面我们多次提到过类不能直接使用,我们使用的是通过类实例化出来的对象,那么抽
象类不能产生实例对象我们声明抽象类有什么用呢?我们是将抽象方法是做为子类重载的模
板使用的,定义抽象类就相当于定义了一种规范,这种规范要求子类去遵守,子类继函抽象
类之后,把抽象类里面的抽象方法按照子类的需要实现。子类必须把父类中的抽象方法全部
都实现,否则子类中还存在抽象方法,那么子类还是抽象类,还是不能实例化对;为什么我
们非要从抽象类中继承呢?因为有的时候我们要实现一些功能就必须从抽象类中继承,否则
这些功能你就实现不了,如果继承了抽象类,就要实现类其中的抽象方法;
代码片段
代码如下:
<?
abstract class Demo{
var $test;
abstract function fun1();
abstract function fun2();
function fun3(){
… .
}
}
$demo=new Demo(); //抽象类为能产生实例对象,所以这样做是错的,实例化对象交给子类
class Test extends Demo{
function fun1(){
…
}
function fun2(){
…
}
}
$test=new Test(); //子类可以实例化对象,因为实现了父类中所有抽象方法
?>
[2]php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误
来源: 互联网 发布时间: 2013-11-30
16.__toString()方法
我们前面说过在类里面声明“— ”开始的方法名的方法(PHP 给我们提供的),都是在
某一时刻不同情况下自动调用执行的方法,“__toString()”方法也是一样自动被调用的,是在
直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,比如说:“$p=new
Person()”中,$p 就是一个引用,我们不能使用echo 直接输出$p,这样会输出“Catchable fatal
error: Object of class Person could not be converted to string”这样的错误,如果你在类里面定义
了“__toString()”方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用了
“__toString()”方法,输出“__toString()”方法中返回的字符,所以“__toString()”方法一定
要有个返回值(return 语句)。
代码片段
<?php
// Declare a simple class
class TestClass{
public $foo;
public function __construct($foo) {
$this->foo = $foo;
}
//定义一个__toString方法,返加一个成员属性$foo
public function __toString() {
return $this->foo;
}
}
$class = new TestClass('Hello');
//直接输出对象
echo $class;
?>
上例输出:Hello
17.克隆对象
有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”
关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要
根据一个对象完全克隆出一个一模一样的对象,是非常有必要的,而且克隆以后,两个对象
互不干扰。
在PHP5 中我们使用“clone”这个关键字克隆对象;
代码片段
<?
class Person{
//下面是人的成员属性
var $name; //人的名子
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
function __construct($name="", $sex="", $age=""){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say() {
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
}
$p1=new Person("张三", "男", 20);
//使用“clone”克隆新对象p2,和p1对象具有相同的属性和方法。
$p2=clone $p1;
$p2->say();
?>
PHP5 定义了一个特殊的方法名“__clone()”方法,是在对象克隆时自动调用的方法,
用“__clone()”方法将建立一个与原对象拥有相同属性和方法的对象,如果想在克隆后改变
原对象的内容,需要在__clone()中重写原本的属性和方法,“__clone()”方法可以没有参数,
它自动包含$this 和$that 两个指针,$this 指向复本,而$that 指向原本;
代码片段
class Person{
//下面是人的成员属性
var $name; //人的名子
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
function __construct($name="", $sex="", $age=""){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say() {
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
//对象克隆时自动调用的方法, 如果想在克隆后改变原对象的内容,需要在__clone()中重写原本
的属性和方法
function __clone(){
//$this指的复本p2, 而$that是指向原本p1,这样就在本方法里,改变了复本的属性。
$this->name="我是假的$that->name";
$this->age=30;
}
}
$p1=new Person("张三", "男", 20);
$p2=clone $p1;
$p1->say();
$p2->say();
?>
上例输出:
执行结果
我的名子叫:张三性别:男我的年龄是:20
我的名子叫:我是假的张三性别:男我的年龄是:30
18.__call 处理调用错误
在程序开发中,如果在使用对象调用对象内部方法时候,调用的这个方法不存在那么程
序就会出错,然后程序退出不能继续执行。那么可不可以在程序调用对象内部不存在的方法
时,提示我们调用的方法及使用的参数不存在,但程序还可以继续执行,这个时候我们就要
使用在调用不存在的方法时自动调用的方法“__call()”。
代码片段
<?php
//这是一个测试的类,里面没有属性和方法
class Test{
}
//产生一个Test类的对象
$test=new Test();
//调用对象里不存在的方法
$test->demo("one", "two", "three");
//程序不会执行到这里
echo "this is a test<br>";
?>
上例出现如下错误,程序通出不能继续执行;
Fatal error: Call to undefined method Test::demo()
下面我们加上“__call()”方法,这个方法有2 个参数,第一个参数为调用不存在的方法
过程中,自动调用__call()方法时,把这个不存在的方法的方法名传给第一个参数,第二个参
数则是把这个方法的多个参数以数组的形式传进来。
代码片段
<?php
//这是一个测试的类,里面没有属性和方法
class Test{
//调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数
function __call($function_name, $args){
print "你所调用的函数:$function_name(参数:";
print_r($args);
print ")不存在!<br>\n";
}
}
//产生一个Test类的对象
$test=new Test();
//调用对象里不存在的方法
$test->demo("one", "two", "three");
//程序不会退出可以执行到这里
echo "this is a test<br>";
?>
上例输出结果为:
执行结果
你所调用的函数: demo(参数:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test.
我们前面说过在类里面声明“— ”开始的方法名的方法(PHP 给我们提供的),都是在
某一时刻不同情况下自动调用执行的方法,“__toString()”方法也是一样自动被调用的,是在
直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,比如说:“$p=new
Person()”中,$p 就是一个引用,我们不能使用echo 直接输出$p,这样会输出“Catchable fatal
error: Object of class Person could not be converted to string”这样的错误,如果你在类里面定义
了“__toString()”方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用了
“__toString()”方法,输出“__toString()”方法中返回的字符,所以“__toString()”方法一定
要有个返回值(return 语句)。
代码片段
代码如下:
<?php
// Declare a simple class
class TestClass{
public $foo;
public function __construct($foo) {
$this->foo = $foo;
}
//定义一个__toString方法,返加一个成员属性$foo
public function __toString() {
return $this->foo;
}
}
$class = new TestClass('Hello');
//直接输出对象
echo $class;
?>
上例输出:Hello
17.克隆对象
有的时候我们需要在一个项目里面,使用两个或多个一样的对象,如果你使用“new”
关键字重新创建对象的话,再赋值上相同的属性,这样做比较烦琐而且也容易出错,所以要
根据一个对象完全克隆出一个一模一样的对象,是非常有必要的,而且克隆以后,两个对象
互不干扰。
在PHP5 中我们使用“clone”这个关键字克隆对象;
代码片段
代码如下:
<?
class Person{
//下面是人的成员属性
var $name; //人的名子
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
function __construct($name="", $sex="", $age=""){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say() {
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
}
$p1=new Person("张三", "男", 20);
//使用“clone”克隆新对象p2,和p1对象具有相同的属性和方法。
$p2=clone $p1;
$p2->say();
?>
PHP5 定义了一个特殊的方法名“__clone()”方法,是在对象克隆时自动调用的方法,
用“__clone()”方法将建立一个与原对象拥有相同属性和方法的对象,如果想在克隆后改变
原对象的内容,需要在__clone()中重写原本的属性和方法,“__clone()”方法可以没有参数,
它自动包含$this 和$that 两个指针,$this 指向复本,而$that 指向原本;
代码片段
代码如下:
class Person{
//下面是人的成员属性
var $name; //人的名子
var $sex; //人的性别
var $age; //人的年龄
//定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
function __construct($name="", $sex="", $age=""){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
//这个人可以说话的方法, 说出自己的属性
function say() {
echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
}
//对象克隆时自动调用的方法, 如果想在克隆后改变原对象的内容,需要在__clone()中重写原本
的属性和方法
function __clone(){
//$this指的复本p2, 而$that是指向原本p1,这样就在本方法里,改变了复本的属性。
$this->name="我是假的$that->name";
$this->age=30;
}
}
$p1=new Person("张三", "男", 20);
$p2=clone $p1;
$p1->say();
$p2->say();
?>
上例输出:
执行结果
我的名子叫:张三性别:男我的年龄是:20
我的名子叫:我是假的张三性别:男我的年龄是:30
18.__call 处理调用错误
在程序开发中,如果在使用对象调用对象内部方法时候,调用的这个方法不存在那么程
序就会出错,然后程序退出不能继续执行。那么可不可以在程序调用对象内部不存在的方法
时,提示我们调用的方法及使用的参数不存在,但程序还可以继续执行,这个时候我们就要
使用在调用不存在的方法时自动调用的方法“__call()”。
代码片段
代码如下:
<?php
//这是一个测试的类,里面没有属性和方法
class Test{
}
//产生一个Test类的对象
$test=new Test();
//调用对象里不存在的方法
$test->demo("one", "two", "three");
//程序不会执行到这里
echo "this is a test<br>";
?>
上例出现如下错误,程序通出不能继续执行;
Fatal error: Call to undefined method Test::demo()
下面我们加上“__call()”方法,这个方法有2 个参数,第一个参数为调用不存在的方法
过程中,自动调用__call()方法时,把这个不存在的方法的方法名传给第一个参数,第二个参
数则是把这个方法的多个参数以数组的形式传进来。
代码片段
代码如下:
<?php
//这是一个测试的类,里面没有属性和方法
class Test{
//调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数
function __call($function_name, $args){
print "你所调用的函数:$function_name(参数:";
print_r($args);
print ")不存在!<br>\n";
}
}
//产生一个Test类的对象
$test=new Test();
//调用对象里不存在的方法
$test->demo("one", "two", "three");
//程序不会退出可以执行到这里
echo "this is a test<br>";
?>
上例输出结果为:
执行结果
你所调用的函数: demo(参数:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test.
[3]php面向对象全攻略 (十) final static const关键字的使用
来源: 互联网 发布时间: 2013-11-30
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 的成员是属于类的,是不属于任何对象实例,是
在类第一次被加载的时候分配的空间,其他类是无法访问的,只对类的实例共享,能一定程
度对类该成员形成保护;
从内存的角度我们来分析一下,内存从逻辑上被分为四段,其中对象是放在“堆内存”里
面,对象的引用被放到了“栈内存”里,而静态成员则放到了“初始化静态段”,在类第一次
被加载的时候放入的,可以让堆内存里面的每个对象所共享,如下图;
类的静态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样
的,类似于全局函数。
代码片段
<?
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; 是不允许的
这个关键字只能用来定义类和定义方法,不能使用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 的成员是属于类的,是不属于任何对象实例,是
在类第一次被加载的时候分配的空间,其他类是无法访问的,只对类的实例共享,能一定程
度对类该成员形成保护;
从内存的角度我们来分析一下,内存从逻辑上被分为四段,其中对象是放在“堆内存”里
面,对象的引用被放到了“栈内存”里,而静态成员则放到了“初始化静态段”,在类第一次
被加载的时候放入的,可以让堆内存里面的每个对象所共享,如下图;
类的静态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样
的,类似于全局函数。
代码片段
代码如下:
<?
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; 是不允许的
最新技术文章: