面向对象程序设计的来源得自于人们看待电话、汽车这些物体的想法。不少程序设计者在讨论面向对象程序设计的时候喜欢用“包装”或者“继承”这些让通常人疑惑不解的词语。咱们能够把面向对象这个概念和天然物体联系起来去理解它的原理。让咱们拿交通工具来作个比方。 设计图 为了构建交通工具咱们须要一份设计图。这份设计图能够定义交通工具的车轮的数量、颜色等等。一种交通工具经过必定的属性和行为来定义。在PHP中这些属性和行为就叫作变量和方法(函数)。描述一个对象的一组变量和方法就构成了一个“类”。 扩展的设计图 由于有各类不一样类型的交通工具,好比汽车、自行车和摩托车。咱们须要一种方法,它可让咱们为各类交通工具增长新功能的同时也可使用交通工具的通常性的方法,换句话说,由于“履带”要用在全部类型的交通工具上面,咱们不须要再从新编写这种方法。咱们可以“继承”来完成这个功能。假如咱们建立一个从“交通工具”继承过来的“汽车”的类,全部在“交通工具”类中的方法将被“汽车”类继承。 抽象 抽象的目的只关注于一个复杂对象的部分性质,为了解决你的问题须要你去构建一个考究的对象。你能够很容易的获得一辆汽车成千上万的属性,可是若是你须要设计一个程序去保存一个汽车经销商的目录,那么你应该只须要一个包含10多个属性的子集。这样一辆汽车被抽象成一个适合编程使用的汽车对象. 包装 包装能够隐藏一组方法的内容工具机制而只提供给用户一个定义良好的借口。在面向对象程序编程中,包装使得对象的数据结构和方法组合在一块儿。最容易理解“包装”的方式能够参考电话机。当今消费者能够购买各式各样的电话机,虽然这些电话机的内部设计方法可能不一样,可是全部这些电话机器都可以经过一个标准的公共接口通信。这就是包装的思想. 一个类能够定义新数据类型。PHP自己具备变量类型,好比字符串变量和浮点类型变量。可是经过类你能够设计本身的数据类型好比船、用户参考手册和数据库等等。一个类定义这种数据类型的属性和行为(成员变量和方法)。下面的例子显示如何定义一个包含属性和方法的类。 让咱们看一下咱们的交通工具的实际的例子 <?php /* ** 如何定义一个类 */ class Class_Name { [var 变量定义] [Function 方法定义] } ?> ----------交通工具类------------ <?php class vehicle { /* ** 属性 */ var $property1; var $property2; var $property3; /* ** 方法 */ function setTires($type) { if ($type == \"Firestone\") { $this->property1 = \"Must be a Ford SUV\"; } } function color($col) { $this->property2 = $col; } } ?> 如何使用定义好的类 类定义好之后,咱们就能够创建它的实例。为了使用刚才的例子,咱们在下面建立一个“交通工具”类的实例。 <?php $myCar = new vehicle(); $myCar->setTires(\"Firestone\"); ?> 使用类中的变量 最大的不一样点在于使用一个对象和对象拥有的值的种类。一个字符串变量却是很容易理解,由于它拥有一个值。 $myStr = \"PHP stands for... uh.. i forget\"; 然而一个对象能够拥有任何种类的值 $myCar->year = 1988; $myCar->value = 813.77; $myCar->hasAirbag = false; $myCar->color = \"periwinkle\"; 在PHP中,一个对象的全部成员变量默认是公有的。没有办法能够强迫一个对象的访问属性,可是若是但愿一个变量是私有变量的话,咱们能够用一种强调的方式来实现。 $this pointer 若是你想调用一个对象的方法,你可使用 \'$this\'来调用此对象指定实例的成员变量。刚开始,你可能对这个有点不理解,让咱们来看个例子。首先,假设你有两辆汽车。 $myCar = new vehicle(); $spousesCar = new vehicle(); 如今你有了同一个类的两个对象。你可能也听过这样的说法,“如今你有了同一个用户定义变量类型的两个综合变量”。 These are just different ways of talking about the same OOP concepts. 每一个变量,$myCar 和 $spousesCar, 拥有这个类的独立的一套属性。 $myCar->property1; //这两个是不一样的 $spousesCar->property1; //即便property1只在类定义中出现一次。你必须清楚,它仅仅是为了构成一个新数据类型而设计的。 可是在这个类内只有一个setTires()函数。当咱们使用下面的语句的时候,它如何了解是谁调用了它呢? $myCar->setTires(\"Firestone\"); 呵呵,如今这个$this就起做用了。在一个指定对象调用类内部的函数时候,这个对象就自动做为一个参数传递。用$this是出于方便的须要。看看下面的例子你应该能够理解。 $myCar->setTires(\"Firestone\"); /* ** 方法 */ function setTires($type) { if ($type == \"Firestone\") { $this->property1 = \"Must be a Ford SUV\"; } } //$this 表明 $myCar 变量 $spousesCar->setTires(\"Goodyear\"); /* ** 方法 */ function setTires($type) { if ($type == \"Firestone\") { $this->property1 = \"Must be a Ford SUV\"; } } //如今它就表明 $spousesCar. 建立一个构造器 在一个类的实例被建立之后,若是开发者但愿能有一个“默认”的函数能够调用,该怎么办呢?这就是要用到“构造器” 其实你只须要简单的将构造器的名字定义为类的名字就能够实现。如今你每次建立这个类的对象的时候,这个构造器方法将被调用。 类的继承 咱们之前说过,一个类能够继承另外一个类;可是咱们如何利用这种功能呢?在一个系统中,许多变量起相同的做用,仅仅一些的做用有些不一样,继承是很是有用的。继承是一种方法,经过这种方法,一个类能够用另一个类做为模板来创建自身。继承类将把在被继承类中定义的成员变量和方法继承过来。经过延伸或者继承过来的类叫作子类。被继承类的叫作超类或父类。这样可使类之间的做用不一样而且不会影响现存的代码.如今让咱们看个例子。 class Airplane { var $tirePressure; var $fuelLevel; var $passengerLimit; function takeOff() { ... } function land() { ... } function preFlightCheck() {} } class sevenFortySeven extends Airplane { function preFlightCheck() { //747飞机起飞预备工做 } } class biplane extends Airplane { function preFlightCheck() { //双翼飞机起飞预备工做 } } $planeArray[] = new biplane(); $planeArray[] = new sevenFortySeven(); $planeArray[] = new sevenFortySeven(); $planeArray[] = new biplane(); for ($x = 0; $x < count($planeArray); $x++) { $currentPlane = $planeArray[$x]; if ($currentPlane->preFlightCheck() ) { $currentPlane->takeOff(); //不论是什么型号的飞机,它都会知道它要起飞了 } else { print \"飞机出了点问题.\"; } } 类的静态方法 当处理一个类的对象的时候,你可能放一个对这个对象有用的函数在这个类中,而不是再另写一个特殊类。这样的函数叫作静态方法。一个良好 类应该包含全部有用的(utility)函数。 class Money { function addTax($amount,$percent){ return $amount + ($amount * $percent); } function convertCurrency ($amount, $from, $to) { //在数据库中查找一个从$from变换到$to的转换率 return $amount * $rate; } } $total = Money::addTax($subtotal,6.5); $yen = Money::convertCurrency ($usd, \"america\", \"japan\"); 方法工厂(Factory Methods) 有时候将代码分红一个一个的块去建立对象颇有好处。你可使用大量的类,也可使用一个类来决定对象使用工厂类(factory methods)。 工厂类能够帮助你有效的组织你的代码。通常状况下,工厂类包含一个比较大的转换声明而且返回一个合适的对象的实例。让咱们看个有关C扫描 仪的例子。有一个Item基本类, 可是也有不少子类,这些子类能够为各类各样的产品调用(好比电子类的, 服装类的...)。 Class Item { var $price; var $isTaxable; var $properties; function getNewItem($upc) { //链接到数据库 //查找$upc的类型并将其放入$type变量中 //查找$upc的属性并将其放如$attrib变量中; return new $type($attrib); } } class produce extends Item { function produce ($a) { $this->properties = $a; } function requiresScale() { return true; } } class hardlines extends Item { function hardlines ($a) { $this->properties = $a; } function requiresSclae() { return false; } } while ( $upc = $scanner->next_code() ) { //假设有一个扫描仪的类 $z = Item::getNewItem($upc); if ($z->requiresScale() ) { echo \"须要尺寸!\"; } $subtotal += $z->properties[\"price\"]; }