php面向对象

面向对象基础回顾

什么是对象?什么是类?两者有什么区别和联系?

类是对一类事物描述,是抽象的、概念上的定义;\
对象是实际存在的该类事物的每个个体,因而也称实例(instance)。在计算机中,可以理解为,在内存中创建了实实在在存在的一个内存区域存储着这个对象。\
创建对象的过程称为创建对象,也称为实例化。

什么是继承?PHP支持怎样的继承?

继承(Inheritance)是面向对象软件技术当中的一个概念。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。

一个扩充类总是依赖一个单独的基类,也就是说,不支持多继承。使用关键字“extends”来扩展一个类。

什么是重写(overriding)?PHP是否支持重载(overloading)?

Java 重写(Override)与重载(Overload)

重写是子类对父类的允许访问的方法的实现过程进行重新编写!返回值和形参都不能改变。即外壳不变,核心重写!

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型呢?可以相同也可以不同。

什么是静态方法?什么情况下适合使用静态方法?

静态方法只要定义了类,不必建立类的实例就可使用

全部静态意味着牺牲了OOP的三个特性,也就意味着放弃了封装、集成、多态。另外,由于没有统一编码习惯和约定,很多东西不做抽象,不做单一入口,代码本身的复用以及维护都是个问题。写多了这种代码,估计工程师本身的成就感都是个问题。
个人理解下面这几种情景下使用static关键字会比较合适:\

  • util类(或者某个类中充当了util角色的method)
  • 一些特殊的design pattern中,比如static factory、singleton pattern中
  • 某项被封装的功能,即使类不实例化,也可以调用并且不觉得别扭、奇怪,不依赖类内部的其它非静态成员

什么是类常量?什么情况下应该使用类常量?

可以把在类中始终保持不变的值定义为常量。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。

什么是抽象类?什么是接口?分别适用于何种场景?

定义为抽象的类不能被实例化。任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。

使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。接口中定义的所有方法都必须是公有,这是接口的特性。

  • 接口没有构造函数,抽象类可以有构造函数。
  • 接口中的方法默认都是public类型的。而抽象类中的方法可以使用private,protected或public来修饰。
  • 一个类可以同时实现多个接口。一个类只能继承一个抽象类。

抽象类还是接口

  • 如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类。如果要创建由一些不相关对象采用的功能,就使用接口。
  • 如果必须从多个来源继承行为,就使用接口。
  • 如果知道所有类都会共享一个公共的行为实现,就可以使用抽象类,并在其中实现该行为。

异常处理

程序中运行时出现的问题, 该怎样处理?

什么是异常?

异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。

怎么样产生一个异常?怎样处理产生的异常?

function inverse($x) {
    if (!$x) {
        throw new Exception('Division by zero.');
    }
    else return 1/$x;
}

try {
    echo inverse(5) . "\n";
    echo inverse(0) . "\n";
} catch (Exception $e) {
    echo 'Caught exception: ',  $e->getMessage(), "\n";
}

怎样自定义异常?

class MyException extends Exception { }

try\catch\finally是怎样协同工作的?

php面向对象_第1张图片

PHP的error, warning, notice等类型的错误,怎样通过抛出异常的方式处理?

trigger_error — 产生一个用户级别的 error/warning/notice 信息

怎样捕捉PHP中的致命错误?

set_error_handler("customError");

Traits

Traits是什么?

Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。

什么场景下适合使用Trait?

PHP使用单一继承模型。虽然这种模型足够应付大部分用例场景,但有时用户也需要将一些通用样板代码放置其他无关联的类中。

怎样使用Trait?

trait PropertiesTrait {
    public $same = true;
    public $different = false;
}

class PropertiesExample {
    use PropertiesTrait;
    public $same = true; // Strict Standards
    public $different = true; // 致命错误
}

trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait World {
    public function sayWorld() {
        echo 'World!';
    }
}

trait HelloWorld {
    use Hello, World;
}

class MyHelloWorld {
    use HelloWorld;
}

预订义接口

PHP中有哪些预订义接口?它们可实现什么功能?

  • 遍历Traversable 检测一个类是否可以使用 foreach 进行遍历的接口。无法被单独实现的基本抽象接口。相反它必须由 IteratorAggregate 或 Iterator 接口实现。
  • 迭代器Iterator 可在内部迭代自己的外部迭代器或类的接口。
  • 聚合式迭代器IteratorAggregate 创建外部迭代器的接口。
  • 数组式访问ArrayAccess 提供像访问数组一样访问对象的能力的接口。
  • 序列化 自定义序列化的接口。
  • Closure 用于代表匿名函数的类.

怎样使用PHP的预订义接口?

Traversable是什么?Iterator和IteratorAggregate是什么?

Traversable 无法被单独实现的基本抽象接口。相反它必须由 IteratorAggregate 或 Iterator 接口实现。

Iterator extends Traversable {
/* 方法 */
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}

IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator ( void )
}

foreach是否只能用于遍历数组?

怎样高效便捷地读取超大的文本文件?

class FileIterator implements Iterator

怎样通过数组的方式调用自定义类中的数据?

ArrayAccess(数组式访问)

yield是什么东西?它和Generator类,Traversable类有什么联系?

Generators provide an easy way to implement simple iterators without the overhead or complexity of implementing a class that implements the Iterator interface.

function xrange($start, $limit, $step = 1) {
    for ($i = $start; $i <= $limit; $i += $step) {
        yield $i;
    }
}

echo 'Single digit odd numbers: ';

/* 注意保存在内存中的数组绝不会被创建或返回 */ 
foreach (xrange(1, 9, 2) as $number) {
    echo "$number ";
}

什么是回调函数?怎样创建回调函数?

call_user_func()和call_user_func_array()

怎么样调用匿名函数?怎样在匿名函数中使用外部变量?

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。

$greet = function($name)
{
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');

// 继承 $message
$example = function () use ($message) {
    var_dump($message);
};

PHP的魔术方法和魔术常量

什么是魔术方法?什么是魔术常量?

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为”魔术方法”(Magic methods)

  • LINE 文件中的当前行号。
  • FILE 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,FILE 总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
  • DIR 文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(FILE)。除非是根目录,否则目录中名不包括末尾的斜杠。(PHP 5.3.0中新增) =
  • FUNCTION 函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
  • CLASS 类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。类名包括其被声明的作用区域(例如 Foo\Bar)。注意自 PHP 5.4 起 CLASS 对 trait 也起作用。当用在 trait 方法中时,CLASS 是调用 trait 方法的类的名字。
  • TRAIT Trait 的名字(PHP 5.4.0 新加)。自 PHP 5.4 起此常量返回 trait 被定义时的名字(区分大小写)。Trait 名包括其被声明的作用区域(例如 Foo\Bar)。
  • METHOD 类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。
  • NAMESPACE 当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。

PHP中有哪些魔术方法?

__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为”魔术方法”(Magic methods)

调用类中不存在的方法会发生什么?

在对象中调用一个不可访问方法时,__call() 会被调用。用静态方式中调用一个不可访问方法时,__callStatic() 会被调用。

怎样避免一个类被实例化?

private

单例模式

类中的方法能否以类属性的方式调用?

命名空间与自动加载

什么是命名空间?怎样定义命名空间?

在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题

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

命名空间有什么作用?

命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问

同一个文件内能否定义多个命名空间?

namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

什么是非限定名称?什么是相对限定名称?什么是完全限定名称?

PHP 命名空间中的元素使用同样的原理。例如,类名可以通过三种方式引用:

  • 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
  • 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
  • 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

定义了命名空间后,怎样调用PHP内置的函数?

怎样在一个命名空间中使用另一个命名空间下的类?

use My\Full\Classname as Another;
new \My\Full\Classname();

命名空间和文件目录有关系吗?

在文件系统中访问一个文件有三种方式:

  • 相对文件名形式如foo.txt。它会被解析为 currentdirectory/foo.txt,其中 currentdirectory 表示当前目录。因此如果当前目录是 /home/foo,则该文件名被解析为/home/foo/foo.txt。
  • 相对路径名形式如subdirectory/foo.txt。它会被解析为 currentdirectory/subdirectory/foo.txt。
  • 绝对路径名形式如/main/foo.txt。它会被解析为/main/foo.txt。

怎样实现类的自动加载?

反射

什么是反射?

在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。

通过反射可以了解哪些信息?

某个类中所有的方法、属性、注释、方法参数等

什么时候使用类函数?什么时候使用反射?

反射使用场景: 自动加载插件,自动生成文档,甚至可用来扩充PHP语言。

参考

PHP在Web开发中static的使用场景
魔术方法,延迟绑定及静态成员
后期静态绑定
PHP的新特性finally
PHP 5.4弃Register Globals增Traits
PHP5.4的新特性
PHP如何快速读取大文件
深入理解PHP之匿名函数
匿名函数及闭包

你可能感兴趣的:(PHP)