<?
class Person
{
	// 下面是人的成员属性
	var $name;	// 人的名子
	var $sex;	// 人的性别
	var $age;	// 人的年龄

	// 定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
	function __construct($name = "", $sex = "", $age = "")
	{
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}

	// 这个人可以说话的方法,说出自己的属性
	function say()
	{
		echo "我的名子叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
	}
}

$p1 = new Person("张三", "男", 20);

// 使用“clone”克隆新对象p2,和p1对象具有相同的属性和方法。
$p2=clone $p1;
$p2->say();
?>

  “__clone()”方法可以没有参数,它自 动包含$this和$that两个指针,$this指向复本,而$that指向原本;

<?
class Person
{
	// 下面是人的成员属性
	var $name;	// 人的名子
	var $sex;	// 人的性别
	var $age;	// 人的年龄

	// 定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
	function __construct($name = "", $sex = "", $age = "")
	{
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}

	// 这个人可以说话的方法, 说出自己的属性
	function say()
	{
		echo "我的名子叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
	}

	// 对象克隆时自动调用的方法, 如果想在克隆后改变原对象的内容,需要在__clone()中重写原本的属性和方法
	function __clone()
	{
		// $this指的复本p2, 而$that是指向原本p1,这样就在本方法里,改变了复本的属性。
		$this->name = "我是假的 $that->name";
		$this->age = 30;
	}
}

$p1 = new Person("张三", "男", 20);
$p2 = clone $p1;
$p1->say();
$p2->say();
?>

  

上例输出:

我的名子叫:张三 性别:男 我的年龄是:20
我的名子叫:我是假的张三 性别:男 我的年龄是:30

如果一个项目,我们要对一个一模一样的类进行引用,我们可以用__clone()然后,然后对其进行赋值就可以了 省去繁琐的操作

注意被克隆的物体一定是个被实例化过的对象

当我们调用了一个不存在的方法时程序就会报错

此时我们引入了一个错误的处理方法__call();

<?php
//这是一个测试的类,里面没有属性和方法
class Test
{
	// 调用不存的方法时自动调用的方法,第一个参数为方法名,第二个参数是数组参数
	function __call($function_name, $args)
	{
		print "你所调用的函数:$function_name(参数:";
		print_r($args);
		echo ")不存在!<br>";
	}
}

// 产生一个Test类的对象
$test=new Test();

// 调用对象里不存在的方法
$test->demo("one", "two", "three");

// 程序不会退出可以执行到这里
echo "this is a test<br>";
?> 

上例输出结果为:

你所调用的函数: demo(参数:Array ( [0] => one [1] => two [2] => three ) )不存在!
this is a test

在OOP语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为外部代码访问其的接口。而抽象方法就是为了方便继承而引入的,我们先来看一下抽象类和抽象方法的定义再说明它的用途。

用法:所谓的没有方法体指的是,在方法声明的时候没有大括号以及其中的内容,而是直接在声明时在方法名后加上分号结束,另外在声明抽象方法时还要加一个关键字“abstract”来修饰;

例如:

abstract function fun1();
abstract function fun2();

  要点:1.抽象类不能产生实例对象

2.子类必须把父类中的抽象方法全部都实现,否则子类中还存在抽象方法,那么子类还是抽象类,还是不能实例化类

<?
abstract class Demo
{
	var $test;

	abstract function fun1();
	abstract function fun2();

	function fun3()
	{
		...
	}
}

$demo = new Demo(); // 抽象类不能产生实例对象,所以这样做是错的,实例化对象交给子类

class Test extends Demo
{
	function fun1()
	{
		...
	}

	function fun2()
	{
		...
	}
}

$test = new Test(); // 子类可以实例化对象,因为实现了父类中所有抽象方法
?>

  为了解决多继承的问题,我们引入了接口这个概念

接口:接口是一种特殊的抽象类,抽象类又是一种特殊的类,所以接口也是一种特殊的类

类的定义:  class 类名{ … } ,
接口的声明:interface 接口名{ …}

<?php
// 定义一个接口使用interface关键字,“One”为接口名称
interface One
{
	// 定义一个常量
	const constant = 'constant value';

	// 定义了一个抽象方法”fun1”
	public function fun1();

	// 定义了抽象方法”fun2”
	public function fun2();
}
?>

  PHP中不仅一个类可以实现多个接口,也可以在继承一个类的同时实现多个接口, 一定要先继承类再去实现接口;

<?php
// 使用extends继承一个类,使用implements实现多个接口
class Four extends 类名一 implemtns 接口一, 接口二, ...
{
	// 所有接口中的方法都要实现才可以实例化对象
	...
}
?>

  PHP的多态就是多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法

<?php
// 定义了一个形状的接口,里面有两个抽象方法让子类去实现
interface Shape
{
	function area();
	function perimeter();
}

// 定义了一个矩形子类实现了形状接口中的周长和面积
class Rect implements Shape
{
	private $width;
	private $height;

	function __construct($width, $height)
	{
		$this->width = $width;
		$this->height = $height;
	}

	function area()
	{
		return "矩形的面积是:" . ($this->width * $this->height);
	}

	function perimeter()
	{
		return "矩形的周长是:" . (2 * ($this->width + $this->height));
	}
}

// 定义了一个圆形子类实现了形状接口中的周长和面积
class  Circular implements Shape
{
	private $radius;

	function __construct($radius)
	{
		$this->radius=$radius;
	}

	function area()
	{
		return "圆形的面积是:" . (3.14 * $this->radius * $this->radius);
	}

	function perimeter()
	{
		return "圆形的周长是:" . (2 * 3.14 * $this->radius);
	}
}

// 把子类矩形对象赋给形状的一个引用
$shape = new Rect(5, 10);
echo $shape->area() . "<br>";
echo $shape->perimeter() . "<br>";

// 把子类圆形对象赋给形状的一个引用
$shape = new Circular(10);
echo $shape->area() . "<br>";
echo $shape->perimeter() . "<br>";
?>

  为了方便传输,我们可以进行将对象转化为二进制的输出 我们将这个过程称为序列化

第一种情况就是把一个对象在网络中传输的时候要将对象串行化

第二种情况就是把对象写入文件或是数据库的时候用到串行化。

序列化:serialize()

反序列化:unserialize()

<?
class Person
{
	// 下面是人的成员属性
	var $name;	// 人的名子
	var $sex;	// 人的性别
	var $age;	// 人的年龄

	// 定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值
	function __construct($name = "", $sex = "", $age = "")
	{
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}

	// 这个人可以说话的方法, 说出自己的属性
	function say()
	{
		echo "我的名子叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
	}
}

$p1 = new Person("张三", "男", 20);
$p1_string = serialize($p1);	// 把一个对象串行化,返一个字符串
echo $p1_string . "<br>";		// 串行化的字符串我们通常不去解析
$p2 = unserialize($p1_string);	// 把一个串行化的字符串反串行化形成对象$p2
$p2->say();
?>

  

上例输出值为:

O:6:"Person":2:{s:4:"name";s:4:"张三";s:3:"age";i:20;}
我的名子叫:张三 性别: 我的年龄是:40

我们在mVC的架构中经常看到这么一个函数__autoload()函数

<?php
function __autoload($classname)
{
	require_once $classname . '.php';
}

//MyClass1类不存在时,自动调用__autoload()函数,传入参数”MyClass1”
$obj = new MyClass1();

//MyClass2类不存在时,自动调用__autoload()函数,传入参数”MyClass2”
$obj2 = new MyClass2();
?>

  

php面向对象编程(三)的更多相关文章

  1. Python学习笔记之面向对象编程(三)Python类的魔术方法

    python类中有一些方法前后都有两个下划线,这类函数统称为魔术方法.这些方法有特殊的用途,有的不需要我们自己定义,有的则通过一些简单的定义可以实现比较神奇的功能 我主要把它们分为三个部分,下文也是分 ...

  2. java面向对象编程(三)--this

    看一段代码:(Demo112.java),先了解为什么要使用this. /* this的必要性 */ public class Demo112{ public static void main(Str ...

  3. 面向对象编程(十)——继承之Super关键字及内存分析

    Super关键字

  4. python面向对象编程 -- 封装、继承

    面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...

  5. 进击的Python【第六章】:Python的高级应用(三)面向对象编程

    Python的高级应用(三)面向对象编程 本章学习要点: 面向对象编程介绍 面向对象与面向过程编程的区别 为什么要用面向对象编程思想 面向对象的相关概念 一.面向对象编程介绍 面向对象程序设计(英语: ...

  6. JavaScript 面向对象编程(三)如何写类和子类

    在JavaScript面向对象编程(一)原型与继承和JavaScript面向对象编程(二)构造函数和类中,我们分别讨论了JavaScript中面向对象的原型和类的概念.基于这两点理论,本篇文章用一个简 ...

  7. C++编程之面向对象的三个基本特征

    面向对象的三个基本特征是:封装.继承.多态. 封装 封装最好理解了.封装是面向对象的特征之一,是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类 ...

  8. (三)Javascript面向对象编程:非构造函数的继承

    Javascript面向对象编程:非构造函数的继承   这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...

  9. Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)

    Javascript面向对象编程(三):非构造函数的继承   作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...

随机推荐

  1. php 7.0 安装mcrypt

    1. 添加ppa源 sudo add-apt-repository ppa:ondrej/php 2. 升级源 sudo apt-get update && sudo apt-get ...

  2. Linux-1:安装&忘记密码&CRT连接centos 6.5

    我是在虚拟机VM安装的centos 6.5 一.Linux安装 Ctrl + Alt:鼠标退出LINUX界面 安装我是参考,当然也可以根据网上教程安装:http://oldboy.blog.51cto ...

  3. WebBrowser的Cookie操作之流量刷新机

    最近一直在思考着如何通过代码去伪装或实现人工自然浏览网页的效果,起初能想到的是用WebBrowser实现这一效果,需要达到的功能预想有以下几点: 1.自动刷新 2.模拟人工下拉滚动条并停留一段时间: ...

  4. EntityFramework简介

    EntityFramework是什么? 1.是对ADO.NET 更高封装的ORM (对象关系映射)框架,跟Nhibernate类似 2.用面向对象的方式来操作关系数据库 3.目标: 提高开发效率,减轻 ...

  5. ORA-19502: write error on file "xxxxx", block number xxxx

    错误现象: 在ORACLE 10g下为表空间IGNITE_EGVSQL01增加数据文件时,报如下错误: SQL> ALTER TABLESPACE IGNITE_EGVSQL01      AD ...

  6. SQL Server 2012安装错误案例:Error while enabling Windows feature: NetFx3, Error Code: -2146498298

    案例环境: 服务器环境 :    Windows Server 2012 R2 Standard 数据库版本 :    SQL Server 2012 SP1 案例介绍:   在Windows Ser ...

  7. JDBC Driver Types

    JDBC Driver Types Type1: JDBC-ODBC Bridge Driver Type2: JDBC-Native API Type3: JDBC-Net Pure Java Ty ...

  8. 如何读懂复杂的C语言声明

    本文已迁移至: http://www.danfengcao.info/c/c++/2014/02/25/howto-understand-complicated-declaration-of-c.ht ...

  9. 设置DIV可编辑

    <div id="move" contentEditable="true">可编辑</div> 设置contentEditable属性可 ...

  10. Windows10的革命之路-全新UWP开发平台

    众所周知,最近几年,微软一直在操作系统上进行统一化的尝试.第一次尝试的产品——Windows 8/8.1操作系统完全谈不上成功.请看下图: 我个人认为,这并不意味着操作系统统一化的策略是错误的,只能算 ...