您的位置:首页 > 编程语言 > PHP开发

php面向对象你懂得

2011-09-12 20:46 239 查看

1 面向对象编程的特点

1.1 封装性:

将一个类的使用和实现分开,只保留有限的接口(方法)与外部联系。对于使用该类的开发人员,只要知道这个类该如何使用即可,而不可关心这个类是如何实现的。这样做可以让开发人员更好的把精力集中在其他事情上,同时也避免了程序之间的相互依赖而带来的不便。

1.2 继承性:

派生类(子类)自动继承一个或多个基类(父类)中的属性和方法,并可以重写或添加新的属性和方法。继承性简化了对象和类的创建,增强了代码的可重用性。

1.3 多态性

用一个类的不同对象使用同一个方法可以获得不同的结果。多态性增强了软件的灵活性和重用性。

2 类的声明

2.1 类的定义

和很多面向对象的语言一样,php也是通过class关键字加类名来定义类的。类的格式如下:

<?php

权限修饰符 class 类名{

类体;

}

?>

权限修饰符是可选项,可是public、protected、private或者省略这3者。

Class是创建类的关键字

类名是所要创建类的名称,它必须写在class关键字之后,在类的名称后面必须跟上一对大括号。

类体是类的成员,类体必须放在类名后面的两个大括号{ }之间。

<?php

Class ConnDB{

}

?>

2.2 成员属性

在类中直接声明的变量称为成员属性(也可以称为成员变量)。可以在类中声明多个变量,即对象中有多个成员属性,每个变量都存储对象不同的属性信息。

成员属性的类型可以是php中的标量类型和复合类型,使用资源和空类型是没有意义的。

成员属性的声明必须有关键字来修饰,例如,public, protected, private 等,这是具有特定意义的关键字。如果不需要有特定意义,那么可以使用var关键字来对它进行修饰。还有就是在声明成员属性时没有必要赋初始值。

<?

Class ConnDB{

Var $dbtype;

Var $host;

Var $user;

Var $pwd;

Var $dbname;

Var $debug;

Var $conn;

}

?>

成员常量就是不会改变的量,是一个恒值,例如,圆周率就是众所周知的一个常量,在类中定一个常量时使用关键字const,例如,定义一个圆周率常量。

const PI = 3.1415926;

常量的输出不需要实例化对象,直接由类名+常量名调用即可。常量输出的格式为:

类名::常量名

类名和常量名之间的两个冒号::称为作用域操作符,使用这个操作符可以在不创建对象的情况下调用类的常量、变量和方法。

2.3 成员方法

在类中声明的函数称为成员方法,在一个类中可以声明多个函数,即对象中可以有多个成员方法。成员方法的声明和函数的声明相同,唯一特殊之处是成员方法可以有关键字对它进行修饰,从而控制成员方法的权限。

3 类的实例化

3.1 创建对象

类的实例化格式如下:

$变量名 = new 类名称([参数]);

3.2 访问类中的成员

类中包括成员属性和成员方法,访问类中的成员包括成员属性和方法的访问。访问方法于访问数组中的元素类似,需要通过对象的引用来访问类中的每个成员。其中还要应用到一个特殊的运算符号”->”。访问类中成员的语法格式如下:

$var = new ClassName();

$var->name = “zhanghai”;

$var->name;

$var->getDBConn();

<?php

class ConnDB{

var$dbtype;

var$host;

var$user;

var$pwd;

var$dbname;

var$debug;

var$conn;

functionConnDB($dbtype,$host,$user,$pwd,$dbname,$debug=false){

$this->dbtype=$dbtype;

$this->host=$host;

$this->user=$user;

$this->pwd=$pwd;

$this->dbname=$dbname;

$this->debug=$debug;

}

functionGetConnId(){

echo"<br>登陆服务器用户名: ".$this->user;

echo"<br>登陆服务器密码: ".$this->pwd;

}

functionCloseConnId(){

$this->conn->DisConnect();

}

}

header("Content-type: text/html;charset=utf-8");

$connObj = newConnDB("mysql","localhost","root","123456","tpsns",false);

echo "数据库类型".$connObj->dbtype;

echo "<br>服务器".$connObj->host;

$connObj->GetConnId();

?>

3.3 特殊的访问方法---- $this 和::

3.3.1 $this

$this存在于类的每个成员方法中,它是一个特殊的对象引用方法。成员方法属于哪个对象,$this引用就代表哪个对象,其作用就是专门完成对象内部成员之间的访问。

3.3.2 操作符::

相比$this引用只能在类的内部使用,操作符::才是真正的强大。操作符::可以在没有声明任何实例的情况下访问类中的成员。例如,在子类重载方法中调用父类中被覆盖的方法。操作符::的语法格式如下:

关键字::变量名|常量名|方法名

这里的关键字分为3种情况:

1、parent关键字:可以调用父类中的成员变量、成员方法和常量

2、self关键字:可以调用当前类中的静态成员和常量

3、类名:可以调用本类中的变量、常量和方法

<?php

class Book{

constNAME="编程宝典系列";

function__construct(){

echo"父类:".Book::NAME ;

}

}

class l_book extends Book{

constNAME = "PHP编程宝典";

function__construct(){

parent::__construct();

echo"子类:".self::NAME ;

}

}

header("Content-type: text/html;charset=utf-8");

$obj = new l_book();

?>

3.4 构造函数和析构函数

3.4.1 构造函数

构造函数是对象创建完成之后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。如果在类中没有直接声明的构造方法,那么类中会默认生成一个没有任何参数且内容为空的构造方法。

构造方法多数是执行一些初始化的任务。

构造方法的声明有两种,一种是构造方法的名称必须与类名相同;第二种是在php5版本中,构造方法的名称必须是以两个下划线开始的__construct()。

Php5中的这个变化考虑到构造函数可以独立于类名,当类名发生变化时不需要修改相应的构造函数的名称。

3.4.2 析构方法

是对象被销毁之前最后一个被对象调用的方法。他是php5中新添加的内容,用于实现在销毁一个对象之前执行一些特定的操作,如,关闭文件和释放内存等。

析构方法的声明以两个下划线开头__destruct(),析构方法没有任何参数。

Function __destruct(){

}

Php中有一种垃圾回收机制,可以自动清楚不再使用的对象以释放内存。而析构方法就是在这个垃圾回收程序执行之前被调用的方法,在php中它属于类中的可选内容。

4 封装性

面向对象编程的特点之一是封装性,它将类中的成员属性和方法结合成一个独立的相同单位,并尽可能隐藏对象的内容细节。

其目的就是确保类以外的部分不能随意存取类的内部数据(成员属性和成员方法)。从而有效避免外部错误对类内数据的影响。

类的封装是通过关键字public private protected static final实现的。

4.1 Public(公共成员)

可以公开的、没有必要隐藏的数据信息。可以在程序的任何地点(类内、类外)被其他的类和对象调用。子类可以继承和使用父类中所有的公共成员。

4.2 Private(私有成员)

被private关键字修饰的变量和方法只能在所属类的内部被调用和修改,不可以在类外被访问,即使在子类中也不可以。

4.3 Protected(保护成员)

在本类、子类中可以被访问,其他类中不可以被访问。

5 继承性

5.1 类的继承-----extends关键字

5.2 类的继承-----parent::关键字

在子类中调用父类的方法parent::getName();

5.3 覆盖父类方法

所谓覆盖父类方法,就是使用子类中的方法替换父类中继承的方法,也叫方法重写。

覆盖父类方法的关键就是在子类中创建与父类中相同的方法,包括方法名称、参数和返回值类型。

提示:当父类和子类中都定义了构造方法,且子类的对象被创建后,将调用子类的构造函数,而不会调用父类的构造函数。

6 抽象类和接口

抽象类(Abstract)和接口(Interface)都是不能被实例化的特殊类。他们都是配合面向对象的多态性一起使用。

6.1 抽象类

抽象类是一种不能被实例化的类,只能作为其他类的父类来使用。抽象类使用abstract关键字来声明,其语法格式如下:

abstract class 抽象类名{

//抽象类的成员变量列表

Abstractfunction 成员方法(参数 );

…..

}

抽象类和普通类相似,包含成员变量、成员方法。两者的区别在于抽象类至少要包含一个抽象方法。抽象方法没有方法体,其功能的实现只能在子类中完成。抽象方法也是使用abstract关键字来修饰。

6.2 接口

继承特性简化了对象和类的创建,增强了代码的可重用性。但php只支持单继承,如果想实现多继承,就要使用接口,php可以实现多个接口。

1、 接口的声明

接口类通过Interface关键字来声明,接口中声明的方法必须是抽象方法,接口中不能声明变量,只能使用const关键字声明为常量的成员属性,并且接口中的所有成员都必须具备public的访问权限。接口的语法:

interface 接口名称{

//常量成员

//抽象方法



接口和抽象类都不能进行实例化操作,需要通过子类来实现。但是接口可以直接使用接口名称在接口外获取常量成员的值。

2、 接口的应用

因为接口不能进行实例化的操作,所以如果要使用接口中的成员,就必须借助子类。在子类中继承接口需要使用implements关键字。如果要实现多个接口的继承,那么每个接口之间必须使用逗号,连接。

<?php

interface Person{

functionsetName($name);

functiongetName();

}

interface Popedom{

functionsetPopedom($popedom);

functiongetPopedom();

}

class Member implements Person ,Popedom{

private$name;

private$popedom;

functionsetName($name){

$this->name=$name;

}

functiongetName(){

echo"姓名:".$this->name;

}

functionsetPopedom($popedom){

$this->popedom=$popedom;

}

functiongetPopedom(){

echo"<br>权限:".$this->popedom;

}

}

header("Content-type: text/html;charset=utf-8");

$pop=new Member();

$pop->setName("明日帝国");

$pop->getName();

$pop->setPopedom("管理员");

$pop->getPopedom();

?>

抽象类和接口之间的区别:

1、抽象类的操作通过继承关键字extends来实现,而接口的使用是通过implements关键字来实现。

3、 抽象类中有数据成员,可以实现数据的封装,但是接口没有数据成员

4、 抽象类中可以有构造函数,但是接口没有构造函数

5、 抽象类的方法可以通过private,proected,pubic关键字来修饰,而接口中的方法只能使用public关键字来修饰

6、 一个类只能继承于一个抽象类,而一个类可以同时实现多个接口

7、 抽象类中可以有成员方法的实现代码,而接口中不可以有成员方法的实现代码。

7 多态性

在php中多态有两种实现方法,即通过继承实现多态和通过接口实现多态。

7.1 通过继承实现多态

<?php

abstract class Vehicle{

abstractfunction goTrip();

}

class Train extends Vehicle {

functiongoTrip(){

echo"坐着火车去拉萨";

}

}

class Car extends Vehicle {

functiongoTrip(){

echo"开着汽车去北京";

}

}

function printRightSelect($object){

if($object instanceof Vehicle ) {

$object->goTrip();

}else{

echo"出现错误";

}

echo"<br>";

}

header("Content-type: text/html;charset=utf-8");

echo "select one:";

$obj = new Train();

printRightSelect($obj);

echo "<br>select two:";

$obj1= new Car();

printRightSelect($obj1);

?>

7.2 通过接口实现多态

<?php

abstract class Vehicle{

abstractfunction goTrip();

}

class Train extends Vehicle {

functiongoTrip(){

echo"坐着火车去拉萨";

}

}

class Car extends Vehicle {

functiongoTrip(){

echo"开着汽车去北京";

}

}

function printRightSelect($object){

if($object instanceof Vehicle ) {

$object->goTrip();

}else{

echo"出现错误";

}

echo"<br>";

}

header("Content-type: text/html;charset=utf-8");

echo "select one:";

$obj = new Train();

printRightSelect($obj);

echo "<br>select two:";

$obj1= new Car();

printRightSelect($obj1);

?>

8 面向对象----常用关键字

8.1 final关键字

被final修饰过的类和方法就是最终的版本,如果有一个类的格式为:

final class className(){}

则说明该类不可以再被继承,也不能再有子类。

如果有方法的格式为:

final function methodName(){}

则说明该方法在子类中不可以进行重写,也不可以被覆盖。

这就是final关键字的作用。

8.2 static关键字 ---- 声明静态类成员

在php中通过static关键字修饰的成员属性和成员方法称为静态属性和静态方法。静态属性和静态方法不需要被类实例化就可以直接使用。

8.2.1 静态属性

静态属性就是使用static关键字修饰的成员属性,它属于类本身而不属于类的任何实例。它相当于存储在类中的全局变量,可以在任何位置通过类名来访问。

静态属性访问的语法如下:

类名称::$静态属性名称

其中符号::称为范围解析操作符,用于访问静态成员、静态方法和常量,还可以用于覆盖类中的成员和方法。

如果要在类内部成员方法中访问静态属性,那么在静态属性的名称前加self::即可。

8.2.2 静态方法

静态方法就是通过关键字static修饰的成员方法。由于它不受任何对象的限制,因此可以不通过类的实例化而直接引用类中的静态方法。

静态方法引用的语法:

类名::静态方法名称([参数])

同样,如果要在类内部的成员方法中引用静态方法,那么也是在静态方法的名称前加上操作符self::

使用静态成员除了不需要实例化对象,另一个作用是在对象被销毁后仍然保存被修改的静态数据,以便下次继续使用。

<?php

class Book{

static$num=0;

publicfunction showMe(){

header("Content-type:text/html; charset=utf-8");

echo"您是第".self::$num."位访客";

self::$num++;

}

}

$book1=new Book();

$book1->showMe();

echo "<br>";

$book2=new Book();

$book2->showMe();

echo "<br>";

echo "您是第".Book::$num."位访客";

?>

8.3 Clone关键字 ---- 克隆对象

8.3.1 克隆对象

对象的克隆可以通过关键字clone来实现。使用clone克隆的对象与原对象没有人呢和关系,它是将原对象从当前位置重新复制一份,也就相当于在内存中新开辟了一块空间。

$克隆对象=clone $原对象名称;

对象克隆成功后,她们的成员方法、属性以及值是完全相同的。如果哟奥为克隆后的副本对象重新初始化就要用到下面将介绍的魔术方法__clone()

8.3.2 克隆副本对象的初始化

魔术方法__clone()可以对克隆后的副本对象重新初始化。它不需要任何参数,其中自动包含$this $that两个对象的引用,$this是副本对象的引用,$that则是原对象的引用。

8.4 对象比较

== 比较两个对象的内容

=== 比较对象的引用地址

8.5 Instanceof关键字 ---- 对象类型检测

Instanceof操作符可以检测当前对象属于哪个类。

objectName instanceof className

9 面向对象----常用魔术方法

Php中有很多以两个下划线开头的方法,如前__construct()__destruct() __clone()这些方法称为魔术方法。

9.1 __set()和__get()方法

__set()和__get()方法用于对私有成员进行赋值或者获取取值的操作。

__set()方法:在程序运行过程中为私有的成员属性设置值,它不需要任何返回值。__set()方法包含两个参数,分别表示变量名称和变量值。两个参数不可省略。这个方法不需要主动调用,可以在方法前加private关键字,防止用户直接调用

__get()方法:在程序运行过程中,在对象的外部获取私有成员属性的值。他有一个必要的参数,即私有成员属性名,它返回一个允许对象在外部使用的值。这个方法不需要主动调用,可以在方法前加private关键字,防止用户直接调用

9.2 __isset()和__unset()方法

__isset()帮助isset()函数检测私有成员属性。

如果在对象中存在__isset()方法,当在类的外部使用isset()函数检查对象中的所有成员时,就好自动调用类中的__isset()方法完成对私有成员属性的检测操作。

__unset()方法帮助unset函数在类外部删除指定的私有成员属性。

9.3 __call()方法

__call()方法的作用是当程序试图调用不存在或不可见的成员方法时,php会先调用__call()方法来存储方法名及其参数。

9.4 __toString()方法

当使用echo或print输出对象时,将对象转化为字符串

9.5 __autoload()方法

__autoload()方法可以自动实例化需要使用的类,当程序要用到一个类,但该类还没有被实例化时,php5将使用__autoload()方法在指定的路径下自动查找和该类名相同的文件,如果找到则继续执行,否则报告错误。

MrSoft.class.php

<?php

class MrSoft{

private$cont;

publicfunction __construct($cont){

$this->cont=$cont;

}

publicfunction __toString(){

return$this->cont;

}

}

?>

<?php

function __autoload($class_name){

$class_path= $class_name.'.class.php';

if(file_exists($class_path)) {

include_once($class_path);

}else{

echo"类路径错误";

}

}

$mrsoft = new MrSoft("helllsdf");

echo $mrsoft;

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: