目录

PHP 类与对象 全解析( 一)

PHP 类与对象 全解析( 二)

PHP 类与对象 全解析(三 )

7.Static关键字

声明类成员或方法为static,就可以不实例化类而直接访问。不能通过一个对象来访问其中的静态成员(静态方法除外)。

静态成员属于类,不属于任何对象实例,但类的对象实例都能共享。
小结:

在类内部访问静态成员属性或者方法,使用 self::(没有 $ 符号),如:
 self:: $country  //类内部访问静态成员属性
 self:: myCountry()
在子类访问父类静态成员属性或方法,使用 parent::(没有 $ 符号),如:
 parent:: $country
 parent:: myCountry()
外部访问静态成员属性和方法为 类名/子类名:: ,如:
 Person::$country
 Person::myCountry()
 Student::$country
但静态方法也可以通过普通对象的方式访问

    <?php  

    Class Person{
// 定义静态成员属性
public static $country = "中国";
// 定义静态成员方法
public static function myCountry() {
// 内部访问静态成员属性
echo "我是".self::$country."人<br />";
}
}
class Student extends Person {
function study() {
echo "我是". parent::$country."人<br />";
}
}
// 输出成员属性值
echo Person::$country."<br />"; // 输出:中国
$p1 = new Person();
//echo $p1->country; // 错误写法
// 访问静态成员方法
Person::myCountry(); // 输出:我是中国人
// 静态方法也可通过对象访问:
$p1->myCountry(); // 子类中输出成员属性值
echo Student::$country."<br />"; // 输出:中国
$t1 = new Student();
$t1->study(); // 输出:我是中国人 ?>

---------------------------------------------------

8.抽象类    PHP5支持抽象类和抽象方法。

抽象类不能直接被实例化,你必须先继承该抽象类,然后再实例化子类。
      抽象类中 至少要包含一个抽象方法。如果类方法被声明为抽象的,那么其中就不能包括具体的功能实现。
      继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法;
      另外,这些方法的可见性 必须和抽象类中一样(或者更为宽松)。
      如果抽象类中某个抽象方法被声明为protected,那么子类中实现的方法就应该声明为protected或者public,而不 能定义为private。
      //抽象方法:abstract protected function getValue();
例子1

    abstract class AbstractClass{
// 定义抽象方法
abstract protected function getValue();
// 普通方法
public function printOut(){
print $this->getValue()."<br />";
}
}
class ConcreteClass extends AbstractClass{
protected function getValue(){
return "abstract ";//抽象方法的实现
}
} $class1 = new ConcreteClass;
$class1->printOut();

例子2

    abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix); // 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . "\n";
}
} class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
} public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
} class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
} public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
} $class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') ."\n"; $class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') ."\n";

/*
 * 抽象类不能直接被实例化,你必须先继承该抽象类,然后再实例化子类。
      抽象类中 至少要包含一个抽象方法。如果类方法被声明为抽象的,那么其中就不能包括具体的功能实现。
      继承一个抽象类的时候,子类必须实现抽象类中的所有抽象方法;
      另外,这些方法的可见性 必须和抽象类中一样(或者更为宽松)。
      如果抽象类中某个抽象方法被声明为protected,那么子类中实现的方法就应该声明为protected或者public,而不 能定义为private。
 *
 */

    class Person {
public $name;
public $age; function say() {
echo "my name is:".$this->name."<br />";
echo "my age is:".$this->age;
}
}

// 类的继承

    class Student extends Person {
var $school; //学生所在学校的属性 function study() {
echo "my name is:".$this->name."<br />";
echo "my shool is:".$this->school;
}
} $t1 = new Student();
$t1->name = "zhangsan";
$t1->school = "beijindaxue";
$t1->study();

---------------------------------------------------------------------

9.接口

接口定义:方法和常量值定义的集合
              通过interface来定义一个接口,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
   
 接口的特性:接口中定义的所有方法都必须是public
 
 接口的实现:一个接口可以使用implements操作符,类中必须实现接口中的所有方法,否则会报fatal错误,如果要实现多个接口,可以使用逗号来分隔多个接口的名称。

抽象类和接口的区别

接口是特殊的抽象类,也可以看做是一个模型的规范。接口与抽象类大致区别如下:

1.一个子类如果 implements 一个接口,就必须实现接口中的所有方法(不管是否需要);如果是继承一个抽象类,只需要实现需要的方法即可。
2.如果一个接口中定义的方法名改变了,那么所有实现此接口的子类需要同步更新方法名;而抽象类中如果方法名改变了,其子类对应的方法名将不受影响,只是变成了一个新的方法而已(相对老的方法实现)。
3.抽象类只能单继承,当一个子类需要实现的功能需要继承自多个父类时,就必须使用接口。
实例1:
// 声明一个'iTemplate'接口

nterface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}

// 实现接口
// 下面的写法是正确的

    class Template implements iTemplate
{
private $vars = array(); public function setVariable($name, $var)
{
$this->vars[$name] = $var;
} public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
} return $template;
}
}

实例2:
//定义接口

    interface User{
function getDiscount();
function getUserType();
}

//VIP用户 接口实现

    class VipUser implements User{
// VIP 用户折扣系数
private $discount = 0.8;
function getDiscount() {
return $this->discount;
}
function getUserType() {
return "VIP user";
}
}
class Goods{
var $price = 100;
var $vc;
//定义 User 接口类型参数,这时并不知道是什么用户
function run(User $vc){
$this->vc = $vc;
$discount = $this->vc->getDiscount();
$usertype = $this->vc->getUserType();
echo $usertype."goods Price:".$this->price*$discount;
}
} display ->run(new VipUser); //可以是更多其他用户类型

-------------------------------------------------------------

10.重载

定义:一个类中的方法与另一个方法名称相同,但参数不同
   什么情况下执行重载?  当调用当前的环境下未被定义的属性或者方法时,或者当调用当前环境下不可见的属性或方法。
  
提示:
 如果父类定义方法时使用了 final 关键字,则不允许被子类方法覆盖。

访问父类被覆盖的方法
 可以通过parent:: 符号来访问父类被覆盖的方法或成员属性:
 //PHP 重载方法 __call()

__call()(Method overloading)
为了避免当调用的方法不存在时产生错误,可以使用 __call() 方法来避免。该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去。

语法:
// __call()方法重载

    class Test{
public function __call($name,$args){
if($name== 'null' && count($args)==2 ){
$type='num';
foreach($args as $key => $val){
if(!(is_int($val) || is_float($val))){
$type= 'string';
}
}
$method=$name.ucfirst($type);
if(method_exists($this,$method),$args){
call_user_func_array(array($this,$method),$args);
}
}
}
public addNum($i,$j){
echo $i+$j;
} public addString($i,$j){
echo $i.$j;
}
}
$test =new Test();
$test->add(3,4);
$test->add(3,'4');

案例:

    class MemberTest {  

        private $data = array();//被重载的数据保存在此
public $declared = 1;/** 重载不能被用在已经定义的属性 */
private $hidden = 2; /** 只有从类外部访问这个属性时,重载才会发生 */ public function __set($name, $value) {
echo "Setting '$name' to '$value'\n";
$this->data[$name] = $value;
} public function __get($name) {
echo "Getting '$name'\n";
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
} $trace = debug_backtrace();
trigger_error(
'Undefined property via __get(): ' . $name .
' in ' . $trace[0]['file'] .
' on line ' . $trace[0]['line'],
E_USER_NOTICE);
return null;
} /** PHP 5.1.0之后版本 */
public function __isset($name) {
echo "Is '$name' set?\n";
return isset($this->data[$name]);
} /** PHP 5.1.0之后版本 */
public function __unset($name) {
echo "Unsetting '$name'\n";
unset($this->data[$name]);
} /** 非魔术方法 */
public function getHidden() {
return $this->hidden;
}
} echo "<pre>\n"; $obj = new MemberTest; $obj->a = 1;
echo $obj->a . "\n\n"; var_dump(isset($obj->a));
unset($obj->a);
var_dump(isset($obj->a));
echo "\n"; echo $obj->declared . "\n\n"; echo "Let's experiment with the private property named 'hidden':\n";
echo "Privates are visible inside the class, so __get() not used...\n";
echo $obj->getHidden() . "\n";
echo "Privates not visible outside of class, so __get() is used...\n";
echo $obj->hidden . "\n";

//属性重载:__set(),__get(),__isset(),__unset()

    class Person{
private $data =array();
function __set($name,$value){
$this->data[$name]=$value;
}
function __get($name){
return $this->data[$name];
}
}

-----------------------------------------------------------------------------------

11.对象迭代

PHP5提供了一种迭代(iteration)对象的功能,就像使用数组那样,可以通过foreach 来遍历对象中的属性

    class MyClass
{
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3'; protected $protected = 'protected var';
private $private = 'private var'; function iterateVisible() {
echo "MyClass::iterateVisible:\n";
foreach($this as $key => $value) {
print "$key => $value\n";
}
}
} $class = new MyClass(); foreach($class as $key => $value) {
print "$key => $value\n";
}
echo "\n"; $class->iterateVisible();

---------------------------------------------------------------------------

12.设计模式: 工厂模式和 单例模式,    观察者模式,命令链模式和策略模式

 命令链 模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容。每个处理程序都会自行判断自己能否处理请求。
如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序,而不影响其他处理程序。

工厂模式
    定义:工厂模式(Factory)允许你在代码执行时实例化对象。它之所以被称为工厂模式是因为它负责“生产”对象。工厂方法的参数是你要生成的对象对应的类名称。
 
工厂模式语法:

    <?php
class Example
{
public static function factory($type)
{
if (include_once 'Drivers/' . $type . '.php') {
$classname = 'Driver_' . $type;
return new $classname;
} else {
throw new Exception ('Driver not found');
}
}
}
?>

工厂模式案例:

    <?php
interface IUser{
function getName();
}
class User implements IUser{
public function __construct($id){}
public function getName(){
return "haha";
}
}
class UserFactory{
public static function Create($id){
return new User($id);
}
}
$uo =UserFactory::Create(1);
echo $uo->getName(); ?>

单例
   定义三要素:1,某个类只能有一个实例  2,必须自行创建这个实例  3,必须自行向系统提供这个实例
  
   作用: 1,如果系统中需要有一个类来全局控制某些配置信息,那么使用单例模式可以很方便的实现。
          2,使用单例模式,可以避免大量的new操作消耗资源()
          3在一个页面请求中,便于调试,因为所有的代码都集中在一个类中(如数据库操作类) 可以在类中设置钩子,输出日志,从而避免到处都是var_dump
    
单例模式(Singleton)用于为一个类生成一个唯一的对象。最常用的地方是数据库连接。 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。
单件模式是我们在开发中经常用到的一种设计模式,利用PHP5面向对象的特性,我们可以很容易的构建单件模式的应用,下面是单件模式在PHP中的几种实现方法:

    class Stat{
static $instance = NULL; static function getInstance(){
if(self::$instance == NULL){
self::$instance = new Stat();
} return self::$instance;
}
private function __construct(){
}
private function __clone(){
} function sayHi(){
return "The Class is saying hi to u ";
}
} echo Stat::getInstance()->sayHi();

这是一种最通常的方式,在一个getInstance方法中返回唯一的类实例。

对这里例子稍加修改,便可以产生一个通用的方法,只要叫道任何你想用到单件的类里,就可以了。

    class Teacher{
function sayHi(){
return "The teacher smiling and said 'Hello '";
} static function getInstance(){
static $instance; if(!isset($instance)){
$c = __CLASS__;
$instance = new $c;
}
return $instance;
}
} echo Teacher::getInstance()->sayHi();

最后一种是提供一个singleton类,然后通过调用getInstance方法,可以为任何一个类生产出一个实例来。

    class singleton{
function getInstance($class){
static $instances = array();
if(!array_key_exists($class,$instances)){
$instances[$class] = &new $class;
}
$instance = $instances[$class]; return $instance;
}
} class People{
function sayHi(){
return 'Hello i am a people?';
}
} echo "<br />";
echo singleton::getInstance('People')->sayHi();

通过这三种方法,我们可以很容易的应用单件模式,如果能够结合工厂模式,将使我们的编程变得更有条理和效率。
---------------------------------------------------------------------------------------

PHP 类与对象 全解析( 二)的更多相关文章

  1. PHP 类与对象 全解析(三)

    目录 PHP 类与对象 全解析( 一) PHP 类与对象 全解析( 二) PHP 类与对象 全解析(三 ) 13.魔术方法 定义:PHP把所有以__(两个下划线)开头的类方法当成魔术方法     __ ...

  2. PHP 类与对象 全解析( 一)

    目录 PHP 类与对象 全解析( 一) PHP 类与对象 全解析( 二) PHP 类与对象 全解析(三 ) 1.类与对象 对象:实际存在该类事物中每个实物的个体.$a =new User(); 实例化 ...

  3. PHP 类与对象 全解析方法

    1.类与对象 对象:实际存在该类事物中每个实物的个体.$a =new User(); 实例化后的$a 引用�php的别名,两个不同的变量名字指向相同的内容 封装: 把对象的属性和方法组织在一个类(逻辑 ...

  4. 你不知道的JavaScript--Item22 Date对象全解析

    本篇主要介绍 Date 日期和时间对象的操作. 1. 介绍 1.1 说明 Date对象,是操作日期和时间的对象.Date对象对日期和时间的操作只能通过方法. 1.2 属性 无: Date对象对日期和时 ...

  5. Android IPC机制全解析<二>

    在AIDL文件中并不是所有的数据类型都可以使用,AIDL支持的数据类型如下: 基本数据类型(int.long.char.boolean.double等) String和CharSequence Lis ...

  6. 一扫天下——ZXing使用全解析

    一扫天下--ZXing使用全解析 二维码如今已经烂App了,无论什么App.没有二维码就好像低人一等了. 所以,在自己的项目中集成二维码功能还是非常有必要的. 网上非常多都是基于ZXing2.3的.可 ...

  7. java代码解析二维码

    java代码解析二维码一般步骤 本文采用的是google的zxing技术进行解析二维码技术,解析二维码的一般步骤如下: 一.下载zxing-core的jar包: 二.创建一个BufferedImage ...

  8. 解析Java类和对象的初始化过程

    类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...

  9. OC分类(类目/类别) 和 类扩展 - 全解析

    OC分类(类目/类别) 和 类扩展 - 全解析   具体见: oschina -> MyDemo -> 011.FoundationLog-OC分类剖析 http://blog.csdn. ...

随机推荐

  1. MaxScript调用DotNet时命名空间的问题

    Fn GetSpecialFolder argEnumName = (DotNetClass "System.Environment").GetFolderPath (Execut ...

  2. 批处理系列(14) - 路径/时间/字符切分等DEMO操作

    结合本系列文章第一篇,看本文. 本篇熟悉操作文件路径.时间,温习字符切分. 路径 @echo off @REM @Author: xianghongai@gmail.com :GTCONTINUE @ ...

  3. php主要用于哪几方面

    1,服务端脚本,网站和web应用程序,web服务器,php解析器,web浏览器 2,命令行脚本 3,编写桌面应用程序

  4. 五,session数据写入memcached

    1,session数据通常保存在服务器端的文件中,它的默认过期时间是1440s.我们可以将session数据保存到memcached中,设定memcached的过期时间大于session过期时间即可. ...

  5. elasticsearch 5.x Delete By Query API(根据条件删除)

    之前在 2.X版本里 这个Delete By Query功能被去掉了 因为官方认为会引发一些错误 如需使用 需要自己安装插件. bin/plugin install delete-by-query 需 ...

  6. [bug] VUE 的 template 中使用 ES6 语法导致页面空白

    如果你在 template 中,使用了 es6 及以上的语法,那么,在部分ios.安卓.微信浏览器中,打开页面后显示一片空白内容.如下: <ul id="example-1" ...

  7. 本地数据库导入线上服务器的mongodb中

    更改默认端口 sudo vi /etc/mongod.conf 进入conf文件,修改port值为19999保存并退出. 重启mongodb sudo service mongod restart 进 ...

  8. [兼容]——IE 8 常见兼容性问题

    接触了一个PC端网页开发的项目,要求兼容到IE 8,遇到不少坑,在这里记录下: 1.IE8 的兼容性视图 bug描述:IE8有许多新更新,但微软为了兼容以前的IE浏览器,提出了"兼容性视图& ...

  9. iOS---GCD的三种常见用法

    1.一次性代码:dispatch_once 有时候,有些代码在程序中只要被执行一次. 整个程序运行过程中,只会执行一次. - (void)viewDidLoad { [super viewDidLoa ...

  10. iOS--MJRefresh的使用 上拉刷新和下拉加载

    1.一般使用MJRefresh 来实现上拉刷新和下拉加载功能 2.MJRefresh 下载地址:https://github.com/CoderMJLee/MJRefresh 3. MJRefresh ...