目录
PHP中的类class与对象obj
1.类的创建 class
2.创建对象的6种方法
3.类常量 const
4. 自动加载类,spl_autoload_register()
5.类的构造方法
6.类的继承 extends
7.类内访问控制符private
8.类内静态访问 成员状态符:static
9.静态绑定 self parent static
10.克隆对象 clone
11. 魔术方法 __call() __callStatic()
12. 对象的序列化
13. 抽象类 abstract
14. 接口 interface
15. 代码复用 trait
16. 命名空间 namespace
17. 对象的遍历
class Demo
{
//属性和方法
//属性的声明必须以访问控制符开头(public、private、protected)
public $name = 'php'; //公共属性,外部可以访问
private $age = 20; //私有属性,只允许类中的访问调用
protected $sex = 'male'; //受保护的,仅允许本类或子类访问
//属性类型支持:标量(整数/浮点/字符串/布尔值),复合类型:数组和对象
//方法也必须以访问控制符开头:public,private,protected
public function getName(){
//$this是伪变量,总是指向当前对象
return $this->name;
}
public function getAge(){
return $this->age;
}
}
//创建对象的过程,就是类的实例化
$obj = new Demo(); //$obj 就是Demo的实例
//类必须实例化才可以访问里面的属性和方法
echo $obj->name; //用对象访问运算符->来直接访问属性
echo '
';
echo $obj->getName();
//echo $obj->age; //private定义的属性不能在外部访问
echo '
';
echo $obj->getAge(); //private属性可以通过类内函数访问
echo '
';
//通过类实例化的对象是一个引用变量
//我们对对象的赋值并没有创建新对象,而是创建一个当前对象的引用
$obj2 = $obj;
if($obj2 === $obj){ //返回完全相等
echo '相等';
}else{
echo '不相等';
}
echo '
';
echo get_class($obj2); //获取对象
echo '
';
echo get_class($obj); //两个对象是同一个
echo '
';
echo $obj2->name;
//如果在类的外部访问属性或方法,可以直接通过创建对象
//如果在类的内部访问属性或方法,必须使用伪变量$this(因为对象还未创建)
class Demo1
{
public $name = 'PHP中文网';
public function getName()
{
return $this->name;
}
public function getObj(){
return new self(); //返回一个当前对象
}
public function getStatic(){
return new static();
}
}
class Demo2 extends Demo1 //extends继承父类
{
public function getNewObj(){
return new parent(); //根据当前类的父类创建一个对象
}
}
$obj1 = new Demo1(); //如果不需要传入参数,可以省去括号
echo $obj1->name;
echo '
';
将类名以字符串的方式放在一个变量中
$className = 'Demo1';
$obj2 = new $className();
echo $obj2->name;
echo '
';
用对象来创建对象,并且它创建的是一个新对象
$obj3 = new $obj1(); //注意:与$obj3 = $obj1 不同
echo get_class($obj3);
echo '
';
echo $obj3->name;
echo '
';
用 new self()
$obj4 = $obj1->getObj();
echo get_class($obj4);
echo '
';
echo $obj4->name;
echo '
';
用 new parent() 来创建一个对象
$obj5 = (new Demo2)->getNewObj();
echo get_class($obj5);
echo '
';
echo $obj5->name;
echo '
';
基于当前调用的类来创建 new static,new static创建的对象,直接与调用者绑定,静态延迟绑定
$obj6 = (new Demo1)->getStatic();
$obj7 = (new Demo1)->getObj();
echo get_class($obj6);
echo get_class($obj7);
echo '
';
$obj8 = (new Demo2)->getStatic();
$obj9 = (new Demo2)->getObj();
echo get_class($obj8); //new static 返回的是Demo2
echo '
';
echo get_class($obj9); //new self() 返回的是Demo1
类常量是用const关键字创建,不要加$符,必须初始化 (对比记忆,外部访问静态变量static,需要加$符号)
类常量从php5.3+开始支持nowdoc语法
class Demo
{
const siteName = 'php中文网';
const domain = <<< 'EOT'
www.php.cn
EOT;
public function getSiteName(){
//在类的方法中访问类常量:self::类常量名
return self::siteName;
}
}
访问类常量的方法://类外访问类常量:(类名/类变量/对象/对象->方法 ::类常量名)
//方法1:类名::类常量名
echo '1.类名::类常量名:'.Demo::siteName.Demo::domain.'
';
//方法2:类变量::类常量名 php5.3+
$className = 'Demo';
echo '2.类变量::类常量名:'.$className::siteName.$className::domain.'
';
//方法3:用当前类的对象来访问类常量
echo '3.对象::类常量名:'.(new Demo())::siteName.'
';
//方法4:用类中的方法来间接访问类常量
echo '4.对象->方法():'.(new Demo)->getSiteName();
//类外访问类常量:类名/类变量/对象/对象->方法 ::类常量名 //在类的方法中访问类常量:self::类常量名
class Test
{
public $name;
//构造方法,实例化类的时候,自动调用,通常用来初始化对象
public function __construct($name = 'PHP中文网')
{
$this->name = $name;
}
}
加载php类的方法,新建一个autoloader.php文件,使用spl_autoload_register()直接加载自动加载函数loader
//1. 用require或include导入一个类文件
require('test.php'); //导入test.php
include('test.php'); //导入test.php
//2.自定义导入函数,用spl_autoload_register()将自定义的类导入函数添加到函数栈中
function loader($className){ //自动装载函数,参数为要导入的类名
$path = $className.'.php'; //test.php
if(file_exists($path)){
require_once($path);
}else{
echo $path.'不存在,请检查~~';
}
}
spl_autoload_register('loader'); //直接加载函数
echo (new Test('www.php.net'))->name;
类内添加自动加载函数,//自定义的注册函数在类内,spl_autoload_register(['类名/对象','方法名']);
class LoaderClass
{
function loader($className)
{
$path = $className.'.php';
if(file_exists($path)){
require_once($path);
}else{
echo $path.'不存在,请检查';
}
}
}
//自定义的注册函数在类内,spl_autoload_register(['类名/对象','方法名']);
spl_autoload_register([(new LoaderClass),'loader']); //类内函数加载
echo (new Test('www.php.net'))->name;
类内静态方法 static function
class LoaderClass
{
static function loader($className){
$path = $className.'.php';
if(file_exists($path)){
require_once($path);
}else{
echo $path.'不存在,请检查类';
}
}
}
spl_autoload_register(['LoaderClass','loader']); //静态方法加载
echo (new Test('www.php.net'))->name;
构造方法:是用来实例化类,创建对象的
构造方法使用固定的方法名:__construct()
析构方法:对象销毁时自动调用,没有参数,__destruct()
class Staff //声明一个员工类
{
public $name;
public $age;
public $salary;
//构造方法使用固定的方法名:__construct()
public function __construct($name,$age,$salary){
//构造方法:通常是同来初始化对象中的属性
$this->name = $name;
$this->age = $age;
$this->salary = $salary;
}
//析构方法:对象销毁时自动调用,没有参数,__destruct()
public function __destruct()
{
echo '当前对象被销毁啦~~';
}
}
创建一个对象,来访问类中的属性
$obj = new Staff('peter',25,3500);//构建对象时,初始化赋值
echo '姓名:'.$obj->name;
echo '
';
echo '年龄:'.$obj->age;
echo '
';
echo '薪水:'.$obj->salary;
echo '
';
销毁对象,使用unset()方法
unset($obj); //变量值为none,当前对象失去了引用,启动垃圾回收机制
新建一个父类
class Person
{
protected $name; //protected受保护,外部不可访问,只允许自己内部或子类访问
protected $age;
protected $salary;
//创建构造方法,用来实例化这个类
public function __construct($name,$age,$salary)
{
$this->name = $name;
$this->age = $age;
$this->salary = $salary;
}
//这里声明为保护的,这样就只能被子类继承,子类继承过去仍然是protected
// protected function showMess()
protected function showMess()
{
return '我的姓名是:'.$this->name.',年龄是:'.$this->age.',工资是:'.$this->salary;
}
}
//声明一个子类(扩展类),继承使用关键字:extends,php是单继承语言
//创建子类是为了扩展父类的功能,实现代码复用
class Staff extends Person
{
protected $department; //员工所在部门
public function __construct($name,$age,$salary,$department)
{
parent::__construct($name,$age,$salary); //父类的初始化,简写
// $this->name = $name;
// $this->age = $age;
// $this->salary = $salary;
$this->department = $department;
}
//在子类重写父类方法,其访问权限不能低于原来的,原来是protected,那么现在应该是public
public function showMess(){
return parent::showMess().',部门是:'.$this->department;
// return '我的姓名是:'.$this->name.',年龄是:'.$this->age.',工资是:'.$this->salary.',部门是:'.$this->department;
}
}
$obj = new Staff('Mary',28,8900,'市场部');
echo $obj->showMess();
/**
* 魔术方法,可以访问私有属性
* 1. __get(属性名):外部访问不存在或私有属性时自动调用
* 2. __set(属性,值):外部给类中不存在或不可见属性赋值时自动调用
* 3. __isset(属性名):外部检测某私有属性是否存在时自动调用
* 4. __unset(属性名):在类外部销毁某个私有属性时自动调用它
*/
class Staff
{
private $name; //私有的,外部不可见
private $age;
private $salary;
public function __construct($name,$age,$salary){
//构造方法用来初始化对象属性
$this->name = $name;
$this->age = $age;
$this->salary = $salary;
}
//__get(属性名):外部访问不存在或私有属性时自动调用
public function __get($name){
return $this->$name;
}
//__set(属性,值):外部给类中不存在或不可见属性赋值时自动调用
public function __set($name,$value){
if($name == 'age'){ //若想设置某个值不被修改,单独添加判断
return false;
}
$this->$name = $value;
}
// public function getName(){ //通过接口访问类内私有变量
// return $this->name;
// }
// public function getAge(){
// return $this->age;
// }
// public function setName($name,$value){
// $this->$name = $value;
// }
/**
* __isset():检测是否存在某个属性
* __unset():删除某个私有属性
*/
public function __isset($name){
return isset($this->$name);
}
public function __unset($name){
unset($this->$name);
}
}
类外访问private的方式如下:(自动调用魔术方法)
$obj = new Staff('peter',28,4500);
//echo $obj->getName();
//echo $obj->getAge();
//echo "
";
//$obj->setName('name','Danew');
//echo $obj->getName();
//echo "
";
//$obj->setName('age',40);
//echo $obj->getAge();
echo $obj->name;
echo $obj->age;
echo $obj->salary;
echo '
';
$obj->name = 'Tom';
echo $obj->name;
echo '
';
$obj->age = 20;
echo $obj->age;
echo '
';
$obj->salary = 5000;
echo $obj->salary;
echo "
";
echo isset($obj->age) ? '存在' : "不存在";
echo "
";
unset($obj->age); //魔术方法自动调用,修改私有属性
echo isset($obj->age) ? '存在' : "不存在";
public static $name = 'Peter'; //公共静态属性,类内部/外部/子类均可访问
private static $age = 28; //私有静态属性,只能在类内部访问
protected static $salary = 3600; //受保护的静态属性,可以在类内部和子类中访问
public static function show(){ //静态方法
注:静态属性只允许在静态方法中访问,静态方法不允许使用伪变量$this->
class Father
{
//访问控制符:指示类成员在哪里可以被访问:public/private/protected
//成员状态符:指示如何访问该成员:静态self/parent/static 非静态:$this->
public static $name = 'Peter'; //公共静态属性,类内部/外部/子类均可访问
private static $age = 28; //私有静态属性,只能在类内部访问
protected static $salary = 3600;//受保护的静态属性,可以在类内部和子类中访问
public static function show(){ //静态方法
//类里面访问静态属性时,不能使用this伪变量
//使用 self::(属性)
//静态属性只允许在静态方法中访问,静态方法不允许使用伪变量$this->
//因为静态方法为所有的对象所共有的,不需要引用
return '年龄:'.self::$age.'---'.'工资:'.self::$salary;
}
}
//创建子类Son,继承父类
class Son extends Father{
public static function display(){
//parent::引用父类中的静态成员
return '工资是:'.parent::$salary;
}
}
在类的外部访问类内静态成员,使用 类名::静态成员,其中静态属性必须要加$符号
静态成员包括(静态属性和静态方法)
echo '姓名是:'.Father::$name;//外部使用类访问静态属性
echo '
';
echo Father::show(); //访问类中的静态方法
echo '
';
echo Son::show(); //用子类访问父类的静态方法
echo '
';
echo Son::display(); //访问子类的静态方法
echo '
';
$obj = new Father();
echo $obj::show(); //外部使用对象,也可以访问静态方法
//echo $obj->$name; //外部对象不能访问类中的静态属性
echo '
';
$res = $obj instanceof Father;
echo '$obj是Father类的实例吗?'.($res ? '是的' : '不是的');
总结:使用 类名::静态成员可以访问静态属性和静态方法,继承类同样可以
外部对象不能通过->访问静态成员,只能通过::作用域访问静态成员
self静态绑定当前类,parent 静态绑定当前类的父类,static是动态绑定当前的调用类,叫做:静态延迟绑定(后期静态绑定)
* 静态绑定(self和parent)它们与类的绑定是在代码的编译阶段进行,
* 而static与类的绑定是在代码的运行时才进行绑定,所以叫:静态延迟绑定(与类绑定的时机不同)
class Demo1
{
public static $name = 'peter';
public static $salary = 3000;
public static function show()
{
//return self::$name;//访问本类中的静态属性 self::就是当前类
//return static::$name; //访问本类中的静态属性static::就是当前类
return static::$sex;
//static和self,parent是不一样的,它对应的类是动态设置的,由调用类决定
}
}
class Demo2 extends Demo1
{
public static $sex = 'male';
public static function display()
{
//parent::与父类进行静态绑定
//self::与当前类 静态绑定
//static::与当前类 静态绑定
//return parent::$name.'的工资是:'.parent::$salary.',性别是:'.self::$sex;
return parent::$name.'的工资是:'.parent::$salary.',性别是:'.static::$sex;
}
}
//echo '姓名是:'.Demo1::$name; //外部访问类中的静态属性
//echo '
';
//echo '姓名是:' . Demo1::show(); //外部访问类中的静态方法
//echo "
";
//echo Demo2::display();
echo '性别是:' . Demo2::show(); //外部访问类中的静态方法
//这里是Demo2调用static,所以static与Demo2绑定,返回Demo2的静态属性
* 总结
* 克隆就是将当前对象复制一份镜像,与重新new 一个对象完全相同
* 对象赋值时引用,仅仅是给当前对象起了一个别名,并没有创建新对象
* 关键字clone克隆出的一个与原来对象毫无关系的一个新对象
class Demo
{
public $name = 'peter';
}
$obj1 = new Demo();
$obj2 = $obj1; //对象都是引用赋值
$obj3 = clone $obj1; //克隆,相当于值传递赋值,将当前对象复制到新的变量中
$obj4 = new Demo(); //创建对象
$obj1->name = 'jack'; //重新设置对象$obj1中的属性name的值
echo '对象引用:'.$obj1->name,'---',$obj2->name; //引用赋值,对象是同一个
echo '
';
echo '克隆赋值:'.$obj1->name,'---',$obj3->name; //克隆赋值,产生独立的新的对象
echo '
';
echo '创建对象:'.$obj1->name,'---',$obj4->name; //创建对象,产生新的对象
echo '
';
echo '克隆对象的类是:' . get_class($obj3); //大家都是同一个类的对象
当外部访问一个不存在的非静态方法时,自动调用类中的魔术方法: __call()
当外部访问一个不存在的静态方法时,自动调用类中的魔术方法: __callStatic()
__call($method,$args) 第一个参数是方法名,第二个参数是方法的参数,以数组形式传入
class Demo
{
//第一个参数是方法名,第二个参数是方法的参数,以数组形式传入
public function __call($method, $args)
{
// 遍历参数$args
$var = '';
foreach ($args as $values) { //args是数组,作为数组遍历
$var .= $values.','; // .= 字符串的连接运算
}
return '您调用的方法:' . $method . '(' . $var . ')' . '并不存在';
}
//当我们调用一个不存在的静态方法时,会自动调用 __callStatic()
public static function __callStatic($method,$args){
$var = '';
foreach($args as $values){
$var .= $values.',';
}
return '您所调用的静态方法:' . $method . '(' . $var . ')' . '并不存在';
}
}
//当访问一个不存在的非静态方法时,自动调用类中的魔术方法: __call()
echo (new Demo())->hello('php','python');
echo '
';
//当访问一个不存在的静态方法时,自动调用类中的魔术方法: __callStatic()
echo Demo::world('HTML', 'JS', 20);
序列化原因:对象是没有对应实体的,程序结束后就消失了,想保存必须要序列化;
序列化本质:就是将对象转为二进制的字符串描述,保存到变量或者文件中;
序列化函数: serialize()和__sleep()搭配使用,实现对象指定属性的序列化
反序列化函数: unserialize()和 __wakeup()搭配使用,实现序列化唤醒以及属性值修改
class Staff
{
public $name;
public $age;
public $salary;
public function __construct($name,$age,$salary)
{
$this->name = $name;
$this->age = $age;
$this->salary = $salary;
}
public function __sleep() //如果存在,序列化对象时将自动调用,将指定的属性序列化
{
//将允许序列化的对象属性放在一个数组中返回
return['name', 'age'];
}
public function __wakeup() //如果存在,反序列化时将自动调用wakeup,修改对象属性值
{
$this->age = 48; //唤醒的结果已被修改
}
}
$obj1 = new Staff('peter',28,5000);
echo '我的姓名是:'.$obj1->name.'年龄是:'.$obj1->age.'工资是:'.$obj1->salary;
echo '
';
//序列化
$objStr = serialize($obj1);
echo '序列化的对象:'.$objStr;
echo '
';
//反序列化
$obj2 = unserialize($objStr); //$objStr没有salary,所以$obj2也没有salary
echo '我的姓名是:'.$obj2->name.'年龄是:'.$obj2->age;
运行结果如下:
1. 类内有抽象方法,则必须改为抽象类,
2. 抽象类规定了子类必须拥有的方法,但具体的实现由子类决定
3. 抽象方法不允许实例化,只能用子类实例化
abstract class Demo //抽象方法不允许实例化
{
public $name;
public function __construct($name)
{
$this->name = $name;
}
abstract public function hello(); //没有函数体,这就是抽象方法
abstract public function say();
public function test(){
return 'Demo::test()';
}
}
//必须在子类中将抽象类中的全部抽象方法全部实现才可以
class Demo1 extends Demo
{
public function hello(){
return 'Hello '.$this->name;
}
public function say(){
return '我的name是:'.$this->name;
}
}
//Demo是抽象类,不能实例化,只有子类才可以
$obj = new Demo1('php');
echo $obj->name;
echo '
';
echo $obj->hello();
echo '
';
echo $obj->say();
echo '
';
echo $obj->test(); //正常方法还是正常调用
接口是一种特殊的类,不使用class创建,使用interface声明
* 接口的成员中同样有属性和方法
* 1.属性:类常量 (const)
* 2.方法:抽象方法(默认public,可以不写)
//接口1
interface Demo1
{
//接口成员属性必须是:类常量
const SITENAME = 'PHP中文网';
//接口成员方法必须是抽象方法,而且访问控制符必须是public,可以省略,但abstract必须省略
function show();
function mess();
}
//接口2
interface Demo2
{
function hello();
}
//接口不允许实例化,但可以被继承,所以需要创建一个类,来继承接口,并实现接口中全部抽象方法
class Test implements Demo1,Demo2 //使用implements可以继承多个接口,但php仍是单继承的面向对象的语言
{
//实现接口Demo1中的show()方法
public function show(){
return '站点名称是:'.self::SITENAME;
}
//实现接口Demo1中的mess()方法
public function mess(){
return '站点域名是:www.php.cn';
}
//实现接口Demo2中的hello()方法
public function hello(){
return self::SITENAME.'欢迎您!';
}
}
$obj = new Test();
echo $obj->show(); //访问接口Demo1中的show()方法
echo '
';
echo $obj->mess(); //访问接口Demo1中的mess()方法
echo '
';
echo $obj->hello(); //访问接口Demo2中的hello()方法
* trait 是一种代码复用的方法
* Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。
* Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。
类中的公共或外部代码主要来源
1.父类
2.trait类(方法集),横向扩展类的功能
* Trait类还可以互相嵌套
同一类中,同名方法访问优先级:子类>trait类>父类
Trait类同名方法不能直接use,要用 替换insteadof 或 别名as 才能访问
1. use Test1;(Test1为trait类,不能实例化,不能有类常量),use方法相当于将trait类的内容全部拷贝进来;
//1.创建一个trait类Test1
trait Test1
{
public $name = 'PHP中文网'; //trait类中可以有属性,不能有类常量
public function hello1()
{
return 'Test1::hello1()';
}
}
//2.创建一个trait类Test2
trait Test2
{
// use Test1; //trait类可以直接将Test1中的代码复制到了Test2中
public function hello2(){
return 'Test2::hello2()';
}
}
//3.创建父类Demo
class Demo
{
public function hello2() //与trait同名方法,会被trait的方法覆盖
{
return '父类Demo::hello2()';
}
}
//4.创建子类Demo1
class Demo1 extends Demo
{
// use Test1,Test2; //相当于将trait内的内容拷贝进来
use Test2; //Test2中已经有了Test1
public function hello2() //与trait同名方法,本类优先级最高
{
return '子类Demo1::hello2()';
}
}
//测试
$obj = new Demo1();
echo $obj->hello1(); //访问trait类Test1中的hello1()
echo '
';
echo $obj->name;
echo '
';
echo $obj->hello2(); //测试同名优先级
2. trait同名方法,使用替换insteadof或别名as才能访问,否则报错;
//1.创建一个trait类Test1
trait Test1
{
public function hello()
{
return 'Test1::hello()';
}
}
//2.创建一个trait类Test2
trait Test2
{
public function hello(){
return 'Test2::hello()';
}
}
//3.创建类Demo1
class Demo1
{
use Test1,Test2 { //trait类方法同名时,设置替换方式
Test1::hello insteadof Test2; //用Test1::hello()替换Test2::hello()
Test2::hello as test2Hello; //用别名访问Test2::hello()方法
}
}
//测试
$obj = new Demo1();
echo $obj->hello();
echo '
';
echo $obj->test2Hello(); //test2Hello 是Test2::hello()方法的别名
* 命名空间:解决了同一脚本中成员命名冲突的问题,是一种代码封装技术
* 函数、常量、类是作用于全局的,容易同名,一般需要命名空间封装
* 一般一个文件只使用一个命名空间
namespace test1;
const SITE_NAME = 'PHP'; //声明常量SITE_NAME
function sum($n, $m)
{
return $n + $m;
}
class Staff
{
private $name = 'Peter';
public function __get($name){
return $this->$name;
}
public function __set($name, $value)
{
$this->$name = $value;
}
}
namespace test2;
//use test1; //只定位到空间,未定位到类
use test1\Staff as test1Staff; //定位到空间中的类,只是引用,并没有引入类
use test2\test3\Demo;
const SITE_NAME = 'www.php.cn'; //声明常量SITE_NAME
function sum($n, $m)
{
return $n + $m;
}
class Staff
{
private $name = 'Jack';
public function __get($name){
return $this->$name;
}
public function __set($name, $value)
{
$this->$name = $value;
}
}
访问
//访问
echo '当前的命名空间是:'.__NAMESPACE__;
echo '
';
echo SITE_NAME; //非限定名称的命名空间
echo '
';
echo \test1\SITE_NAME; //访问命名空间1的常量,完全限定名称的命名空间
echo '
';
echo sum(10, 15);
echo '
';
$obj = new Staff();
echo $obj->name;
echo '
';
$obj1 = new \test1\Staff(); //访问命名空间1的类
echo $obj1->name;
//echo '
在test2启用test1后
';
//$obj1 = new test1\Staff(); //少写一个\
//echo $obj1->name;
echo '
在test2启用test1的类
';
$obj1 = new test1Staff(); //重命名后
$obj1->name = 'Tom';
echo $obj1->name;
echo '
';
echo Demo::CITY;
namespace test2\test3; //子空间
class Demo
{
const CITY = 'HFSS';
}
* 对象的遍历一般指的是针对public的属性进行遍历
* private和protected属性需要类内方法遍历
class Demo
{
public $name;
public $age;
public $salary;
private $sex; //私有属性
protected $isMarried; //受保护属性
public static $home; //静态属性
//声明构造方法,用来初始化属性
public function __construct($name, $age, $salary,$sex,$isMarried,$home)
{
$this->name = $name;
$this->age = $age;
$this->salary = $salary;
$this->sex = $sex;
$this->isMarried = $isMarried;
self::$home = $home;
}
//声明一个query方法,用来在类的内部遍历属性
public function query()
{
print '遍历出对象中的全部属性,包括私有和受保护的:
';
foreach ($this as $key=>$values){
print $key.'=>'.$values.'
';
}
print self::$home;
}
}
//外部访问
$obj = new Demo('peter',18,5000,'male',true,'合肥');
//遍历对象
echo '外部访问公共属性
';
foreach ($obj as $key => $value) {
echo $key.'=>'.$value.'
';
}
echo '
';
echo '外部访问静态成员 Demo::$home;'.Demo::$home;
echo '
';
$obj->query(); //遍历出对象中的全部属性
运行结果如下: