PHP--面向对象

原创 2016年08月31日 17:47:10
面向对象编程的三特点: 封装性,继承性(PHP支持单继承),多态性

PHP的一个类必须在一段代码段中,即一个“<?php  ......  ?>”

php5.6.25

一个简单的类:

class PhpClass{
    public $name;
    public function toString(){
        return "PhpClass";
    }
}

定义成员方法:  [关键词] function 方法名(){...}

访问成员方法:  对象名->成员方法

定义成员变量:  [关键字] 成员变量名

访问成员变量:  对象名->成员变量

关键字可以使用 public、private、protected、static和final中的任意一个

定义类常量:      const 常量名
访问类常量:      类名::常量名

<?phclass PhpClass{
    public $name;
    const PI = 3.1415926;   // 不能有修饰词
    public function toString(){
        return "PhpClass";
    }
    public function printPI(){
        echo PhpClass::PI.'<br/>';  // 直接通过类名访问
    }
    public function printName(){
        echo $this->name;   // 注意此处的写法
    }
}
$lycClass = new PhpClass();
echo $lycClass::PI.'<br/>'; // 通过对象访问
echo PhpClass::PI.'<br/>';
echo $lycClass->toString().'<br/>';
$lycClass->name = "Lyc";
$lycClass->printName();

构造方法和析构方法:

构造方法: 不写会默认一个

void __construct([mixed args [,...]]) 下划线为两个

析构方法: 

void __destruct(void) 下划线为两个

php使用垃圾回收机制,不用 unset 函数析构方法也会自动被调用

class PhpClass{
    public $name;
    //public function __construct(){} PHP不支持 C++、java 形式上的方法重载

    public function __construct($name){
        $this->name = $name;
    }
    public function __destruct(){
        echo '析构一下...';
    }
}
$lycClass = new PhpClass('lyc');
echo $lycClass->name;
//unset($lycClass); 不写也会调用 __destruct()

继承和多态:

继承: 在PHP中子类可以继承父类的所有public和protected修饰的成员变量和方法,包括构造方法。

声明继承的格式: 

class subClass extendes superClass{

......

}

多态:(覆盖和重载两种,覆盖和c++、java中重写相同)

重载概念和c++、java中的重载概念相同,但实现方式不同,重载实例: 

class PhpClass{
    public $nae;
    // PHP中有很多以两个下划线开头的方法,被称为魔术方法***********************
    /* __call()方法的作用是: 当程序试图调用不存在或不可见的成员方法时
     * PHP会先调用__call()方法来存储方法名及其参数。__call()方法包含
     * 两个参数,即方法名和方法参数。其中,方法参数是以数组形式存在的  */
    function __call($name, $arguments){
        // 通过count($arguments)获得参数个数
        $argNum = count($arguments);
        //echo $argNum."***************<br/>";
        if($name == 'right'){   // 一下方法调用中的 $this-> 不可省略
            switch($argNum){
                case 0:
                    $this->right0();
                    break;
                case 1:
                    $this->right1($arguments[0]);
                    break;
                case 2:
                    $this->right2($arguments[0],$arguments[1]);
                    break;
                default:
                    echo "参数可能多了,我不干了...<br/>";
            }
        }else if($name == 'left'){
            switch($argNum){
                case 1:
                    $this->left1($arguments[0]);
                    break;
                case 2:
                    $this->left2($arguments[0],$arguments[1]);
                    break;
                default:
                    echo "参数不对,我不干了...<br/>";
            }
        }else{
            echo "什么也不做...";
        }
    }
    //几种实现重载的方法,方法名不相同
    public function right0(){
        echo 'right0<br/>';
    }
    public function right1($arg){
        echo 'right1 '.$arg.'<br/>';
    }
    public function right2($arg1,$arg2){
        echo 'right1 '.$arg1.' '.$arg2.'<br/>';
    }
    public function left0(){
        echo 'left0<br/>';
    }
    public function left1($arg){
        echo 'left1 '.$arg.'<br/>';
    }
    public function left2($arg1,$arg2){
        echo 'left1 '.$arg1.' '.$arg2.'<br/>';
    }
}
$lyc = new PhpClass();
$lyc->left();           // 此处实现重载
$lyc->left('LEFT');
$lyc->left('LEFT','LYC');
$lyc->right();
$lyc->right('RIGHT');
$lyc->right(123,'LYC');
$lyc->right(123,'lyc','right');


$this:

$this类似C++java中的this,只能在类中使用,意思就是对象本身,切记是对象本身
class LycA{
    //若果LycA被LycB继承,通过LycB调用,$this就是LycB
    //若果LycA被LycC继承,通过LycC调用,$this就是LycC
    //总之哪个对象调用的,就是哪个对象
    public function toString(){
        //$this->toStr();
        return get_class($this);
    }
    public function toStr(){
        return get_class($this);
    }
}
class LycB extends LycA{
    public function toString(){
        echo parent::toString();    // 此处仍然是 LycB  尽管重写了父类中的toString()方法,仍然调用父类中的
        echo parent::toStr();       // 此处仍然是 LycB
        return get_class($this);    // LycB
    }
}
$lycB = new LycB();
echo $lycB->toString().'<br/>';     // LycBLycBLycB
$lycA = new LycA();
echo $lycA->toString().'<br/>';     //LycA

::(parent、self、类名):
::可以在没有声明实例的情况下使用类中的属性和方法
class LycA{
    const CONST_LYCA = 'CONST_LYCA';
    public $namea = 'LycAClass';
    static $staticA = 'staticA';
    public function toString(){
        //$this->toStr();
        return get_class($this);
    }
    public function toStr(){
        return 'LycA.toStr()';
    }
    static function staticStr(){
        return 'staticA';
    }
}
class LycB extends LycA{
    const CONST_LYCB = 'CONST_LYCB';
    public $nameb = 'LycBClass';
    static $staticB = 'staticB';
    public function println(){
        // parent 可以调用父类中的cosnt属性、static属性、static方法和一般方法,包括继承而来的。
        // 类名、self 可以调用本类中的cosnt属性、static属性、static方法和一般方法,包括继承而来的。
        //$this可以调用本类中的一般属性和方法,包括继承而来的
        echo parent::CONST_LYCA.'<br/>';
        echo self::$staticB.'<br/>';
        echo LycB::toString().'<br/>';
        echo $this->namea.'<br/>';
        echo $this->toStr().'<br/>';
        /*  在PHP中const、static修饰的属性和方法属于类,不属于对象,而$this是伪对象,不能调用
            parent、self和类名可以调用const、static修饰的属性和方法,并且还可以调用一般方法(在类外使用有区别) */
    }
}
$lycB = new LycB();
$lycB->println();
// 类名 在类外或外类中使用可以调用本类中的cosnt属性、static属性、static方法,包括继承而来的。相对在本类中使用缺少了一般方法的调用
echo LycB::$staticB;
//LycB::println();    //错误

public、protected、private、static、final:
public:公开,都可以访问
protected:本类和子类中可以访问
private:只有本类,子类也不可以
对于成员变量,必须指定关键字;对于成员方法,如果没有指定关键字,默认为public。
被final修饰的类不能被继承,被final修饰的方法不能被重写或覆盖。

抽象类:

抽象类不能实例化,至少要有一个抽象方法,也包含成员变量和成员方法,用abstract声明

abstract class AbstractName{ ...... }

抽象方法:abstract function abstractName();


接口:

PHP使用接口实现多继承,和java类似,只能包含一些未实现的方法和成员变量,不能用public以外的关键字修饰接口中的类成员

接口:

interface InterfaceName{

functioninterfaceName1();

......

}

实现接口:

class SubClass implements InterfaceName1,InterfaceName2...{

...所实现的接口中的方法

}


克隆对象:网上有不同版本的说法,这里测试结果也和网上的不全相同,具体情况请自行测试

在PHP5中,默认情况下对象 是通过引用传递的,和java的对象传递是相似的,赋值之后,两个变量保存的都是同一地址的引用。C++中的引用是给变量起别名

class SportObject{
    private $object_type = 'book';
    public function setType($type){
        $this->object_type = $type;
    }
    public function getType(){
        return $this->object_type;
    }
}
$book1 = new SportObject();
$book2 = $book1;
$book2->setType('computer');
echo '对象$book1的值为:'.$book1->getType();  // computer
$book3 = &$book1;
$book3->setType('macbook');
echo '对象$book1的值为:'.$book1->getType();  // macbook

如果要想复制的形式赋值的话,可以使用 clone

$book4 = clone $book1;

这样 $book4和$book1是不同的两个对象。改变一个不会影响另一个

__clone() 方法:在克隆对象的过程中,调用__clone()方法,进行相关操作

class SportObject{
    private $object_type = 0;
    public function setType($type){
        $this->object_type = $type;
    }
    public function getType(){
        return $this->object_type;
    }
    public function __clone(){
        $this->object_type = 'iphone';
    }
}
$book1 = new SportObject();
$book2 = clone $book1;
echo $book2->getType(); // iphone

instanceof:

用于检测当前对象属于哪个类,基础父类,实现接口,都可检测

class A{}
interface B{}
class lyc extends A implements B{}
$lyc = new lyc();
$lyc instanceof lyc;    // true
$lyc instanceof A;      // true
$lyc instanceof B;      // true

魔术方法:

PHP中有很多以两个下划线开头的方法,构造方法__construct(),析构方法__destruct(),__call,__clone(),这些方法被称为魔术方法

PHP中保留了所有以”__“开头的方法,所以只能使用已有的这些方法,不要自己创建。如果希望PHP调用这些魔术方法,首先必须在类中进行定义,否则PHP不会执行未定义的魔术方法。

__set():当程序试图写入一个不存在或不可见的成员变量时,PHP就会执行__set()方法。__set()方法包含两个参数,分别表示变量名称和变量值,不可省略

__get():当程序调用一个未定义或不可见的成员变量时,可以通过__get()方法来读取变量值。__get()方法有一个参数,表示要调用的变量名

class PhpClass{
    private $type = 'book';
    public function __get($name){
        if(isset($this->$name)){
            echo '变量'.$name.'的值为:'.$this->$name.'<br/>';
        }else{
            echo '变量'.$name.'未定义,初始化为0<br/>';
            $this->$name = 0;   //  此处会调用__set()
        }
    }
    public function __set($name,$value){
        if(isset($this->$name)){
            $this->$name = $value;
            echo '变量'.$name.'赋值为:'.$value.'<b/>';
        }else{
            $this->$name = $value;
            echo '变量'.$name.'被初始化问为:'.$value.'<b/>';
        }
    }
}
$lyc = new PhpClass();
$lyc->type = 'DIY'; //  变量type赋值为:DIY
$lyc->type;         //  变量type的值为:DIY
$lyc->name;         //  变量name未定义,初始化为0
                    //  vbvbv变量name被初始化问为:0


__call()上面介绍过了

__sleep()

__wakeup()

__toString():当使用echo或print输出对象时,将对象转化为字符串。和java中的 toString() 作用类似

如果没有__toString()方法,直接输出对象将会发生致命错误(fatal error)。输出要注意,echo或print函数后面直接跟要输出的对象,中间不要有多余的字符,否则__toString()方法不会执行。

__autoload()

没介绍的以后再介绍吧


版权声明:本文为博主原创文章,未经博主允许不得转载。

面向对象和基于对象的区别

面向对象大家都很熟悉,可是基于对象就不一定了。两个听起来好象是同一回事,而事实上它们却千差万别。基于对象是指:我们采用对象这一封装技术,将数据和操作捆绑在一起,但是并没有合理的使用多态、继承等面向对象...
  • QQ1449301756
  • QQ1449301756
  • 2015年08月13日 22:07
  • 753

面试百题001——谈谈你对面向对象编程的认识

面向对象程序设计的基本概念:面向对象, 概括地说, 就是把问题抽象为对象, 设置属性(数据) , 指定事件或处理方式(代码) 来达到目的, 强调从问题域的概念到软件程序和界面的直接映射。面向对象程序设...
  • seven_13
  • seven_13
  • 2013年08月29日 15:34
  • 4884

面向对象和面向过程的区别以及优缺点

面向过程    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。    缺...
  • SHZnt
  • SHZnt
  • 2015年12月22日 22:58
  • 15504

什么是面向对象思想

面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想是将数据作为第一位,而方法或者说是算法作为其次,这是对数据一种优...
  • chenqiuping_ls
  • chenqiuping_ls
  • 2016年12月13日 15:02
  • 9957

面向对象编程基础 二 this的用法

this可以简单的理解为当前的对象,在构造对象时可以理解为对象的第一人称“我”。this一般被分为三种用法: 1、this表示对象成员变量的引用而非函数参数变量,如下面的代码 public class...
  • xinsuixiaofeiyu
  • xinsuixiaofeiyu
  • 2014年03月12日 10:25
  • 1091

面向过程编程和面向对象编程的区别

面向过程编程 面向过程编程是一种以过程为中心的编程思想,分析出解决问题的步骤,然后用函数把这些步骤一步一步实现。面向过程编程,数据和对数据的操作是分离的。 面向对象编程 面向对象编程是将事物对象化...
  • sxh850297968
  • sxh850297968
  • 2015年04月16日 23:12
  • 4942

iOS面向对象的三大特征

一、封装 封装是对象和类概念的主要特性。它是隐藏内部实现,稳定外部接口,可以看作是“包装”。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行...
  • zhangshichi
  • zhangshichi
  • 2016年04月09日 11:35
  • 1087

javascript中的面向对象理解(一)

一、注意:提到“面向对象”这一概念,众所周知,javascript中的面向对象思想与其他的编程语言(例如:PHP、Java等)是有着很大区别的。因此,我们先复习下,传统意义上,面向对象的相关概念,以便...
  • u014516981
  • u014516981
  • 2016年10月19日 23:48
  • 1850

如何理解面向对象思想

我们学习JAVA语言必须要掌握对象和类,这样的话就可以更深层次的理解JAVA这种面向对象的程序开发理念,从而更好更快  地掌握JAVA的变成思想和方法。掌握类和对象是JAVA语言变成的基础。那么,...
  • LK764265808
  • LK764265808
  • 2016年07月08日 11:05
  • 4288

基于对象和面向对象的区别

基本上每个程序员都听过面向对象(Object-oriented)和基于对象(Object-based)这两个概念。其实这两个概念并没有很明显的界线,不过现在业界比较统一的认为只有完全具有封装、继承、多...
  • jiangxinnju
  • jiangxinnju
  • 2014年10月17日 00:00
  • 4842
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PHP--面向对象
举报原因:
原因补充:

(最多只允许输入30个字)