【PHP】PHP中的类与对象
面向对象并不是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 指调用的对象本身。
类中可定义属性,属性作用域,作用域可用关键字 public、private、protected 修饰,具体意义与c++相同。
另外可以使用 ClassName::class 来取得类的类型。实际上这返回的是一个带命名空间的完整路径。
比如,一下代码的输出会是:NS\ClassName
注意:
不要将类的定义分割到不同的文件或块中
为了兼容PHP4,var定义的成员变量(属性)与public具有相同的访问权限(大多数面向对象语言默认的是private)
可以动态的为类增加属性,如 $cart->newProperty = 4, $cart为类型Cart的实例,给Cart增加了newProperty属性,但这破坏了面向对象的原则,不提倡
方法也可以接受访问修饰符,默认 publicPHP 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中的类与对象的更多相关文章
- 【JAVA零基础入门系列】Day11 Java中的类和对象
今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...
- Python Cookbook(第3版)中文版:15.19 从C语言中读取类文件对象
15.19 从C语言中读取类文件对象¶ 问题¶ 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案¶ 要读取一个类文件对象的数据,你需要重复调 ...
- Java学习笔记十三:Java中的类和对象
Java中的类和对象 一:什么是对象: 总的来说就是"万物皆对象",客观存在的事物皆为对象.是计算机所关注的具体信息. 对象(object)是一件事.一个物体.一个名词,或可以获得 ...
- Java程序设计基础笔记 • 【第7章 Java中的类和对象】
全部章节 >>>> 本章目录 7.1 理解类和对象 7.1.1 对象 7.1.2 抽象与类 7.1.3 类与对象的关系: 7.2 Java中的类和对象 7.2.1 类的定义 ...
- 谈谈Delphi中的类和对象1---介绍几个概念 && 对象是一个地地道道的指针
参考:http://blog.163.com/liang_liu99/blog/static/88415216200952123412180/ 以下的介绍主要针对的是Delphi的面向对象的知识,可能 ...
- 初识python中的类与对象
这篇博客的路线是由深入浅,所以尽管图画的花花绿绿的很好看,但是请先关注我的文字,因为初接触类的小伙伴直接看类的实现可能会觉得难度大,只要耐着性子看下去,就会有一种“拨开迷雾看未来”的感觉了. 一.py ...
- JAVA编程中的类和对象
1:初学JAVA,都知道JAVA是面向对象的编程.笔者这节开始说说类和对象.(实例仅供参考,如若复制粘贴记得修改包名和类名,避免出错) 学习JAVA的快捷键,Alt+/代码补全功能,其实此快捷键启动了 ...
- python中的类,对象,方法,属性等介绍
注:这篇文章写得很好.加底纹的是我自己的理解 python中一切皆为对象,所谓对象:我自己就是一个对象,我玩的电脑就是对象,坐着的椅子就是对象,家里养的小狗也是一个对象...... 我们通过描述属性( ...
- java中的类和对象
Java中的类是一个模板,它用于描述一类对象的行为和状态. 对象则是类中的一个实例,对象有状态(属性)和行为(方法).例如一条狗就是一个对象,他的状态就是他的颜色,名字,品种:他的行为就是叫,摇尾巴, ...
随机推荐
- 凸包(Convex Hull)构造算法——Graham扫描法
凸包(Convex Hull) 在图形学中,凸包是一个非常重要的概念.简明的说,在平面中给出N个点,找出一个由其中某些点作为顶点组成的凸多边形,恰好能围住所有的N个点. 这十分像是在一块木板上钉了N个 ...
- [WinForm]平均切割图片AvgCutImage
昨天晚上下班前有朋友问我有的人的QQ空间相册的那种多个图片拼接成一张完整的图片的是怎么做到的比如像这样效果: 嘛,反正我是1000%不会使用这样封面来做网络相册的封面,因为用户体验实在是太差了.完全不 ...
- &&和||的那点事儿
以前一直以为&&和||的运算结果就是布尔值,但今天看到一段代码又填补的一些知识漏洞. var a = (1&&2&&5) || 3; console.l ...
- Spring Cloud 开门见山
Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性toke ...
- 慕课网-安卓工程师初养成-4-11 Java循环跳转语句之 break
来源:http://www.imooc.com/code/1431 生活中,我们经常会因为某些原因中断既定的任务安排.如在参加 10000 米长跑时,才跑了 500 米就由于体力不支,需要退出比赛.在 ...
- AX2012全新的批处理方式
AX2009 的批处理操作我们是通过RunBaseBatch framework,我们所要做的事情就是继承RunBaseBatch class,实现里面该实现的方法来执行批处理. AX2012 的批处 ...
- USACO Section 3.2 香甜的黄油 Sweet Butter
本题是多源最短路问题 但使用弗洛伊德算法会超时 而因为边数目比较少 所以用队列优化后的迪杰斯特拉算法可以通过 #include<iostream> #include<cstring& ...
- 洛谷P2751 [USACO4.2]工序安排Job Processing
P2751 [USACO4.2]工序安排Job Processing 18通过 78提交 题目提供者该用户不存在 标签 难度普及+/提高 提交 讨论 题解 最新讨论 暂时没有讨论 题目描述 一家工 ...
- 再看.net本质(二)
3.[HTTP协议] 当浏览器寻找到Web服务器的地址之后,浏览器将帮助我们把对服务器的请求转换为一系列参数发送给Web服务器.服务器收到浏览器的请求对数之后,将会分析这些数据并进行处理,然后向浏览 ...
- h5 吸顶效果 顶部悬浮
window.onscroll = function(){ var scrollTop = document.documentElement.scrollTop || document.body.sc ...