php对象

在对象中定义的变量属性,一般需要public,private,static关键字修饰,如果不加这些关键字修饰的话,需要在变量前加var关键字修饰。如下:

class Person {
  public name;   //定义属性名称
}

class Person {
  var name;    //定义属性名称
}

构造函数

在php5之前构造函数都是与类名相同的函数,在php5后构造函必须是两个下划线开始的函数,但是为了向下兼容,在php5中也可以识别与类同名的构造函数。

php5之前:
class Person {
  function Perosn(){};
}
php5之后:
class Person {
  function __construct(){};
}

析构函数

析构函数是在销毁一个对象之前执行一些特定的操作,如关闭文件等。当一个对象失去引用后就会自动调用析构函数。
析构函数是php5才引入的特性。析构函数的定义和构造函数一样都是以两个下划线开始的固定名称,析构函数不能带参数。如下:

class Person {
function __destruct(){};
}

对象的三大特性:

  • 封装
  • 继承
  • 多态

封装性

封装性是通过private关键字在对象里修饰变量或者方法来完成的。被private修饰的变量和方法不能再对象外部被直接访问。如果需要对对象里private变量和方法进行操作可以通过定义对象的public方法来访问。public的变量和方法可以在对象外直接被访问。
魔术方法:__get(), __set(), __isset(), __unset()
如果类中的私有变量太多,而且还需要访问多次,我们就需要为每个私有变量设置公共接口来访问,这样导致了繁琐。php5.1.0以后为我们提供了__set(),__get()等魔术方法来解决这个问题。
当我们需要在外部直接访问私有变量时,如果类的内部实现了对该私有变量的操作,在外部我们就能直接访问。如在外部调用私有变量:

<?php
    class Person {
        private $name;
        private $age;

        function __set($propertyname,$propertyvalue){   
            $this->$propertyname = $propertyvalue;
        }
        public function say() {
            echo "名称:"  .$this->name.  ", 年龄" .$this->age;
        }
    }

    $p = new Person();
    
    $p->name = "xzp";   //直接访问私有变量,系统会自动调用__set()函数
    $p->age = 8;        //直接访问私有变量
    $p->say();
?>

__set()方法:这个方法用来为私有成员属性设置值的,有两个参数,第一个参数为你要为设置值的属性名,第二个参数是要给属性设置的值,没有返回值。这个方法同样不用我们手工去调用,它也可以做成私有的,是在直接设置私有属性值的时候自动调用的,同样属性私有的已经被封装上 了,如果没有__set()这个方法,是不允许的,但是如果你在类里面加上了__set($propertyname, $value)这个方法,在直接给私有属性赋值的时候,就会自动调用它,把属性比如name传给$propertyname,把要赋的值“zhangsan”传给$value,通过这个方法的执行,达到赋值的目的。如果成员属性不封装成私有的,对象本身就不会去自动调用这个方法。为了不传入非法的值,还可以在这个方法给做一下判断。

__get()方法:这个方法用来获取私有成员属性值的,有一个参数,参数传入你要获取的成员属性的名称,返回获取的属性值,这个方法不用我们手工的去调用,因为我们也可以把这个方法做成私有的方法,是在直接获取私有属性的时候对象自动调用的。因为私有属性已经被封装上了,是不能直接获取值的,但是如果你在类里面加上了这个方法,在使用“echo$p1->name”这样的语句直接获取值的时候就会自动调用。

__isset() 方法:在看这个方法之前我们看一下"isset()"函数的应用,isset()是测定变量是否设定用的函数,传入一个变量作为参数,如果传入的变量存在则传回true,否则传回false。
那么如果在一个对象外面使用"isset()"这个函数去测定对象里面的成员是否被设定可不可以用它呢?分两种情况,如果对象里面成员是公有的,我们就可以使用这个函数来测定成员属性,如果是私有的成员属性,这个函数就不起作用了,原因就是因为私有的被封装了,在外部不可见。那么我们就不可以在对象的外部使用"isset()"函数来测定私有成员属性是否被设定了呢?
答案是可以的,你只要在类里面加上一个"__isset()"方法就可以了,当在类外部使用"isset()"函数来测定对象里面的私有成员是否被设定时,就会自动调用类里面的"__isset()"方法了帮我们完成这样的操作,"__isset()"方法也可以做成私有的。

__unset()方法:看这个方法之前呢,我们也先来看一下"unset()"这个函数,"unset()"这个函数的作用是删除指定的变量且传回true,参数为要删除的变量。那么如果在一个对象外部去删除对象内部的成员属性用"unset()"函数可不可以呢,也是分两种情况,如果一个对象里面的成员属性是公有的,就可以使用这个函数在对象外面删除对象的公有属性,如果对象的成员属性是私有的,我使用这个函数就没有权限去删除,但同样如果你在一个对象里面加上"__unset()"这个方法,就可以在对象的外部去删除对象的私有成员属性了。
在对象里面加上了"__unset()"这个方法之后,在对象外部使用"unset()"函数删除对象内部的私有成员属性时,自动调用"__unset()"函数来帮
我们删除对象内部的私有成员属性,这个方法也可以在类的内部定义成私有的。

继承性

继承可以使软件具有开放性,可扩展性,增加代码可重用性。
php的只有单继承,没有c++的多继承。
php的继承使用extends关键字修饰,语法如下:

<?php
class Student extends Person {}
?>

在继承中存在访问类型的控制,php5支持3中访问修饰符

  • public
  • preotected
  • private
    访问修饰符的区别与联系:
private protected public
类本身
类的子类中
所有外部成员

private
private修饰的成员,对于同一个类中的成员访问都没有限制,但是对于该类外的是不允许修改操作的,该类的子类也不能访问。
protected
protected修饰的成员,对于该类的子类及子类的子类都有访问权限。但不能被该类的外部代码访问。
重载
因为子类继承了父类的成员和方法,子类可以重载父类的方法,当子类存在和父类的方法同名时,会把父类的方法覆盖掉,叫方法重载。

<?php
class Person {
  function say() {
    echo " father";
  }
}
class Student extends Person {
   function say(){     //重载了父类的say()方法
    echo "student";
  }
}
?>

php中提供了一种在子类重载的方法中调用父类被覆盖的方法。如下:

<?php
  class Person {
  function say() {
    echo " father";
  }
}
class Student extends Person {
   function say(){     //重载了父类的say()方法
    parent::say();   //调用父类的方法
    echo "student";
  }
}
?>

在继承中常和 final,static,const等关键字一起使用

final
final关键字可以加在类和类中的方法前,但不能使用final标识成员属性。
final关键字的作用:
1.使用final标识的类不能被继承,也就是说被final标识的类是最终的版本。
2.在类中被final标识的方法不能在子类中被覆盖

<?php
final class Person{}
?>

static
在类中使用static关键字修饰的成员和成员方法时属于整个类,使用该类new出来的所有对象实例共享static修饰的成员和成员变量。
因为static修饰的变量和方法属于整个类,所以可以用类名来访问。如下:

类型::静态属性成员
类型::静态属性方法()

static修饰的属性和方法不属于哪个对象,是属于类,所以不能在类中使用$this关键字,在类中需要使用self关键字来访问静态成员。如下:

self::静态属性成员
self::静态属性方法()
class Person {
  static $count;
  function getcount(){
      return self::$count;   //使用$count变量
   }
}

静态方法使用的注意事项
类中的静态方法只能访问静态成员,不能访问非静态成员。非静态方法可以访问任何成员。
因为访问非静态成员需要使用$this 去引用,但是静态方法可以在没有对象实例的时候通过类名调用,没有对象实例就不存在$this,所以就不能使用非静态成员。
利用static在类的特性,我们可以实现单例模式。
单例模式
单例模式简单来说就是一个类只能创建一个对象。
因为php是脚本语言,每次访问都是一次独立执行的过程,在这个过程中一个类有一个实例就够了。比如操作数据库查询时只需要实例化一个数据库操作类就行了,并且只连接一次数据库就可以了,而不是在脚本中为了执行多条查询语句,单独的为每条语句实例化一个对象,如果这样的话效率会非常的低。所以单例模式的出现为我们很好的解决了这个问题。

<?php
    class DB {
        private static $obj = NULL;
        private function __construct(){   //构造函数用private修饰,类不能再外部被实例化。
            /*在这里完成数据库的连接操作*/
        }

        static function getInstance() {
            if (is_null(self::$obj)){
                $obj = new self();   //实例化本对象
            }
            return $obj;
        }

        function query($sql){
            echo $sql;
        }
    }

    $db = DB::getInstance();    //获得唯一的对象
    $db->query("select * from user");
?>

const
虽然const和static的功能不同,但是使用的方法非常的相似。在php中定义常量是通过define()函数来完成的,但是类中的常量需要使用const关键字来声明。
在类中用const声明的常量和static修饰的静态变量的访问方式一样,都是通过类名来访问,或者在成员方法中通过self关键字访问。类中的const方法只能访问类中的const常量。const修饰的常量前面不要$符号,并且const修饰的常量不可以修改,修改会触发错误。

<?php
    class Myclass {
        const CONSTANT = "CONSTANT value";

        function showconstant() {
            echo self::CONSTANT;    //在类中使用常量
        }
    }

    echo Myclass::CONSTANT;   //使用类名访问常量
    $cla = new Myclass();
    $cla->showconstant();
?>

多态性

  • 抽象类
    当一个类中的方法存在一个抽象方法,那么这个类就是抽象类。
    什么是抽象方法?
    抽象方法就是没有方法体的方法,并且在方法前面用abstract关键字修饰,如下:
abstract function fun1();  //没有方法体

如果一个类中存在抽象方法,那么这个类就是抽象类,这个类也必须使用abstract修饰。
在抽象类中可以存在不是抽象的成员和变量。抽象类不能实例化对象,只能被继承,继承抽象类的子类必须全部实现抽象方法,不然子类也是抽象类。抽象类里的成员和方法不能被private修饰。

abstract class person {
        var name;
        function getname() {
          ........
       }
      abstract function fun1();
  }
  • 接口
    接口也是一种抽象类。在接口中只能存在常量和抽象方法。接口的声明使用interface关键字修饰
interface 接口名称 {
    常量成员      //由const修饰的常量
    抽象方法      //在接口的抽象方法不需要abstract修饰
}

接口和抽象类一样不能实例化对象,必须由子类继承,子类必须实现所有的抽象方法才能实例化对象。php中只能继承一个类,但是可以继承多个接口,而且接口也能继承接口。
接口继承接口使用extends关键字:

interface two extends one {
......
}

类继承接口使用implements关键字:

class 类名 extends 父类名称 implements 接口1,接口2,接口3......{
......
}
  • 多态性
    多态是面向对象的三大特性中除封装和继承之外的另一重要特性。它展现了动态绑定的功能,也称为“同名异式”。多态的功能可让软件在开发和维护时,达到充分的延伸性。事实上,多态最直接的定义是让具有继承关系的不同类对象,可以对相同名称的成员函数调用,产生不同反应效果。所谓多态性就是指一段程序能够处理多种类型对象的能力,在PHP中,多态值指的就是方法的重写。方法重写是指一个子类中可以重新修改父类中的某些方法,使其具有自己的特征。重写要求子类的方法和父类的方法名称相同,这可以通过声明抽象类或是接口来规范。
    我们通过计算机USB设备的应用来介绍一下面向对象中的多态性,目前USB设置的种类仅我们自己用过的我想就有十几种吧。例如USB鼠标、USB键盘、USB存储设备等,这些计算机的外部设备都是通过USB接口连接到计算机以后,被计算机调用并启动运行的。也就是计算机正常运行的同时,没插入一种不同USB设备,就为计算机扩展一样功能,这正是我们所说的多态特征。那么为什么每个USB设备不一样,但都可以被计算机应用呢?那是因为每个USB设置都要遵守电脑USB接口的开发规范,都具有相同的能被计算机加载到并启用的方法,但运行各自相应的功能。这也正是我们对多态的定义,假设我们有一个主程序已经开发完成,需要后期由其他开发人员为其扩展一些功能,但需要在不改动主程序的基础上就可以加载到这些扩展的功能模块,其实也就是为程序开发一些插件。这就需要在主程序中需要为扩展的插件程序写好接口规范,然后每个插件只有按照规范去实现自己的功能,才能被主程序应用到。在计算机中应用USB设备的程序设计如下所示:
?php
//定义一个USB接口,让每个USB设备都遵守这个规范
interface USB{
function run();
}
 
class Computer{
//计算机类中的一个方法可以应用任何一种USB设备
function useUSB($usb){
$usb->run();
}
}
 
$computer =new Computer;
$computer ->useUSB(new Ukey()); //为计算机插入一个usb键盘设备,并运行
$computer ->useUSB(new Umouse()); //为计算机插入一个usb鼠标设备,并运行
$computer ->useUSB(new Ustore()); //为计算机插入一个usb存储设备,并运行
?>
<?php
//扩展一个USB键盘设备,实现usb接口
class Ukey implements USB {
function run(){
echo "运行USB键盘设备<br>";
}
}
//扩展一个USB鼠标设备,实现usb接口
class Umouse implements USB {
function run(){
echo "运行USB鼠标设备<br>";
}
}
 
//扩展一个USB存储设备,实现usb接口
class Ustore implements USB {
function run(){
echo "运行USB存储设备<br>";
}
}
?>

php对象常用函数

  • void __autoload(string 、$class);
    //尝试加载未定义的类class

  • bool class_alias(string $classname, string $alias, [bool $autoload = true]);
    //为类classname创建一个别名alias autoload指定是否调用__autoload 成功返回true 失败返回false

  • bool class_exists(string $classname,[bool $autoload = true])
    //检查类classname是否已定义 autoload指定是否调用__autoload

  • bool property_exists(mixed $class, string $proName);
    //检查类或对象class是否存在proName属性

  • bool method_exists(mixed $class, string $meName);
    //检查类或对象class是否存在meName方法

  • bool interface_exists(string $ifname,[bool $autoload = true]);
    //检查接口ifname是否已定义 autoload指定是否调用__autoload

  • bool trait_exists(string $trname,[bool $autoload = true]);
    //检查trait是否存在 autoload指定是否调用__autoload

  • string get_class([object $obj]);
    //得到对象obj的类名 如果在方法里调用则参数可选 如果不是对象返回false

  • string get_parent_class([object $obj]);
    //得到对象或类的父类名 如果在方法里调用则参数可选 如果不是对象且类不存在返回false

  • array get_class_vars(string $classname);
    在类外调用只返回公有属性和静态属性组成的关联数组;在类内调用返回所有属性组成的关联数组。

  • array get_object_vars(object $obj);
    在类外调用只返回公有属性组成的关联数组;在类内调用返回除了静态变量之外的所有属性组成的关联数组。

  • array get_class_methods(mixed $class);
    在类外调用返回公有方法和静态方法组成的数组;类内调用返回所有方法组成的数组

  • array get_declared_classes(void);
    //返回当前脚本中已定义类的名字数组

  • array get_declared_interfaces(void);
    //返回当前脚本中已定义接口的名字数组

  • array get_declared_traits(void);
    //返回所有已定义的traits的数组

  • bool is_subclass_of(mixed $ob,string $class);
    //如果对象ob所属类是类class的子类返回true

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容

  • 一:java概述: 1,JDK:Java Development Kit,java的开发和运行环境,java的开发...
    慕容小伟阅读 1,785评论 0 10
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,645评论 0 11
  • 面向对象编程(OOP) 在前面的章节中,我们学习了Kotlin的语言基础知识、类型系统、集合类以及泛型相关的知识。...
    Tenderness4阅读 4,434评论 1 6
  • 1.PHP 对待对象的方式与引用和句柄相同,即每个变量都持有对象的引用,而不是整个对象的拷贝。 2.class 中...
    我在太行山下阅读 538评论 0 0
  • 今天没有画画,因为老猪哥夜班转中班,上午回到家时已经很困了,上床后马上就睡着了。下午十四时三十分左右闹钟响了又要上...
    涯为漫画痴阅读 676评论 11 22