基础
子类没有定义构造方法,实例化时自动调用父类的构造方法

一个子类可以使用parent关键字访问父类,而不是用其类名
从当前类(不是子类)访问静态方法,属性,可以使用self,self指向当前类,就像伪变量$this指向当前类一样。
常量属性 使用关键词 const
const AVALIABLE = 0; // 常量不使用$开头,按惯例只能使用大写字母来命名。
常量属性只能通过类,不能通过类的示例访问
print ShopProduct::AVALIABLE;
大多数情况下抽象类至少包含一个抽象方法。
<?phpabstract class ShopProductWriter{protected $products = [];public function addProduct(ShopProduct $shopProduct){$this->products[] = $shopProduct;}abstract function writer();}
抽象类的每一个子类都必须实现抽象类的所有抽象方法或者把它们自身声明为抽象类,
子类方法访问权限不能低于父类的访问权限
接口
<?phpinterface Chargeable{public function getPrice();public function getPrice2();}abstract class A implements Chargeable{}class B implements Chargeable{public function getPrice(){}public function getPrice2(){}}
任何实现接口的类都得实现接口中定义的所有方法,否则该类必修声明为abstract


拦截器
接口
<?phpclass ShopProduct implements Chargeable{private $title;private $producerMainName;private $producerFirstName;protected $price;private $discount = 0;public function __construct($title, $firstName, $mainName, $price) {$this->title = $title;$this->producerFirstName = $firstName;$this->producerMainName = $mainName;$this->price = $price;}public function getProductFirstName(){return $this->producerFirstName;}public function getProductMainName(){return $this->producerMainName;}public function setDiscount($num){$this->discount = $num;}public function getDiscount(){return $this->discount;}public function getTitle(){return $this->title;}public function getPrice(){return ($this->price - $this->discount);}public function getProducer(){return "{$this->producerFirstName}" ."{$this->producerMainName}";}public function getSummeryLine(){$base = "{$this->title}({$this->producerFirstName}";$base .= "{$this->producerFirstName})";return $base;}}class CdShopProduct extends ShopProduct{private $playLength = 0;public function __construct( $title, $firstName, $mainName, $price, $playLength ) {parent::__construct( $title, $firstName, $mainName, $price );$this->playLength;}public function getPlayLength(){$this->playLength;}public function getSummeryLine() {$base = parent::getSummeryLine(); // TODO: Change the autogenerated stub$base .= ": playingtime - {$this->playLength}";return $base;}}class BookProduct extends ShopProduct{private $numPage = 0;public function __construct( $title, $firstName, $mainName, $price, $numPage ) {parent::__construct( $title, $firstName, $mainName, $price );$this->numPage = $numPage;}public function getNumberOfPage(){$this->numPage;}public function getSummeryLine() {$base = parent::getSummeryLine(); // TODO: Change the autogenerated stub$base .= ": page count - {$this->numPage}";}public function getPrice() {return $this->price; // TODO: Change the autogenerated stub}}abstract class ShopProductWriter{protected $products = [];public function addProduct(ShopProduct $shopProduct){$this->products[] = $shopProduct;}abstract function writer();}class XmlProductWriter extends ShopProductWriter {public function writer() {// TODO: Implement writer() method.var_dump($this->products);}}class TextProductWriter extends ShopProductWriter{public function writer() {// TODO: Implement writer() method.}}interface Chargeable{public function getPrice();}
抽象类
<?phpabstract class DomainObject{private $group;public function __construct() {$this->group = static::getGroup();}public static function create(){return new static();}static function getGroup(){return "default";}}class User extends DomainObject{}class Document extends DomainObject{static function getGroup() {return "document";}}class SpreadSheet extends Document {}//print_r(User::create());//print_r(SpreadSheet::create());
拦截器
/***__get __set***/<?phpclass Person{private $_name;private $_age;function __get( $property ) {// TODO: Implement __get() method.$method = "get{$property}";if (method_exists($this, $method)) {return $this->$method();}return false;}function __set( $name, $value ) {// TODO: Implement __set() method.$method = "set{$name}";if (method_exists($this, $method)) {return $this->$method($value);}return false;}function getName(){return "Bob";}function getAge(){return "44";}function setName($name){$this->_name = $name;if (is_null($name)) {$this->_name = strtoupper($this->_name);}}function setAge($age){$this->_age = strtoupper($age);}}$person = new Person();print $person->Age;$person->name = "bob";var_dump($person);//////////////////////**__call***/<?phpclass PersonWriter {function writeName(Person $p) {print $p->getName().'\n';}function writeAge(Person $p) {print $p->getAge().'\n';}}class Person {private $writer;function __construct(PersonWriter $writer) {$this->writer = $writer;}function __call( $methodname, $arguments ) {// TODO: Implement __call() method.if (method_exists($this->writer, $methodname)) {return $this->writer->$methodname($this);}}function getName() {return "Bob";}function getAge(){return 44;}}$person = new Person(new PersonWriter());$person->writeName(); // Bob
析构方法
<?php# 析构方法class Person{private $name;private $age;private $id;function __construct($name, $age) {$this->name = $name;$this->age = $age;}function setId($id){$this->id = $id;}function __destruct() {// TODO: Implement __destruct() method.if (!empty($this->id)) {// 保存person数据print "saving person" . "\n";}}}$person = new Person("Martin", 54);$person->setId(12);unset($person); // 输出saving person
复制
<phpclass CopyMe{}class CopyMe{}$first = new CopyMe();$second = $first; // 引用$third = clone $first; // 赋值var_dump($second === $first); // truevar_dump($third === $first); // false
包含路径
把包放在include_path指向引用的目录,就可以在系统的任何地方被引用。
自动加载
call_user_func
反射
$prod_class = new ReflectionClass(‘CdShopProduct’);
Reflection::export($prod_class);
Class [
@@ E:\WWW\test\php_obj\ShopProduct.php 60-77
- Constants [0] {
}
- Static properties [0] {
}
- Static methods [0] {
}
- Properties [2] {
Property [
Property [
}
- Methods [10] {
Method [
@@ E:\WWW\test\php_obj\ShopProduct.php 63 - 66
- Parameters [5] {
Parameter #0 [
Parameter #1 [
Parameter #2 [
Parameter #3 [
Parameter #4 [
}
} …

多态
四个方向(避免)
5 关联



6 聚合和组合



聚合 删除容器 被包含的对象可以归入另一个容器,而组合 删除容器,容器包含的对象也要被删除。
7 描述使用


8 使用注释
设计模式
组合与继承
使用组合
<?phpabstract class Lesson{private $duration;private $costStrategy;function __construct($duration, CostStrategy $strategy) {$this->duration = $duration;$this->costStrategy = $strategy;}function cost(){return $this->costStrategy->cost($this);}function chargeType(){return $this->costStrategy->chargeType();}function getDuration(){return $this->duration;}// Lesson 类的更多方法}class Lecture extends Lesson{// lecture 特定实现public function __construct( $duration, CostStrategy $strategy ) {parent::__construct( $duration, $strategy );}}class Seminar extends Lesson{public function __construct( $duration, CostStrategy $strategy ) {parent::__construct( $duration, $strategy );}}abstract class CostStrategy{abstract function cost(Lesson $lesson);abstract function chargeType();}class TimedCostStrategy extends CostStrategy{public function chargeType() {// TODO: Implement chargeType() method.return "hourly rate";}public function cost( Lesson $lesson ) {// TODO: Implement cost() method.return ($lesson->getDuration() * 5);}}class FixedCostStrategy extends CostStrategy{public function cost( Lesson $lesson ) {// TODO: Implement cost() method.return 30;}public function chargeType() {// TODO: Implement chargeType() method.return "fixed rare";}}$lessons[] = new Seminar(4, new TimedCostStrategy());$lessons[] = new Lecture(4, new FixedCostStrategy());foreach ($lessons as $lesson) {print "lesson change {$lesson->cost()} ";print "charge type {$lesson->chargeType()}\n";}======输出======lesson change 20 charge type hourly ratelesson change 30 charge type fixed rare
降低耦合
<?phpclass RegistrationMgr{function register(Lesson $lesson){// 处理该课程// 通知某人$notifier = Notifier::getNotifier();$notifier->inform("new lesson cost ({$lesson->cost()})");}}abstract class Notifier{static function getNotifier(){// 根据匹配或其他逻辑获得具体的类if (1 == rand(1, 2)) {return new MailNotifier();} else {return new TextNotifier();}}abstract function inform($message);}class MailNotifier extends Notifier{public function inform( $message ) {// TODO: Implement inform() method.print "Mail notification: {$message}\n";}}class TextNotifier extends Notifier{public function inform( $message ) {// TODO: Implement inform() method.print "Text notification: {$message}\n";}}$lessons1 = new Seminar(4, new TimedCostStrategy());$lessons2 = new Lecture(4, new FixedCostStrategy());$mgr = new RegistrationMgr();$mgr->register($lessons1);$mgr->register($lessons2);====输出====Text notification: new lesson cost (20)Mail notification: new lesson cost (30)
针对接口编程,而不是针对实现编程
<?php/*** Created by PhpStorm.* User: TF* Date: 2019/2/25* Time: 14:02*/abstract class Employee{protected $name;function __construct($name) {$this->name = $name;}abstract function fire();}class Minion extends Employee{public function fire() {// TODO: Implement fire() method.print "{$this->name}: I'll clear my desk\n";}}class NastyBoss{private $employees = [];function addEmployee($employeeName){$this->employees[] = new Minion( $employeeName );}function projectFails(){if (count($this->employees) > 0) {$emp = array_pop($this->employees);$emp->fire();}}}$boss = new NastyBoss();$boss->addEmployee("tom");$boss->addEmployee("lucy");$boss->addEmployee("marry");$boss->projectFails(); // marry: I'll clear my desk

多态存在的三个必要条件
1 继承
2 重写
3 父类引用指向子类对象
单例模式
<?phpclass Preference{private $props = [];private static $instance;private function __construct() {}public static function getInstance(){if (empty(self::$instance)) {self::$instance = new Preference();}return self::$instance;}public function setProperty($key, $val){$this->props[$key] = $val;}public function getProperty($key){return $this->props[$key];}}$pref = Preference::getInstance();$pref->setProperty("name", "marry");unset($pref); // 移除引用$pref2 = Preference::getInstance();print $pref2->getProperty("name") . "\n"; // 该属性值并未丢失


工厂方法模式
<?phpabstract class AppEncoder{abstract function encode();}class BloggsAppEncoder extends AppEncoder{public function encode() {// TODO: Implement encode() method.return 'b';}}class MegaAppEncoder extends AppEncoder{public function encode() {// TODO: Implement encode() method.return 'm';}}abstract class CommsMannager{abstract function getHeaderText();abstract function getAppEncoder();abstract function getFooterText();}class BloggsCommsMannager extends CommsMannager {public function getAppEncoder() {// TODO: Implement getAppEncoder() method.return new BloggsAppEncoder();}public function getFooterText() {// TODO: Implement getFooterText() method.return "blogs footer\n";}public function getHeaderText() {// TODO: Implement getHeaderText() method.return "blogs header\n";}}$bloggscomms = new BloggsCommsMannager();$bloggscomms->getAppEncoder();




抽象工厂模式
<?phpabstract class CommsManager{abstract function getHeaderText();abstract function getAppEncoder();abstract function getTtdEncoder();abstract function getContactEncoder();abstract function getFooterText();}abstract class ApptEncoder{abstract function encode();}abstract class TtdEncoder{abstract function encode();}abstract class ContactEncoder{abstract function encode();}//class BloggsApptEncoder extends ApptEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsTtdEncoder extends TtdEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsContactEncoder extends ContactEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsCommsManager{public function getHeaderText(){return "header\n";}public function getAppEncoder(){return new BloggsApptEncoder();}public function getTtdEncoder(){return new BloggsTtdEncoder();}public function getContactEncoder(){return new BloggsContactEncoder();}public function getFooterText(){return "footer\n";}}



<?phpabstract class CommsMannager{const APPT = 1;const TTD = 2;const CONTACT = 3;abstract function getHeaderText();abstract function make($flag_int);abstract function getFooterText();}abstract class ApptEncoder{abstract function encode();}abstract class TtdEncoder{abstract function encode();}abstract class ContactEncoder{abstract function encode();}//class BloggsApptEncoder extends ApptEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsTtdEncoder extends TtdEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsContactEncoder extends ContactEncoder{public function encode() {// TODO: Implement encode() method.}}class BloggsCommsManager extends CommsMannager{public function getHeaderText() {// TODO: Implement getHeaderText() method.}public function make($flag_int) {// TODO: Implement getAppEncoder() method.switch ($flag_int) {case self::APPT:return new BloggsApptEncoder();break;case self::CONTACT:return new BloggsContactEncoder();break;case self::TTD:return new BloggsTtdEncoder();break;}}public function getFooterText() {// TODO: Implement getFooterText() method.return "footer";}}
原型模式



<?php// 海class Sea{}// 平原class Plains{}// 森林class Forest{}/**地球的海,平原,森林**/class EarthSea extends Sea{}class EarthPlains extends Plains{}class EarthForest extends Forest{}/**火星的海,平原,森林**/class MarsSea extends Sea{}class MarsPlains extends Plains{}class MarsForest extends Forest{}// 抽象工厂 原型模式class TerrainFactory{private $sea;private $plains;private $forest;function __construct(Sea $sea, Plains $plains, Forest $forest) {$this->sea = $sea;$this->plains = $plains;$this->forest = $forest;}function getSea(){return clone $this->sea;}function getPlains(){return clone $this->plains;}function getForest(){return clone $this->forest;}}$factory = new TerrainFactory(new EarthSea(), new MarsPlains(), new EarthForest());print_r($factory->getSea());print_r($factory->getPlains());print_r($factory->getForest());// 地球//class EarthTerrainFactory extends TerrainFactory{// public function getForest() {// // TODO: Implement getForest() method.// }// public function getPlains() {// // TODO: Implement getPlains() method.// }// public function getSea() {// // TODO: Implement getSea() method.// }//}////// 火星//class MarsTerrainFactory extends TerrainFactory{// public function getSea() {// // TODO: Implement getSea() method.// }// public function getPlains() {// // TODO: Implement getPlains() method.// }// public function getForest() {// // TODO: Implement getForest() method.// }//}

<?php// 如果产品对象引用了其他对象,应该实现__clone()方法 确保得到的是深复制class Contained{}class Container{public $contained;public function __construct() {$this->contained = new Contained();}public function __clone() {// TODO: Implement __clone() method.// 确保被克隆的对象持有的是self::$contained的克隆而不是引用$this->contained = clone $this->contained;}}$c = new Container();var_dump($c->contained);
<?phpSetting.phpclass Settings{static $COMMSTYPE = 'Bloggs';}_______________require_once "Setting.php";class Appconfig{private static $instance;private $commsManager;private function __construct() {// 仅运行一次$this->init();}private function init(){switch (Settings::$COMMSTYPE) {case 'Mega':$this->commsManager = new MegaCommsManager();break;default:$this->commsManager = new BloggsCommsMannager();}}public static function getInstance(){if (empty(self::$instance)) {self::$instance = new self();}return self::$instance;}public function getCommsManager(){return $this->commsManager;}}

$commsMgr = Appconfig::getInstance()->getCommsManager();$commsMgr->getAppEncorder()->encode();
组合
组合优于继承





