PHP面试 PHP基础知识 九(面向对象)
面向对象
PHP的类权限控制修饰符
public(公共的) 、 protected(受保护的)、private(私有的)
public :最高权限 可以在类的内部使用 可以在类的外部使用 可以在子类中使用
protected:可以在类的内部使用 可以在子类当中使用
private:只能在类的内部使用 不可以被继承 不可以在类的外部使用
面向对象的封装、继承、多态
封装:成员访问权限 public protected private 访问权限问题
继承:单一继承 同时只能继承一个类
方法重写 子类继承一个父类 在子类中写一个于父类相同的方法名会把父类的方法覆盖掉
如果不想覆盖可以使用parent先调用一下父类的方法
class Father{
public function test(){
}
} class Son extends Father{
public function test(){ parent::test(); .....
}
}
多态:
抽象类的定义
抽象类定义前面以abstract关键字开始
类中可以定义多个方法,可以具体实现方法,也可定义抽象方法,抽象方法就是没有绝体实现的方法,需要在方法前加 abstract 关键字,抽象方法需要在子类中实现
类中只要有抽象方法,这个类必须定义为抽象类。
抽象类和接口一样不能直接实例化为对象,只能被普通类继承。 定义一个抽象类
abstract class MyList{ //抽象方法需要在子类中实现
abstract public function selectgroup($where); public function del($where){ echo "删除成功"; }
} //Tag类继承MyList抽象类
class Tag extends MyList{
//实现抽象方法
public function selectgroup(){ echo "查找数据"; } } //Plist类继承MyList抽象类
class Plist extends MyList{
//实现抽象方法
public function selectgroup(){ echo "查找数据库"; } }
接口的定义 interface 声明定义接口 一句话说明:类方法必须实现,接口的方法必须为空
不同类的共同方法在接口中定义,然后在不同类中实现不同的功能
接口本身就是抽象的不用加 abstract
一个类可以一次实现多个接口 语法用implements实现
接口可以被继承 用extends
接口定义方法只能使用public
接口不能创建自己的对象
interface Action(){ public function eat($foods); } //普通类实现接口方法 calss Human implements Action(){ //实现接口必须提供接口中的方法 public function eat($foods){ echo "Human eat";
} } class Animal implements Action(){ public function eat( $foods){ echo "Animal eat {$foods}"; } } //调用完成的方法
$human = new Human(); $human->eat(); $animal = new Animal(); $animal->eat(); /// instanceof 判断某个对象是否实现了某个接口 function CheckEat( $obj ){ if( $obj instanceof Action ){ $obj->eat( 'orange' ); }else{ echo "the object not implements Action"; } } CheckEat( $human ); CheckEat( $animal ); //接口继承 //extends 让接口继承接口 interface IcanPee extends Action(){ public function pee(); } //当类实现子接口时,父接口定义的方法也需要在这个类里面具体实现 Class Human1 implements IcanPee(){ public function pee(){ } public function eat( $foods ){ } }
魔术方法
__construct() 构建对象时使用
__destruct() 明确销毁对象或脚本结束时被调用
__call() 调用不可访问或不存的方法时被调用
__callStatic() 调用不可访问或不存在的静态方法时被调用
__get() 读取不可访问或不存在的属性时被调用
__set() 当给不可访问或不存在的属性赋值时被调用
__isset() 对不可访问或不存在的属性调用isset()或empty()时被调用
__unset() 对不可访问或不存在的属性进行unset时被调用
__sleep() 当使用serialize时被调用,当你不需要保存大对象的所有数据时很有用
__wakeup() 当使用unserialize时被调用,可用于做些对象的初始化操作
__toString() 当一个类被转换成字符串时被调用
__clone() 进行对象clone时被调用 用来调整对象的克隆行为
__invoke() 当以函数方式调用对象时被调用
__set_state() 当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值
__debuginfo() 当调用var_dump()打印对象时被调用(不想打印所有属性)PHP5.6版本
class MyExample{ public $var = 'test'; //构造函数
public function __construct()
{
echo '__contruct'.PHP_EOL;
} //对象的引用都被删除、对象被销毁、调用exit()后、脚本关闭时被调用
public function __destruct()
{
echo '__destruct'.PHP_EOL;
} //调用不可访问或不存在的方法时被调用
public function __call($name, $arguments)
{
echo '__call'.PHP_EOL;
} //调用不可访问或不存在的静态方法时被调用
public static function __callStatic($name, $arguments)
{
echo '__callStatic'.PHP_EOL;
} //读取不可访问或不存在的属性时被调用
public function __get($name)
{
echo '__get'.PHP_EOL;
} //不可访问或不存在的属性赋值时调用
public function __set($name, $value)
{
echo '__set'.PHP_EOL;
} //不可访问或不存在的属性调用isset()或empty()时被调用
public function __isset($name)
{
echo '__isset'.PHP_EOL;
} //不可访问或不存在的属性unset时被调用
public function __unset($name)
{
echo '__unset'.PHP_EOL;
} //serialize时被调用 ,不需要保存大对象的所有数据时有用
public function __sleep()
{
echo '__sleep'.PHP_EOL;
return array('var111111111111111');
} //unserialize时被调用,可用于做些对象的初始化操作
public function __wakeup()
{
echo '__wakeup'.PHP_EOL;
$this->var = 'test after wakeup';
} //一个类被转换为字符串时被调用
public function __toString()
{
return '__toString'.PHP_EOL;
} //进行对象clone时被调用 用来调整对象的克隆行为
public function __clone()
{
echo '__clone'.PHP_EOL;
} //以函数方式调用对象时被调用
public function __invoke()
{
echo '__invoke'.PHP_EOL;
} //当调用var_export()导出类时,此静态方法被调用。用__set_state的返回值做为var_export的返回值。
public static function __set_state($arr)
{
return '__set_state'.PHP_EOL;
} //调用var_dump()打印对象时被调用(当你不想打印所有属性)适用于PHP5.6版本
public function __debuginfo()
{
echo '__debuginfo'.PHP_EOL;
return array(
'var' =>'test fro __debuginfo'
);
} } $m = new MyExample(); //__construct()被调用
$m->not_exist_property = test; //__set()被调用
echo $m->not_exist_property; //__get()被调用
$m->abc(1,2,3); //__call()被调用
echo isset($m->not_exist_property); //__isset()被调用,返回bool值
unset($m->not_exist_property); //__unset()被调用
echo $tmp = serialize($m); //__sleep()被调用
unserialize($tmp); //__wakeup()被调用
$m1 = clone $m; //__clone()被调用,对象默认是引用传递,使用clone关键词则可实现对象复制
$m(); //__invoke()
eval( '$m2 = ' . var_export ( $m , true ) . ';');var_dump($m2);
var_dump($m);
//最后__destruct()被调用
设计模式
常见的设计模式:工厂模式、单例模式、注册树模式、适配器模式、观察者模式、策略模式
工厂模式
工厂模式是最常用的实例化对象模式,使用工厂方法代替new操作的一种模式
工厂模式的好处是,你想要更改所实例化的类名等,则只需要更改工厂方法内容即可,不需逐一寻找代码中具体实例化的地方修改。为系统结构提供了灵活的动态扩展机制,减少耦合。
/**
*简单工厂模式(静态工厂方法模式)
*/
/**
* Interface people 人类
*/
interface people
{
public function say();
}
/**
* Class man 继承people的男人类
*/
class man implements people
{
// 具体实现people的say方法
public function say()
{
echo '我是男人<br>';
}
}
/**
* Class women 继承people的女人类
*/
class women implements people
{
// 具体实现people的say方法
public function say()
{
echo '我是女人<br>';
}
}
/**
* Class SimpleFactoty 工厂类
*/
class SimpleFactoty
{
// 简单工厂里的静态方法-用于创建男人对象
static function createMan()
{
return new man();
}
// 简单工厂里的静态方法-用于创建女人对象
static function createWomen()
{
return new women();
}
}
/**
* 具体调用
*/
$man = SimpleFactoty::createMan();
$man->say();
$woman = SimpleFactoty::createWomen();
$woman->say();
单例模式
单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式一种常见的设计模式。比如用于,线程池、缓存、日志对象、对话框、打印机、数据库操作等。
单例模式分为三种:懒汉式单例、饿汉式单例、登记式单例。
有三个特点:
1、只能有一个实例。
2、必须自行创建这个实例
3、必须给其他对象提供这一实例
为什么要使用单例模式?
PHP一个主要应用场合就是引用程序和数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库连接数据库行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗和内存的资源。
class Single {
private $name;//声明一个私有的实例变量
private function __construct(){//声明私有构造方法为了防止外部代码使用new来创建对象。
}
static public $instance;//声明一个静态变量(保存在类中唯一的一个实例)
static public function getinstance(){//声明一个getinstance()静态方法,用于检测是否有实例对象
if(!self::$instance) self::$instance = new self();
return self::$instance;
}
public function setname($n){ $this->name = $n; }
public function getname(){ return $this->name; }
}
$oa = Single::getinstance();
$ob = Single::getinstance();
$oa->setname('hello world');
$ob->setname('good morning');
echo $oa->getname();//good morning
echo $ob->getname();//good morning
注册模式
注册模式,解决全局共享和交换对象。已经创建好的对象,挂在某个全局可以是哟个的数组上,在需要使用的时候,直接从该数组上获取即可。将对象注册到全局树上,任何地方直接去访问。
class Register
{
protected static $objects;
function set($alias,$object)//将对象注册到全局的树上
{
self::$objects[$alias]=$object;//将对象放到树上
}
static function get($name){
return self::$objects[$name];//获取某个注册到树上的对象
}
function _unset($alias)
{
unset(self::$objects[$alias]);//移除某个注册到树上的对象。
}
}
适配器模式
将各种截然不同的函数接口封装成统一的API
PHP中的数据库操作有MySQL、MySQLi、PDO三种,可以使用适配器模式统一成一致,使不同的数据库操作,统一成一样的API。类似的场景还有cache适配器,可以将memcache,redis,file,apc等不同的缓存函数,统一成一致。
首先定义一个接口(有几个方法,以及相应的参数)。然后,有几种不同的情况,就写几个类实现该接口。将完成相似功能的函数,统一成一致的方法。
//接口 IDatanase
interface IDatabase
{
function connect($host, $user, $passwd, $dbname);
function query($sql);
function close();
} // Mysql
class MySQL implements IDatabase
{
protected $conn;
function connect($host, $user, $passwd, $dbname)
{
$conn = mysql_connect($host, $user, $passwd);
mysql_select_db($dbname, $conn);
$this->conn = $conn;
}
function query($sql)
{
$res = mysql_query($sql, $this->conn);
return $res;
}
function close()
{
mysql_close($this->conn);
}
} //Mysqli
class MySQLi implements IDatabase
{
protected $conn;
function connect($host, $user, $passwd, $dbname)
{
$conn = mysqli_connect($host, $user, $passwd, $dbname);
$this->conn = $conn;
}
function query($sql)
{
return mysqli_query($this->conn, $sql);
}
function close()
{
mysqli_close($this->conn);
}
}
观察者模式
1、观察者模式,当一个对象状态发生变化时,依赖它的对象全部会收到通知,并自动更新。
2、场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理的逻辑。当更新的逻辑增多之后,代码会变的那一维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件的主体代码。
3、观察者模式实现了低耦合,非侵入式的通知与更新机制。
// 主题接口
interface Subject{
public function register(Observer $observer);
public function notify();
} // 观察者接口
interface Observer{
public function watch();
} // 主题
class Action implements Subject{
public $_observers=array();
public function register(Observer $observer){
$this->_observers[]=$observer;
} public function notify(){
foreach ($this->_observers as $observer) {
$observer->watch();
} }
} // 观察者
class Cat implements Observer{
public function watch(){
echo "Cat watches TV<hr/>";
}
}
class Dog implements Observer{
public function watch(){
echo "Dog watches TV<hr/>";
}
}
class People implements Observer{
public function watch(){
echo "People watches TV<hr/>";
}
} // 应用实例
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();
策略模式
策略模式是对象的行为模式,用意是对一组算法的封装。动态的选择徐太的算法并使用。
策略模式指的是程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个模式本身的核心思想就是面向对象编程的多形性思想
策略模式三个角色
1:抽象策略角色
2:具体策略角色
3:环境角色(对抽象策略角色的引用)
实现步骤:
1:定义抽象角色类 (定义好各个实现的共同抽象方法)
2:定义具体策略类 (具体实现父类的共同方法)
3:定义环境角色类 (私有化申明抽象角色变量,重载构造方法,执行抽象方法)
打个比方说明策略模式:
如果我需要买衣服了,我可以有几种方式买衣服?
1、我可以在京东购买。
2、我可以在淘宝购买。
3、我可以找代购买。
4、我可以去商场买。
每个方式我都可以买到衣服,但是使用了不同方式。
abstract class baseAgent { //抽象策略类
abstract function PrintPage();
}
//用于客户端是IE时调用的类(环境角色)
class ieAgent extends baseAgent {
function PrintPage() {
return 'IE';
}
}
//用于客户端不是IE时调用的类(环境角色)
class otherAgent extends baseAgent {
function PrintPage() {
return 'not IE';
}
}
class Browser { //具体策略角色
public function call($object) {
return $object->PrintPage ();
}
}
$bro = new Browser ();
echo $bro->call ( new ieAgent () );
PHP面试 PHP基础知识 九(面向对象)的更多相关文章
- 【Java面试】基础知识篇
[Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充.源码分享见个人公告.Ja ...
- javascript的基础知识及面向对象和原型属性
自己总结一下javascript的基础知识,希望对大家有用,也希望大家来拍砖,毕竟是个人的理解啊 1.1 类型检查:typeof(验证数据类型是:string) var num = 123; cons ...
- C#基础知识之面向对象以及面向对象的三大特性
在C#基础知识之类和结构体中我详细记录了类.类成员.重载.重写.继承等知识总结.这里就记录一下对面向对象和面向对象三大特性的广义理解. 一.理解面向对象 类是面向对象编程的基本单元,面向对象思想其实就 ...
- 死磕面试 - Dubbo基础知识37问(必须掌握)
作为一个JAVA工程师,出去项目拿20k薪资以上,dubbo绝对是面试必问的,即使你对dubbo在项目架构上的作用不了解,但dubbo的基础知识也必须掌握. 整理分享一些面试中常会被问到的dubbo基 ...
- JAVA基础知识之面向对象编程知识汇总
JAVA基础课程部分面向对象已经学习完成,知识结构如下: 总体知识框架: 类的结构: 面向对象编程三大特征: 关键字和抽象类接口等: 常见知识汇总: 成员变量和局部变量比较 有无返回值方法比较: 权限 ...
- [C#基础]基础知识一: 面向对象的基本知识.
激励自己有时间多看看.!! C#基础共分为七个部分: 一: 面向对象 二: 值类型, 引用类型, 字符串操作 三: 集合文件操作 四: 正则表达式 五: XML操作 六: 委托, 事件 七: 反射 1 ...
- java 基础知识九 类与对象
java 基础知识九 类与对象 1.OO(Object–Oriented )面向对象,OO方法(Object-Oriented Method,面向对象方法,面向对象的方法)是一种把面向对象的思想应 ...
- C# 篇基础知识3——面向对象编程
面向过程的结构化编程,例如1972年美国贝尔研究所推出的C语言,这类编程方式重点放在在定函数上,将较大任务分解成若干小任务,每个小任务由函数实现,分而治之的思想,然而随着软件规模的不断扩张,软件的复杂 ...
- python基础知识九
sys模块 sys模块包含系统对应的功能.我们已经学习了sys.argv列表,它包含命令行参数. 命令行参数 例14.1 使用sys.argv #!/usr/bin/python # Filename ...
随机推荐
- idea使用 xml文件
如图 搜索template(模板) 点击加号后
- Android获取手机和系统版本等信息的代码
有时候需要统计手机的型号和版本号,利用程序可以获取到相应的手机信息,对比两部手机发现,厂商不同,某个信息显示方式也不尽相同,具体见: String phoneInfo = "Product: ...
- PHP如何进行错误与异常处理(PHP7中的异常处理和之前版本异常处理的区别)
PHP如何进行错误与异常处理(PHP7中的异常处理和之前版本异常处理的区别) 一.总结 一句话总结: throwable接口+Error类 在PHP7更新中有一条:更多的Error变为可捕获的Exce ...
- php中的list()
list()在php中上一个语言结构,并不是一个函数.类似array(),不过array()这个东西我们现在一般很少使用了,因为从php5.4版本开始,我们会直接使用[]来定义数组. 那么,list( ...
- Tomcat负载均衡、调优核心应用进阶学习笔记(四):JVM调优
文章目录 概述 **JVM管理的内存段可分为两大类:线程共享内存和线程私有内存** Java Heap SIze Options The memory structure of a JVM proce ...
- Cocos2d-x的Android配置以及相关参考文档
关于Win7下配置Coco2d-x的Android开发环境,可以参考子龙山人的博客:Setting Up Cocos2d-x Android Development on Win7,这篇文章写得很详细 ...
- tushare积分怎么获得 tushare pro 积分充值 积分转让
本人是做量化投资的,团队转型,换了交易策略,手头有多个离职同事的闲置转让.600分:原价50元,仅需39元1500分:原价150元,仅需109元(售罄)2000分:原价200元,仅需149元5000分 ...
- MOV EAX,DWORD PTR SS:[EBP+8]
nasm来写可以写成mov eax,dword ptr [ebp + 8]理由:ebp和esp默认是ss段,所以根本不用显式说明. eax,ebx,ecx,edx,edi,esi默认 ...
- ReactOS 代码更新后的编译安装
其实四月份就已经更新过了,最新版应该是0.4.11+,具体去GITHUB上去看. 至于编译,其实在最早的0.2版本时代,ReactOS就曾经给出过一套完整的编译方式, 并且给出过一个完整的编译环境,版 ...
- android中的国际化
java国际化步骤: 定义资源文件: baseName_language_country.properties baseName_language.properties baseName.proper ...