两个比较大的话题,独立成本篇。

面向对象编程


一、命名空间

PHP 命名空间可以解决以下两类问题:

    1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
    2. 为很长的标识符名称 (通常是为了缓解第一类问题而定义的) 创建一个别名(或简短)的名称,提高源代码的可读性。
  • 模块化写法

[1] 可以在同一个文件中定义不同的命名空间代码,如:

<?php
namespace MyProject; const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>

[2] 其实,加个大括号会更好些。

<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
} namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
  • 全局代码
<?php
namespace MyProject {   const CONNECT_OK = 1;
  class Connection { /* ... */ }
  function connect() { /* ... */ }
} namespace { // 全局代码
  session_start();
  $a = MyProject\connect();
  echo MyProject\Connection::start();
}
?>
  • declare 语句
<?php
declare(encoding='UTF-8'); // 定义多个命名空间和不包含在命名空间中的代码

namespace MyProject {   const CONNECT_OK = 1;
  class Connection { /* ... */ }
  function connect() { /* ... */ }
} namespace { // 全局代码
  session_start();
  $a = MyProject\connect();
  echo MyProject\Connection::start();
}
?>
  • 子命名空间
<?php
namespace MyProject\Sub\Level; // 声明分层次的单个命名空间 const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */ } ?>

上面的例子创建了:

  1. 常量  MyProject\Sub\Level\CONNECT_OK
  2. 类  MyProject\Sub\Level\Connection
  3. 函数 MyProject\Sub\Level\Connect

二、命名空间使用

/* implement */

三、面向对象

列举概念:类,对象,成员变量,成员函数,继承,父类,子类,多态,重载,抽象性,封装,构造函数,析构函数。

[1] 一个综合性的例子:

<?php
class Site {
/* 成员变量 */
var $url;
var $title;

---------------------------------------------------------
function __construct( $par1, $par2 ) {
$this->url = $par1;
$this->title = $par2;
} ---------------------------------------------------------
/* 成员函数 */
function setUrl($par){
$this->url = $par;
} function getUrl(){
echo $this->url . PHP_EOL;
} function setTitle($par){
$this->title = $par;
} function getTitle(){
echo $this->title . PHP_EOL;
}
}

---------------------------------------------------------
$runoob = new Site('www.runoob.com', '菜鸟教程');
$taobao = new Site('www.taobao.com', '淘宝');
$google = new Site('www.google.com', 'Google 搜索');

---------------------------------------------------------
// 调用成员函数,获取标题和URL
$runoob->getTitle();
$taobao->getTitle();
$google->getTitle(); $runoob->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

[2] 析构函数

<?php
class MyDestructableClass {
function__construct() {
print "构造函数\n";
$this->name = "MyDestructableClass";
} function__destruct() {
print "销毁 " . $this->name . "\n";
}
} $obj = new MyDestructableClass();
?>

php中对应的malloc是什么? - ref: php 内存分配

php内核中的内存分配 使用的函数有 emalloc(), erealloc() ,这两个函数分别是malloc(),realloc()函数的封装

[3] extends 继承

<?php
// 子类扩展站点类别
class Child_Site extends Site {
var $category; function setCate($par){
$this->category = $par;
} function getCate(){
echo $this->category . PHP_EOL;
}
}

[4] override 重写

[5] 访问控制

  • 【属性】的访问控制
<?php
/**
* Define MyClass
*/
class MyClass
{
public $public = 'Public';
protected $protected = 'Protected';
private $private = 'Private'; function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
} ------------------------------------------------------------- $obj = new MyClass();
echo $obj->public; // 这行能被正常执行
echo $obj->protected; // <-- 这行会产生一个致命错误
echo $obj->private; // <-- 这行也会产生一个致命错误
$obj->printHello(); // 输出 Public、Protected 和 Private /**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 可以对 public 和 protected 进行重定义,但 private 而不能
protected $protected = 'Protected2'; function printHello()
{
echo $this->public;
echo $this->protected;
echo $this->private;
}
}

-------------------------------------------------------------
$obj2 = new MyClass2();
echo $obj2->public; // 这行能被正常执行
echo $obj2->private; // <-- 未定义 private
echo $obj2->protected; // <-- 这行会产生一个致命错误
$obj2->printHello(); // 输出 Public、Protected2 和 Undefined ?>
  • 【方法】的访问控制
<?php
/**
* Define MyClass
*/
class MyClass
{
public function __construct() { }

---------------------------------------------------------------
public function MyPublic() { }
protected function MyProtected() { }
private function MyPrivate() { } // 此方法为公有
function Foo()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate();
}
}
---------------------------------------------------------------
$myclass = new MyClass;
$myclass->MyPublic(); // 这行能被正常执行
$myclass->MyProtected(); // 这行会产生一个致命错误
$myclass->MyPrivate(); // 这行会产生一个致命错误
$myclass->Foo(); // 公有,受保护,私有都可以执行 /**
* Define MyClass2
*/
class MyClass2 extends MyClass
{
// 此方法默认为公有
function Foo2()
{
$this->MyPublic();
$this->MyProtected();
$this->MyPrivate(); // 这行会产生一个致命错误
}
} --------------------------------------------------------------- $myclass2 = new MyClass2;
$myclass2->MyPublic(); // 这行能被正常执行
$myclass2->Foo2(); // 公有的和受保护的都可执行,但私有的不行 class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
} public function testPublic() {
echo "Bar::testPublic\n";
} private function testPrivate() {
echo "Bar::testPrivate\n";
}
} class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
} private function testPrivate() {
echo "Foo::testPrivate\n";
}
} $myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>

[6] 接口的实现

<?php

// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
} // 实现接口
class Template implements iTemplate
{
private $vars = array(); public function setVariable($name, $var)
{
$this->vars[$name] = $var;
} public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
} return $template;
}
}

[7] 抽象类

<?php
abstract class AbstractClass
{
// 强制要求子类定义这些方法
abstract protected function getValue();
abstract protected function prefixValue($prefix); // 普通方法(非抽象方法)
public function printOut() {
print $this->getValue() . PHP_EOL;
}
} class ConcreteClass1 extends AbstractClass
{
protected function getValue() {
return "ConcreteClass1";
} public function prefixValue($prefix) {
return "{$prefix}ConcreteClass1";
}
} class ConcreteClass2 extends AbstractClass
{
public function getValue() {
return "ConcreteClass2";
} public function prefixValue($prefix) {
return "{$prefix}ConcreteClass2";
}
} $class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL; $class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?> 

考点:

此外,子类方法可以包含父类抽象方法中不存在的可选参数。

例如,子类定义了一个可选参数,而父类抽象方法的声明里没有,则也是可以正常运行的。

[8] const 常量

类中的常量,自带static属性。

[9] Static 关键字

考点:

由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。

<?php
class Foo {
public static $my_static = 'foo'; public function staticValue() {
return self::$my_static;
}
} print Foo::$my_static . PHP_EOL;
$foo = new Foo(); print $foo->staticValue() . PHP_EOL;
?>

[10] Final 关键字

如果父类中的方法被声明为 final,则子类无法覆盖该方法。

如果一个类被声明为 final,则不能被继承。

[11] 调用父类构造方法

需要自己去手动调用。

<?php
class BaseClass {
function __construct() {
print "BaseClass 类中构造方法" . PHP_EOL;
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct(); // 子类构造方法不能自动调用父类的构造方法
print "SubClass 类中构造方法" . PHP_EOL;
}
}
class OtherSubClass extends BaseClass {
// 继承 BaseClass 的构造方法
} // 调用 BaseClass 构造方法
$obj = new BaseClass(); // 调用 BaseClass、SubClass 构造方法
$obj = new SubClass(); // 调用 BaseClass 构造方法
$obj = new OtherSubClass();
?>

考点


一、继承中的 Static关键字

Ref: PHP static关键字的用法及注意点

  • static变量

  a). 可以不赋初值
  b). 不会存储引用。

  • 延迟静态绑定
class A {
public static function foo() {
static::who();   // Jeff: 不再为定义当前方法所在的类,而是实际运行时所在的类的who()
} public static function who() {
echo __CLASS__."\n";
}
} class B extends A {
public static function test() {
A::foo();      // 是在A的运行时环境中
parent::foo(); // 使用了运行时调用类
self::foo();
} public static function who() {
echo __CLASS__."\n";
}
} class C extends B {
public static function who() {
echo __CLASS__."\n";
}
} C::test(); ----------------------------------
结果:
  A
  C
  C

同理,也是要注意”运行时“这个概念!

class A {
protected static $var1 = null;
protected static $var2 = null;
public static function test(){
if(!static::$var2){
static::$var2 = static::$var1;
}
echo get_called_class().' '.static::$var2.' ';
}
}
class B extends A {
protected static $var1 = 'b';
}
class C extends A {
protected static $var1 = 'c';
}
B::test();   // 第一次调用test, var2还未赋值.
C::test();   // 第二次调用test, var2已赋值.

[PHP] 02 - Namespace & Class的更多相关文章

  1. 02.ArrayList和HashTable

    ArrayList集合 数组的缺点: (1).数组只能存储相同类型的数据. (2).数组的长度要在定义时确定. 集合的好处: (1).集合可以存储多种不同类型的数据. (2).集合的长度是可以任意改变 ...

  2. thinkphp的钩子的两种配置和两种调用方法

    thinkphp的钩子行为类是一个比较难以理解的问题,网上有很多写thinkphp钩子类的文章,我也是根据网上的文章来设置thinkphp的钩子行为的,但根据这些网上的文章,我在设置的过程中,尝试了十 ...

  3. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  4. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  5. [Full-stack] 世上最好语言 - PHP

    前言 本篇是对个人PHP, Laravel系列博文的总结与思考. 目的在于理清并熟练如下过程: "需求 --> Usercase --> UI --> 框架 --> ...

  6. 用Razor語法寫範本-RazorEngine組件介紹

    最近剛好有要寫寄Email的程式,在代碼中寫HTML覺得很呆,抽出代碼外寫到txt或html檔當範本,由程式執行時在載入檔案時用Regex換關鍵字又覺得不夠好用,而且因為有時會有要判斷一些條件,就會寫 ...

  7. 01.里氏准换与using关键字

    using关键字有什么用?什么是IDisposable? using可以声明namespace的引入,还可以实现非托管资源的释放,实现了IDisposiable的类在using中创建,using结束后 ...

  8. 利用setns()将进程加入一个新的network namespace

    1.首先使用docker创建一个容器,并获取该容器的network namespace monster@monster-Z:~$ docker run -itd --name test ubuntu ...

  9. BestCoder Round #89 02单调队列优化dp

    1.BestCoder Round #89 2.总结:4个题,只能做A.B,全都靠hack上分.. 01  HDU 5944   水 1.题意:一个字符串,求有多少组字符y,r,x的下标能组成等比数列 ...

随机推荐

  1. Eclipse 安装Maven以及Eclipse配置Maven

    安装Maven 1 下载 Downloading Apache Maven 3.5.0 选择 2 解压 3 配置环境变量 新建变量名:MAVEN_HOME  变量值:D:\SoftwareInstal ...

  2. Kaggle Titanic solution 纯规则学习

    其实就是把train.csv拿出来看了看,找了找规律,调了调参数而已. 找到如下规律: 1.男的容易死,女的容易活 2.一等舱活,三等舱死 3.老人死,小孩活 4.兄弟姐妹多者死 5.票价高的活 6. ...

  3. Instruments

    链接: iOS性能优化:Instruments使用实战 iOS 使用Instruments的工具小结    

  4. AnguarJS中链式的一种更合理写法

    假设有这样的一个场景: 我们知道一个用户某次航班,抽象成一个departure,大致是: {userID : user.email,flightID : "UA_343223",d ...

  5. C#中Split用法【转】

    https://www.cnblogs.com/webenh/p/6570801.html 1.用字符串分隔: using System.Text.RegularExpressions;string  ...

  6. mod_wsgi的工作模式和配置

    Openstack所有提供API接口的服务都是python web server,而其本身性能很弱,目前已经将它们配置到了apache上.但对于如何设置mod_wsgi的参数,我一直没有好好去阅读其文 ...

  7. 详细解读Android中的搜索框(三)—— SearchView

    本篇讲的是如何用searchView实现搜索框,其实原理和之前的没啥差别,也算是个复习吧. 一.Manifest.xml 这里我用一个activity进行信息的输入和展示,配置方式还是老样子,写一个输 ...

  8. docker 安装hadoop

    上一篇文章介绍了一些docker的基本命令,这篇文章来安装一个HADOOP 一.下载hadoop镜像 @~/git/github/docker-ambari (master)$ docker pull ...

  9. (亲测解决)每次打开excel文件都会出现两个窗口,一个是空白的sheet1,另一个是自己的文档

    版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/sinat_34104446/article/details/80210424 一.问题描述每次打开Exce ...

  10. funny

    var life = { "work_hard","have_fun","make_history" };