面向对象并不是PHP的关键,但PHP确实能很好的支持面向对象编程,而且类与对象也成为了PHP5的核心组成部分。PHP的面向对象特性让构建大型的复制应用成为可能,有了类与对象,就自然产生了各种编程范式和层出不穷的编程框架。今天我们来研究PHP中的类和对象。

1 类的定义

先来一段官方的代码说明类的构成

<?php
class SimpleClass
{
// property declaration
public $var = 'a default value'; // method declaration
public function displayVar() {
echo $this->var;
}
}
?>
 

定义类的关键字是 class,这与其他语言没什么区别。类可以有变量,有方法,使用 this 访问对象自己。类的静态方法中 this 指调用的对象本身。
类中可定义属性,属性作用域,作用域可用关键字 publicprivateprotected 修饰,具体意义与c++相同。
另外可以使用 ClassName::class 来取得类的类型。实际上这返回的是一个带命名空间的完整路径。
比如,一下代码的输出会是:NS\ClassName

注意:

不要将类的定义分割到不同的文件或块中

为了兼容PHP4,var定义的成员变量(属性)与public具有相同的访问权限(大多数面向对象语言默认的是private)

可以动态的为类增加属性,如 $cart->newProperty = 4, $cart为类型Cart的实例,给Cart增加了newProperty属性,但这破坏了面向对象的原则,不提倡

方法也可以接受访问修饰符,默认 public

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

 
抽象类
PHP 5 支持抽象类和抽象方法。定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。 
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。此外方法的调用方式必须匹配,即类型和所需参数数量必须一致。例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则两者的声明并无冲突。 这也适用于 PHP 5.4 起的构造函数。在 PHP 5.4 之前的构造函数声明可以不一样的。
<?php
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";
?>

2 类的使用

<?php
$instance = new SimpleClass();
// 也可以这样做:
$className = 'Foo';
$instance = new $className(); // Foo()
?>

使用 new 创建对象,使用 -> 访问对象的属性和方法。PHP5中类为引用传递。

3 自动加载类

尝试加载未定义的类php5中可以使用 autoload() 函数,它在试图使用尚未被定义的类时自动加载。一般用于动态加载未引用的文件。

<?php
function __autoload($class_name) {
require_once $class_name . '.php';
} $obj = new MyClass1();
$obj2 = new MyClass2();
?>

如果每个类都分布于同名文件中,该函数可以使php自动的加载类对应的文件。

spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

<?php

// function __autoload($class) {
// include 'classes/' . $class . '.class.php';
// } function my_autoloader($class) {
include 'classes/' . $class . '.class.php';
} spl_autoload_register('my_autoloader'); // 或者,自 PHP 5.3.0 起可以使用一个匿名函数
spl_autoload_register(function ($class) {
include 'classes/' . $class . '.class.php';
}); ?>
 
 

4 构造函数于析构函数

构造函数

void __construct ([ mixed $args [, $... ]] )

具有构造函数的类会在每次创建新对象时先调用此方法。但要注意的是,在子类的显式构造函数中默认不会调用父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。子类没有构造函数,则默认调用父类的构造函数。

旧式的构造函数是一个与类名相同的函数,建议在代码用不使用。自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。

与其它方法不同,当 __construct() 被与父类 __construct() 具有不同参数的方法覆盖时,PHP 不会产生一个 E_STRICT 错误信息。

析构函数

void __destruct ( void )

PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。

试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。

在析构函数中调用 exit() 将会中止其余关闭操作的运行。

5 继承

一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。
被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。
可以通过 parent:: 来访问被覆盖的方法或属性。
当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。

<?php
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
} class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
} class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
} // In BaseClass constructor
$obj = new BaseClass(); // In BaseClass constructor
// In SubClass constructor
$obj = new SubClass(); // In BaseClass constructor
$obj = new OtherSubClass();
?>

除非使用了自动加载,否则一个类必须在使用之前被定义。如果一个类扩展了另一个,则父类必须在子类之前被声明。此规则适用于类继承其它类与接口。

6 接口

类似于java, php使用 interface 定义接口,使用 implements 实现接口。接口可以继承多个接口。

<?php
interface a
{
public function foo();
} interface b
{
public function bar();
} interface c extends a, b
{
public function baz();
} class d implements c
{
public function foo()
{
} public function bar()
{
} public function baz()
{
}
}
?>

接口加上类型约束,提供了一种很好的方式来确保某个对象包含有某些方法。

instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例,

从php5.3,被废弃的is_a()又可以用了

<?php
class ParentClass
{
} class MyClass extends ParentClass
{
} $a = new MyClass; var_dump($a instanceof MyClass);
var_dump($a instanceof ParentClass);
?>

输出:

bool(true)

bool(true)

7 总结

php具有完整的面向对象特性,类,继承,接口给了我们充分的发挥空间,利用这些特性,我们可以轻松的完成各种任务挑战。

【PHP】PHP中的类与对象的更多相关文章

  1. 【JAVA零基础入门系列】Day11 Java中的类和对象

    今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...

  2. Python Cookbook(第3版)中文版:15.19 从C语言中读取类文件对象

    15.19 从C语言中读取类文件对象¶ 问题¶ 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案¶ 要读取一个类文件对象的数据,你需要重复调 ...

  3. Java学习笔记十三:Java中的类和对象

    Java中的类和对象 一:什么是对象: 总的来说就是"万物皆对象",客观存在的事物皆为对象.是计算机所关注的具体信息. 对象(object)是一件事.一个物体.一个名词,或可以获得 ...

  4. Java程序设计基础笔记 • 【第7章 Java中的类和对象】

    全部章节   >>>> 本章目录 7.1 理解类和对象 7.1.1 对象 7.1.2 抽象与类 7.1.3 类与对象的关系: 7.2 Java中的类和对象 7.2.1 类的定义 ...

  5. 谈谈Delphi中的类和对象1---介绍几个概念 && 对象是一个地地道道的指针

    参考:http://blog.163.com/liang_liu99/blog/static/88415216200952123412180/ 以下的介绍主要针对的是Delphi的面向对象的知识,可能 ...

  6. 初识python中的类与对象

    这篇博客的路线是由深入浅,所以尽管图画的花花绿绿的很好看,但是请先关注我的文字,因为初接触类的小伙伴直接看类的实现可能会觉得难度大,只要耐着性子看下去,就会有一种“拨开迷雾看未来”的感觉了. 一.py ...

  7. JAVA编程中的类和对象

    1:初学JAVA,都知道JAVA是面向对象的编程.笔者这节开始说说类和对象.(实例仅供参考,如若复制粘贴记得修改包名和类名,避免出错) 学习JAVA的快捷键,Alt+/代码补全功能,其实此快捷键启动了 ...

  8. python中的类,对象,方法,属性等介绍

    注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...

  9. java中的类和对象

    Java中的类是一个模板,它用于描述一类对象的行为和状态. 对象则是类中的一个实例,对象有状态(属性)和行为(方法).例如一条狗就是一个对象,他的状态就是他的颜色,名字,品种:他的行为就是叫,摇尾巴, ...

随机推荐

  1. Laxcus大数据管理系统2.0(10)- 第八章 安全

    第八章 安全 由于安全问题对大数据系统乃至当前社会的重要性,我们在Laxcus 2.0版本实现了全体系的安全管理策略.同时我们也考虑到系统的不同环节对安全管理的需求是不一样的,所以有选择地做了不同的安 ...

  2. Weblogic发布小问题——The root element weblogic-web-app is missing in the descriptor file

    前几天发布项目遇到这样一个小错误,在此记录一下,以便加深一点印象,下次好解决类似的问题! (对应的应用服务器是WebLogic Server 版本: 10.3.6.0,应用是以文件夹的形式发在服务器的 ...

  3. ICDM 2007

    Language-Independent Set Expansion of Named Entities Using the Web. Chao Wang, Venu Satuluri, Sriniv ...

  4. extern 相关

    假如a.h中有 int a=10; t1.cpp和t2.cpp同时include "a.h"则编译不成功,因为a重复定义:如果 a.h中是 static int a=10;则可以, ...

  5. WPF学习系列之八(形状,画刷和变换)

    形状,画刷和变换   概述: 在许多用户界面技术中,普通控件和自定义绘图之间具有清晰的区别.通常来说,绘图特性只用于特定的应用程序--如游戏,数据可视化和物理仿真等.而WPF具有一个非常不同的原则.它 ...

  6. 浅谈 cookie 和 session

    1.关闭浏览器后,session是否还存在? session在服务器和客户端各保留一个副本,关闭浏览器与否和session是否存在没有任何关系. session采取的是服务器端保持状态的方案,它存储在 ...

  7. 讲解DLL内容的比较详细的站点

    1.通过 Visual Studio 2008 用C语言创建和调用DLL : http://blog.chinaunix.net/uid-631975-id-116622.html 2.DLL(Dyn ...

  8. What is the behavior of lnk files?

    I access a files which name is "abc.doc", no doubt a lnk file "abc.doc.lnk" show ...

  9. Sunglasses

    It's hot this summer. It also reminds me of one case about sunglasses. She was new to this company a ...

  10. 生成.a文件步骤

    1.新建一个Project 选择 iOS->Framework & Library ->Cocoa Touch Static Library点击Next-> 输入Produc ...