Home > Backend Development > PHP Tutorial > php 面向对象笔记

php 面向对象笔记

WBOY
Release: 2016-06-23 13:04:45
Original
990 people have browsed it

===================================================
PHP的面向对象:

对象是客观存在的一个实体。
类是对对象抽象的一个描述。

概念:对象(实体)、类、 类与对象的关系。

oop面向对象编程的特点:封装、继承、多态

类和对象的关系:
类的实例化结果就是一个对象(使用new关键字)
对对象的抽象描述就是一个类

===================================================
一、如何定义一个类,和使用

1.1 语法格式:
[修饰符] class 类名 [extends 父类] [implements 接口1[,接口2...]]{
【成员属性】定义变量
【成员方法】定义函数
}

1.2 成员属性格式:
修饰符 $变量名[=默认值]; 如:public $name="zhangsan";
注意:成员属性不可以是带运算符的表达式、变量、方法或函数的调用。 如:
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;
正确定义方式:
public $var6 = 100; //普通数值(4个标量:整数、浮点数、布尔、字串)
public $var6 = myConstant; //常量
public $var7 = self::classConstant; //静态属性
public $var8 = array(true, false); //数组

常用的属性修饰符:public、protected、private、static、var

1.3 成员方法格式:
[修饰符] function 方法名(参数..){
[方法体]
[return 返回值]
}

常用的方法修饰符:public、protected、private、static、abstract、final

1.4 对象:类的实例化就会产生一个对象。
如: $p = new Person();

1.5 $this 关键字: 表示自己,表示当前使用对象,*哪个对象调用代表哪个
1.我们在类中调用自己的成员属性或方法都是使用 $this->调用。
2.注意:静态方法不可以使用$this关键字

===================================================
二、构造方法和析构方法

2.1. 构造方法:
1.当我们通过new关键字来创建一个对象时,第一个自动执行的方法称为构造方法。

2.方法名__construct(); 主要用于初始化对象。
(在php4.0时可使用与类名重名的方法作为构造方法)

2.2. 析构方法:当这个对象被销毁时最后自动调用的方法,称为析构方法。
1.__destruct(); 目的是释放资源(如关闭连接、文件,释放资源)

2.对象被销毁时最后自动调用

===================================================
三、封装(访问控制)

3.1 封装:就是将"属性" private或protected 私有,并提供公有的setter放置与getter取值方法

public(公有) protected(受保护) private(私有)
===========================================================
在本类中 Y Y Y
在家族中 Y Y N
在类外边 Y N N

public 类外需要调用此类内的方法或属性时使用
protected 类外不需要调用,而家族内需要使用
private 用于安全信息,只用于当前类

===================================================
四、 重载

4.1 属性重载中的四个魔术方法:__set() __get() __isset() __unset()

__get():当我们直接输出一个对象中的非公有属性时会自动调用的方法,
并将属性名以第一个参数传进去。
__get($name){...} //外部:$m->priAge;

__set():当我们直接设置一个对象中的非公有属性时会自动调用的方法,
并将属性名以第一个参数,值作为第二参数传进去。
__set($name,$value){...} //外部:$m->priAge = 100;

__isset():验证一个对象属性isset($this->name) 或 empty($this->name)时, $this->name是一个非公有属性时,自动调用此方法。
public function __isset($param){
return isset($this->$param);
}

__unset()当销毁一个对象属性unset($this->name), $this->name是一个非公有属性时,自动调用此方法。
public function __unset($param){
unset($this->$param);
}

4.2 方法的重载:
mixed __call ( string $name , array $arguments )
mixed __callStatic ( string $name , array $arguments ) php5.3.0支持

1.当调用一个不可访问方法(如未定义,或者不可见)时,__call() 会被调用。
2.当在静态方法中调用一个不可访问方法(如未定义,或者不可见)时,__callStatic() 会被调用。

第一个参数表示方法名,第二参数表示调用时的参数列表(数组类型)

class A {
//调用不存在的方法
public function __call($methodName,$args) {
echo $methodName;
print_r($args);
}

//调用不存在的静态方法
static public function __callStatic($methodName,$args) {
echo '
'.$methodName;
print_r($args);
}
}
$a = new A;
$a->say('a','b');
A::test('c','d');

===================================================
五、 继承

5.1 继承:extends
*继承的目的:为了减少重复的代码。

假如B类继承A类,那么就继承了A中所有非私有属性和方法.其中A叫父类(基类)B叫子类(派生类)。
class B extends A{
....
}

1.*parent:若子类出现覆盖父类的方法,那么想调用被覆盖掉的父类方法,并可以跟子类的方法融合为一起

格式:parent::父类方法 | 父类名称::父类方法

class A{
public function __construct(){
//....
}
}
class B extends A{
public function __construct(){
parent::__construct();//注意要调用一下父类的构造方法
//....
}
}

2.继承的特性
1、PHP支持单继承,一类只能继承一个父类
2、PHP支持多层继承,可以有子孙类
3、子类会继承父类所有属性和方法,但是私有的属性和方法不能调用

3.属性的继承
1、私有的属性不会被覆盖,其他会被覆盖。
2、属性的修饰只能更加松散,不能更加严谨。 松散性:public > protected > private
3、如果子类中有与父类同名的属性,父类有public $name 子类只能使用public修饰
3、如果子类中有与父类同名的属性,父类有protected $name 子类能使用protected,public修饰

4.方法的继承
1、所有方法可以被继承,但是私有的方法不能被使用
2、如果子类有与父类同名的方法,那么除了私有的方法,其他都被覆盖掉。
3、如果子类有与父类同名的方法,方法的修饰只能更加松散,不能更严谨。

===================================================
六、 final、static和const
*内存逻辑上:常量区(常量、静态属性)、代码区(类、函数)、栈内存(普通的小的变量)、堆内存(大的变量)

6.1 final关键字:主要用于修饰类与成员方法
目的:一是为了安全,二是没有必要

1.使用final关键字修饰类,表示这个类不能被继承,防止有子类的覆盖

2.使用final关键字修饰的方法,不可以在子类中被覆盖(重写)。

3.使用final关键字不能修饰属性

final class B {
final public function A {
..
}
}
---------------------------------------------------------------
6.2 static关键字:表示静态的意思,用于修饰类的属性和方法

static关键字修饰 属性/方法 称为 静态属性/静态方法,
注意:静态方法在实例化后的对象不可以访问 //$对象名->静态方法名

1.可以不用new(实例化)就可以直接使用方法或属性
*外部调用:类名::方法名 | 类名::属性名
*类中调用:self::静态属性名 | self::静态方法名

*2.静态属性是共享的。也就是调用多个对象也是指向同一个地址

3.在静态方法中不可以使用非静态的内容。就是不让使用$this

4.在一个类的方法中若没有出现$this的调用,默认此方法为静态方法。

5.static不能修饰类

---------------------------------------------------------------
6.21 设计模式。目的:节省资源

1、单例设计模式 2、工厂设计模式 3、 抽象工厂设计模式

class Single
{
//定义一个静态属性,用来存放对象
static private $obj = null;

//私有化构造方法。不能在类的外部实例化对象
private function __construct() {}

//实例化对象
static public function test() {
//如果没有对象,我们就允许它new一个对象
if(!self::$obj) {
self::$obj = new Single();//创建对象
}

//有了对象,就直接返回之前的对象
return self::$obj;
}

//单例不允许克隆
public function __clone() {
trigger_error('错误', E_USER_ERROR);
}
}

$s1 = Single::test(); var_dump($s1);
$s2 = Single::test(); var_dump($s2); //调用同一个对象

$s3 = clone $s2; //报错

---------------------------------------------------------------
6.3. const关键字: 在类中修饰成员属性,将其定义成常量(不可修改的),

1.一般要求常量名都是大写的,没有“$”符 没有其他修饰符(public)

2.定义格式:const 成员常量名="值";

3.使用:
*外部调用:类名::成员常量名;
*类中调用:self::成员常量名;

---------------------------------------------------------------
6.4. 检测当前对象是属于谁的类(家族类也是)

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

class A {}
class B extends A {}
$b = new B;
if($b instanceof A) {echo 'y';}

2.is_a — 如果对象属于该类或该类是此对象的父类则返回 TRUE

===================================================
七、 类型约束

1. 类型约束可以使用的类型是:数组,对象,回调函数。
若指定的一个类名,那么可传入本类及子类的对象进去。
可以使用的约束类型:(复合类型)数组array,类名、抽象类名、接口名

class MyClass
{
//第一个参数必须为类OtherClass的一个对象
public function test(OtherClass $otherclass) {
**可以传入别的类,调用别的类的方法和属性
echo $otherclass->var;

//同这里
if( $otherclass instanceof Hanzi){
$otherclass->qinqin();
}
}

//第一个参数必须为数组
public function test_array(array $input_array) {
print_r($input_array);
}
}

===================================================
八、其他魔术方法:

1. 对象复制clone 克隆一个对象,因为对象属于引用类型,普通的“=”号属于引用赋值,
所有需要clone来复制一份。
魔术方法:__clone() 当执行clone克隆时会自动调用的方法。

class A {
public function __clone() {
//自动执行
}
}

$a = new A;
$b = clone $a; //克隆,是两个对象

-----------------------------------------------------------------
2. __toString()方法:魔术方法,当我们直接要输出一个对象时,如echo $a,print $a,
那么会自动调用的方法。
注意:__toString()方法必须返回一个字串类型的值。

class A {
public function __toString() {
return '这是一个对象,不允许ehco,print...';
}
}
$a = new A;
echo $a; //报错

-----------------------------------------------------------------
3. *自动加载"类函数"__autoload(类名):
当new 实例化一个对象时,这个类若不存在,则自动调用此函数,并将类名存入参数
我可以使用这个实现类的自动加载。

function __autoload($className) {
include './autoload/'.$className.'.class.php';
}

$a = new A;
$a->say(); //say

//在 autoload/A.class.php下
class A{
public function say() {
echo 'say';
}
}

-----------------------------------------------------------------
4. __invoke把对象当成函数使用的时候自动调用

class A {
public function __invoke() {
echo 'aa';
}
}

$a = new A;
$a(); //aa

===================================================
九、 对象序列化(串行化)(webservice XML)(在对象持久化存储、和传输中使用)

serialize() -- 序列化
unserialize() -- 反序列化

1.php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。
2.unserialize()函数能够重新把字符串变回php原来的值。
3.序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。

1.__sleep(): 是执行串行化时自动调用的方法,目的是实现资源类型的属性的关闭操作。
@@sleep方法需要返回一个数组,其中数组中的值是序列化时要保留的属性名
2.__wakeup():是在执行反串行化时自动调用的方法,目的是实现资源属性的打开(sleep方法关闭的资源)

//实例:
class A {
public $name1 = 'xiaohei';
public $name2 = 'xiaobai';

public function demo() {
return 'aa';
}

//序列化自动调用的方法
public function __sleep() {
return array('name2'); //只想存储name2,就返回name2
}

//反序列化自动调用的方法
public function __wakeup() {
echo '###';
}
}

$a = new A;

//序列化
$data = serialize($a);

//存入文件
file_put_contents('./1.txt', $data);

//获得数据
$str = file_get_contents('./1.txt');

echo $str; //O:1:"A":1:{s:4:"name";s:7:"xiaohei";}

//反序列化
$tmp = unserialize($str);

print_r($tmp); //A Object ( [name] => xiaohei )

-------------------------------------------------------------------------------------
JSON格式的字符串进行编码/解码

json_encode:对变量进行 JSON 编码
json_decode:对 JSON 格式的字符串进行编码

$arr = array('id'=>1, 'name'=>'jack');

$str1 = json_encode($arr);
echo $str1; //{"id":1,"name":"jack"}

$a = json_decode($str1, true); //加true返回array,否则返回object
echo $a; //Array ( [id] => 1 [name] => jack )

===================================================
十、 抽象类:

目的:抽象类对于子类(实现类),有一个约束的作用,

特点:
//1.定义抽象类
abstract class A {
//2.定义抽象方法
abstract public function test1();
abstract public function test2();

//3.可以有普通方法和属性,不需要子级实现
public function demo() {}
public $name = 'aa';

//4.不能定义抽象属性 Fatal error
abstract public $age = 18;
}

class B extends A {
//5.@@继承了抽象类的"普通类"必须实现抽象类的"所有抽象方法"
public function test1() {}
public function test2() {}

//6.包含了抽象方法的类必须是抽象类,Fatal error
abstract function test3() {}
}

abstract class C extends A {
//7.不能覆盖抽象方法,Fatal error
abstract public function test1() {}

//8.可以继承抽象类的同时添加抽象方法
abstract public function test3();
}

//8.不能实例化,Fatal error
$c = new C;

===================================================
十一、 接口:

目的:同抽象类相同,是更具体的抽象类
假如一个抽象类中所有的方法都是抽象的,那么我们可以使用另外一种方式定义:接口
接口使用关键字interface来定义,接口中只能有常量与抽象方法。

//1.定义接口
interface A {
//2.接口不能有普通属性,Fatal error
public $name = 'aa';

//3.接口不能有普通方法,Fatal error
public function test() {}

//3.但可以定义常量
const HOST = 'aa';

//4.定义接口方法,不需要abstract
public function test1();

}

interface B {
//5.接口之间是继承关系,重复定义Fatal error
const HOST = 'bb';

public function test2();
}

class C {}

//6.可以同时继承"单"类、实现"多"接口(先继承,后实现)
class D extends C implements A,B {
//7.@@继承了抽象类的"普通类"必须实现抽象类的"所有抽象方法"
public function test1() {}
public function test2() {}
}

抽象类和接口总结:
1.目的:制定规范,为了限制其子类
2.选择:如果规范中需要有"普通方法"就选择抽象类
3.区别:
1.定义关键字不同。抽象类:abstract 接口:interface
2.继承/实现关键字不同。抽象类:extends 接口:implements
3.抽象类可以有普通方法,接口不能有普通方法
4.抽象类只能被单继承,接口可以多实现
5.接口不能有成员属性,只有常量与抽象方法

===================================================
十二、多态

定义:对于“同一个方法”,传入“不同对象”,实现了不同的效果

class Meizi {
public function meet($obj) {
//限制了对象必须有qinqin()这个方法
if( $obj instanceof Hanzi){
//同一个方法
$obj->qinqin();
}else{
echo '你不会亲亲这个功能!';
}
}
}

//抽象类
abstract class Hanzi
{
abstract public function qinqin();
}

//大屌丝类
class DDS extends Hanzi {
public function qinqin() {
echo '被妹子打了一巴掌,这就是DDS的命运';
}
}

//高富帅类
class GFS extends Hanzi {
public function qinqin() {
echo '不仅仅亲亲,还啪啪啪,这是高富帅的命运';
}
}

//萌妹子类
class MengMeizi {}

$m = new Meizi;
$dds = new DDS;
$gfs = new GFS;
$mmz = new MengMeizi;

//传入对象
echo $m->meet($dds); //实现了DDS的效果
echo $m->meet($gfs); //实现了GFS的效果

//没有限制
echo $m->meet($mmz); //你不会亲亲!

@@多态的两个实例:
./1.通过接口实现多态的应用.php
./2.通过普通类实现多态的应用.php

===================================================
十三、异常处理:
在php5中有一种新的错误处理机制--异常处理:(采用面向对象方式的)
涉及的类:Exception异常类
Exception类结构:
class Exception
{
protected $message = 'Unknown exception'; // 异常信息
protected $code = 0; // 用户自定义异常代码
protected $file; // 发生异常的文件名
protected $line; // 发生异常的代码行号

function __construct($message = null, $code = 0);

final function getMessage(); // 返回异常信息
final function getCode(); // 返回异常代码
final function getFile(); // 返回发生异常的文件名
final function getLine(); // 返回发生异常的代码行号
final function getTrace(); // backtrace() 数组
final function getTraceAsString(); // 已格成化成字符串的 getTrace() 信息

/* 可重载的方法 */
function __toString(); // 可输出的字符串
}

使用:
try{
throw new Exception("年龄不可以为负数"); //异常抛出
}catch(Exception $e){
//异常处理
echo $e->getmessage();
}

实例:
function addUser($username) {
if($username="xiaobai") {
//添加成功
}else {
//添加失败
throw new Exception('添加失败');
}
}

function updateUser($username) {
if($username = "xiaohei") {
//修改成功
}else {
//修改失败
throw new Exception('修改失败');
}
}

try {
addUser('xiaobaia');

updateUser('xiaohei');
}catch(Exception $e) {

echo '失败信息是:'.$e->getMessage();
}

@@当捕获到一个异常后,try()块里面的后续代码不继续执行

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template