关键的OOP概念
OOP的好处 1.封装, 2继承, 3多态.
多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息将可以产生不同的结果,这种现象称为多态性。
<?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>";
属性的五个作用域
public 都可以访问
private 只能在定义属性的类中访问
protect 继承链上访问
final 不能被子类覆盖
static
属性重载的处理
指php对当前不可访问对象的处理方式. 不可访问对象分为 不存在 和 访问权限受限两种. 注意 : 这里没有静态属性.
对于不存在对象, 用__set() 方法设置属性
<?php
class Employee{
public $name;
function __set($propName, $propValue){
$this->$propName = $propValue;
}
}
$employee = new Employee();
$employee->name = '小明';
$employee->title = '工程师';
用__get()方法获取属性
<?php
class Employee{
public $name;
public $city;
public $age;
function __get($propName){
$vals = ['name', 'city'];
if(in_array($propName, $vals)) return $this->propName;
else return '不存在此属性';
}
}
$employee = new Employee();
$employee->name = '小明';
echo $employee->salary;
对于访问权限受限的对象 可以为私有属性创建两个方法 get() 和 set()
方法的作用域
public
private
protect
abstract 抽象方法, 只能在父类里面声明, 然后在子类中实现, 只有抽象类才能实现抽象方法
<?php
abstract class Employee{
abstract function demote();
}
final 防止被子类覆盖, 如果覆盖将会报致命错误.
static
静态类成员 : 属性或方法被所有的类实例共享, 不能由特定的对象调用.
自动加载对象 __autoload()
定义一个特殊的函数__autoload(), 当脚本加载未定义的类时会自动调用该函数. 也可以使用spl_autoload_register — 注册__autoload()函数
高级特性
对象克隆 : 默认引用传递, 但使用克隆方法可以得到一个副本. 如果要调整对象的克隆行为, 可以使用__clone() 方法, 它会在克隆操作时自动调用.
继承 : 子类如果有构造函数, 则执行子类的构造函数, 否则执行父类的.
接口
定义了一种实现规范, 声明了必需的函数和常量, 但不给出具体实现. 原因是因为不同的实体可能有不同的实现方式
interface IniterfaceName{
CONST 1;
...
CONST N;
function memthodName1();
function memthodName2();
}
类通过使用implements实现接口, 如果没有实现全部方法, 则必须声明为抽象类. 可以通过实现多个接口来模拟多继承.
class Class_Name implements IniterfaceName{
function memthodName1(){
//具体实现
}
function memthodName2(){
//具体实现
}
}
抽象类
不能被实例化的类, 只能被其他类继承
命名空间
不支持 : 方法重载, 操作符重载, 多继承,
方法的重写和重载
父类中存在某个方法, 子类中又重新定义了重名方法, 称为重写. 并没有更改类的结构
<?php
class father{
public function test(){
echo "father";
}
}
class son extends father{
public function test(){
parent::test();//还想要这父类的东西
echo "son ";
}
}
$son = new son();
$son->test();
重载 : 传入不同的参数, 根据参数值返回不同的结果. php本身不支持, 下面代码会报错
<?php
class A{
public function test(){
echo "test1";
}
public function test($a){
echo "test2";
}
}
$a=new A();
$a->test();
$a->test($a);
我们可以通过__call()来模拟重载操作. 注意, 这里为非静态调用, 静态调用使用__callstatic().
<?php
class Magic {
function __call($name,$arguments) {
if($name=='foo') {
if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
}
}
private function foo_for_int($x) {
echo "oh an int!";
}
private function foo_for_string($x) {
echo "oh a string!";
}
}
$x = new Magic();
$x->foo(3);
$x->foo("3"
使用final关键字标记的类不能被继承, 只能被实现, 使用final标记的方法不能被子类覆盖, 是最终版本.
对象在内存中的体现:
内存大体分为4段, 栈空段, 堆空段, 代码段, 初始化静态段. 栈内存是可以直接存取的,而堆内存是不 可以直接存取的内存, 我们的对象来说就是一种大的数据类型而且是占用空间不定长的类型,所以说对象是放在堆里面的,但对象名称是放在栈里面的,这样通 过对象名称就可以使用对象了
从上图可以看出 $p1 = new Person();等号右边是真正的对象实例, 在堆内存里面的实体,上图一共有3次new Person(),所以会在堆里面开辟3个空间,产生3个实例对象,每个对象之间都是相互独立的,使用自己的空间,在PHP里面,只要有一个new这个关键字出现就会实例化出来一个对象,在堆里面开辟一块自己的空间
常见魔术方法
__construct();
__destruct(); 注意 : php对象体现在堆栈中, 所以这里是先进后出.
__isset(); 检查属性是否存在, 专门为私有属性设置(private, protect), public属性不走__set().
__unset(); 销毁属性, 其它同上.
__toString() : 在直接输出对象时调用, 必须return 一个字符串
__clone(): 克隆对象时调用.
__call() : 处理调用错误. 这个方法有2个参数,第一个参数为调用不存在的方法过程中,自动调用__call()方法时,把这个不存在的方法的方法名传给第一个参数, 第二个参数传递一个参数数组.
__sleep(): 在序列化时自动调用, 不接受任何参数, 但返回一个数组,其中包含需要串行化的属性。末被包含的属性将在串行化时被忽略,如果没有__sleep()方法,PHP将保存所有属性。
__wakeup() : 反序列化时调用
后期静态绑定, static:: 不再是当前方法所在的类, 而是运行时所在的类. 如果改成self::who() 则输出为A
<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
} class B extends A {
public static function who() {
echo __CLASS__;
}
} B::test()
关键的OOP概念的更多相关文章
- 面向对象OOP概念描述
面向对象三大特征:封装,继承,多态 封装就是把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法 继承就是在已经存在的类的定义作为基础,建立新的技术.新定义的类可以添加新的数据或功能,也可以 ...
- JS 8-1 OOP概念与继承
function Foo(){ this.y=2; } typeof Foo.prototype; Foo.prototype.x = 1; var obj3= new Foo(); obj3.x; ...
- 读书笔记《PHP与MySQL程序设计》一
第1章 PHP概述 1.1 历史(PHP4.PHP5.PHP5.3.PHP6[未发布]) 1.2 一般语言特性(实用性.强大功能.可选择性.成本[开源]) 第2章 环境配置 2.1 安装的前提条件( ...
- 面向对象的PHP(5)
OOP的好处 封装 封装可以隐藏实现细节,使代码模块化,代码重用 继承 继承可以扩展已存在的代码模块(class),代码重用 多态 为了类在继承和派生的时候,保证实例的某一属性正确调用,接口重用 关键 ...
- PHP基础(2)
测试模板 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- Python2.6-原理之类和oop(下)
来自<python学习手册第四版>第六部分 五.运算符重载(29章) 这部分深入介绍更多的细节并看一些常用的重载方法,虽然不会展示每种可用的运算符重载方法,但是这里给出的代码也足够覆盖py ...
- 深入理解OOP(第一天):多态和继承(初期绑定和编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- 深入浅出OOP(一): 多态和继承(早期绑定/编译时多态)
在本系列中,我们以CodeProject上比较火的OOP系列博客为主,进行OOP深入浅出展现. 无论作为软件设计的高手.或者菜鸟,对于架构设计而言,均需要多次重构.取舍,以有利于整个软件项目的健康构建 ...
- Spring AOP(一)——基础概念
前文的一些内容更多是针对Spring容器内部的一些特性的描述,接下来一个专题将描述Spring AOP的一些信息,配置细节等等. 介绍 面向切面编程(AOP)是一种新的针对程序结构的思路,它补足了面向 ...
随机推荐
- OpenCL 学习step by step (5) 使用二维NDRange workgroup
http://www.cnblogs.com/mikewolf2002/archive/2012/09/07/2675634.html 在本教程中,我们使用二维NDRange来设置workgroup, ...
- 【Head First Servlets and JSP】笔记 25:JSTL 参考
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ t ...
- jQuery图片放大预览
在线演示 本地下载
- 利用canvas和RGraph作图
利用canvas可以直接在页面中绘制各种复杂的图形,其中引用到一个Rgraph的插件. Rgraph插件使用非常方便,只需几步就可以完成一个折线图.饼图.柱状图,或是其中两者图形的结合! (1) 引用 ...
- Python 文件操作综合案例
# 案例 # 文件的复制 # 要求 # 将一个文件, 复制到另外一个副本中 # 步骤分析 # 1. # 只读模式, 打开要复制的文件 import os import shutil path = &q ...
- Flume-NG源码阅读之SourceRunner,及选择器selector和拦截器interceptor的执行
在AbstractConfigurationProvider类中loadSources方法会将所有的source进行封装成SourceRunner放到了Map<String, SourceRun ...
- Pandas分组(GroupBy)
任何分组(groupby)操作都涉及原始对象的以下操作之一.它们是 - 分割对象 应用一个函数 结合的结果 在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数.在应用函数中,可以执行以下 ...
- scala学习手记32 - trait选择性混入
继续上一节. 狗当然是人类的好朋友.但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了.其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友. 用程序怎么实现呢?在java里面, ...
- Spring + Spring MVC + MyBatis框架整合
---恢复内容开始--- 一.Maven Web项目创建 如有需要,请参考:使用maven创建web项目 二.Spring + Spring MVC + MyBatis整合 1.Maven引入需要的J ...
- chrome浏览器经常无响应
chrome浏览器(v68)安装一个fiddler证书导入后点击关闭,会出现无响应 有时候动不动会无响应,今天百度了一下,发现真正的"罪魁祸首"是搜狗输入法,升级一下就好了 万恶的 ...