Polymorphism
)按字面的意思就是“多种状态”abstract
abstract class MyAbsClass {
abstract public function func();
}
复制代码
<?php
abstract class MyAbsClass {
abstract public function func();
}
class ChildClass extends MyAbsClass {
// 这样写会报错, 由于没有实现抽象类中定义的方法
}
复制代码
<?php
abstract class MyAbsClass {
abstract public function func();
}
class ChildClass extends MyAbsClass {
public function func() {
// 即使什么都没有写, 也没有关系...
}
}
复制代码
<?php
abstract class MyAbsClass {
abstract public function func();
}
abstract class ChildClass extends MyAbsClass {
// 什么都没写, 也不会报错...
}
复制代码
abstract class MyAbsClass {
public function func(); // 会报错, 由于没有abstract关键字
}
复制代码
class MyAbsClass // 会报错, 由于没有abstract关键字 {
abstract public function func();
}
复制代码
<?php
abstract class MyAbsClass {
public $name = '张三';
public $age;
public function test() {
echo 'hello';
}
abstract public function func();
}
复制代码
final public static function
php
使用接口(interface),能够指定某个类必须实现哪些方法,但不须要定义这些方法的具体内容。编程
接口中也能够定义常量。函数
接口实现关键字implementsthis
<?php
interface MyInterface {
const NUM = 123;
public function func();
public function test();
}
class MyClass implements MyInterface {
public function func() {
}
public function test() {
echo 'hello';
}
}
复制代码
<?php
interface MyInterface {
const NUM = 123;
public function func();
public function test() {
echo "test"; // 会报错, 不能有具体方法
};
}
复制代码
<?php
interface MyInterface {
const NUM = 123;
public function func();
public function test();
}
class MyClass implements MyInterface {
public function func() {
}
// 报错, 由于没有实现test()
}
复制代码
<?php
interface MyInterface {
const NUM = 123;
public function func();
public function test();
}
abstract class MyClass implements MyInterface {
// 没有实现接口的方法, 也不会报错
}
class Demo extends MyClass {
public function func() {
// 必须实现, 不然报错
}
public function test() {
// 必须实现, 不然报错
}
}
复制代码
<?php
interface A {
public function aaa();
}
interface B extends A {
public function bbb();
}
class C implements A {
public function bbb() {
//
}
public function aaa() {
}
}
复制代码
<?php
interface A {
public function aaa();
}
interface B {
public function bbb();
}
class C implements A, B {
public function bbb() {
// 都得实现, 否则报错
}
public function aaa() {
// 都得实现, 否则报错
}
}
复制代码
<?php
interface A {
public function aaa();
}
interface B {
public function bbb();
}
class C {
public function bbb() {
}
public function aaa() {
}
}
class D extends C implements A, B {
// 类D继承C, C实现了A和B
}
复制代码
抽象类有普通的方法,接口没有spa
抽象类能够有本身的成员属性和方法,接口只能有public 常量。操作系统
抽象类无关紧要构造方法,接口没有构造方法code
抽象类单继承,接口多重继承cdn
instanceof
用于肯定一个PHP变量是否属于某一类class的实例<?php
class A {
}
class B {
}
$a = new A();
var_dump($a instanceof A); // true
var_dump($a instanceof B); // false
复制代码
instanceof
也可用来肯定一个变量是否是继承自某一父类的子类的实例<?php
class A extends B {
}
class B {
}
$a = new A();
var_dump($a instanceof A); // true
var_dump($a instanceof B); // true
复制代码
instanceof
也可用于肯定一个变量是否是实现了某个接口的对象的实例<?php
class A implements B {
}
interface B {
}
$a = new A();
var_dump($a instanceof A); // true
var_dump($a instanceof B); // true
复制代码
<?php
class A {
}
class B {
}
$a = new A();
$b = new B();
function test(A $n) {
echo "ok";
}
test($a); // 输出ok
test($b); // 报错, 由于$b是B的实例, 不是A的实例
复制代码
<?php
class A {
public function aaa(B $n) {
}
}
class B {
}
class C extends B {
public $a = '123';
}
class D extends A {
}
$a = new A();
$c = new C();
$a->aaa($c);
复制代码
须要的类在不一样文件
)__autoload()
函数也能自动加载类和接口spl_autoload_register()
函数能够注册任意数量的自动加载器,spl_autoload_register()
函数__autoload()
函数,在之后的版本中它可能被弃用
C:\Users\Administrator\Desktop\imooc\a.class.php
对象
<?php
class A extends B {
// 会报错, 由于找不到B
}
复制代码
C:\Users\Administrator\Desktop\imooc\b.class.php
blog
<?php
class B {
}
复制代码
引入便可
<?php
include 'b.class.php'; // 引入便可
class A extends B {
// 会报错, 由于找不到B
}
复制代码
使用自动加载
<?php
function myloader() {
echo '被执行了...';
include 'b.class.php';
}
spl_autoload_register('myloader'); // 执行myloader
class A extends B {
}
复制代码
使用静态方法
<?php
class Loader {
public static function myloader() {
echo '被执行了...';
include 'b.class.php';
}
}
spl_autoload_register(['Loader', 'myloader']); // 执行myloader
class A extends B {
// 不会报错
}
复制代码
也能够作成构造方法
<?php
class Loader {
public function __construct() {
spl_autoload_register([$this, 'myloader']);
}
public function myloader() {
echo '被执行了...';
include 'b.class.php';
}
}
$obj = new Loader();
class A extends B {
}
复制代码
接口同理...
编程中常见的两类问题
定义命名空间
namespace
来声明。namespace Project1;
// 代码...
namespace Project2{
// 代码...
}
复制代码
<?php
namespace MySapce {
function test()
{
echo 'test1';
}
test(); // 不会报错
}
namespace MySapce2 {
function test()
{
echo 'test2';
}
test(); // 不会报错
}
复制代码
<?php
namespace myspace;
function time() {
echo 'hello';
}
time(); // 不会报错, 输出hello
复制代码
<?php
namespace myspace1;
function time() {
echo 'hello1';
}
time(); // 不会报错, 输出hello1
namespace myspace2;
function time() {
echo 'hello2';
}
time(); // 不会报错, 输出hello2
复制代码
指定命名空间
<?php
namespace myspace1;
function time() {
echo 'hello1';
}
namespace myspace2;
function time() {
echo 'hello2';
}
\myspace1\time(); // hello1
复制代码
使用系统的time方法, \
表示全局
<?php
namespace myspace1;
function time() {
echo 'hello1';
}
namespace myspace2;
function time() {
echo 'hello2';
}
echo \time(); // 1567210241 系统函数, 返回时间戳
复制代码
声明单个命名空间namespace MyProject
定义子命名空间namespace MyProject\Sub\Level
;
能够在同一个文件中定义多个命名空间
若是没有定义任何命名空间,全部的类与函数的定义都是在全局空间,与PHP引入命名空间概念前同样。
在名称前加上前缀\
表示该名称是全局空间中的名称,即便该名称位于其它的命名空间中时也是如此
__NAMESPACE__常量
常量__NAMESPACE__
的值是包含当前命名空间名称的字符串
在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
<?php
namespace hello\hello1;
var_dump(__NAMESPACE__); // hello\hello1
namespace hello\hello2;
var_dump(__NAMESPACE__); // hello\hello2
复制代码
<?php
var_dump(__NAMESPACE__); // ""
复制代码
非限定名称, 彻底限定名称, 限定名称(绝对路径, 相对路径)
<?php
namespace A\B;
class MyClass {
public function __construct() {
echo '空间A\B 中的类 实例化了' . "\n";
}
}
namespace A;
class MyClass {
public function __construct() {
echo '空间A 中的类 实例化了' . "\n";
}
}
$obj = new MyClass();// 非限定名称 就近
$obj = new \A\B\MyClass();// 彻底限定名称 绝对路径
$obj = new \A\MyClass();// 彻底限定名称 绝对路径
$obj = new B\MyClass();//限定名称 相对路径
复制代码
include
不会改变当前命名空间, 可是include
以后, 可使用引入文件中的命名空间
C:\Users\Administrator\Desktop\imooc\aaa.php
<?php
namespace aaa;
function demo() {
echo 'aaa';
}
复制代码
C:\Users\Administrator\Desktop\imooc\bbb.php
<?php
namespace bbb;
function demo() {
echo 'bbb';
}
include 'aaa.php';
demo(); // bbb
var_dump(__NAMESPACE__); // bbb
\aaa\demo(); // 可使用aaa.php的命名空间
复制代码
动态调用函数
<?php
function demo() {
echo "demo\n";
}
demo(); // 调用demo
$a = 'demo';
$a(); // 一样能够调用demo
复制代码
动态实例化对象
<?php
class A {
public function demo() {
echo "demo\n";
}
}
$a = new A();
$a->demo();
$b = "A";
$c = new $b;
$c->demo();
复制代码
动态调用命名空间
<?php
namespace A\B;
function demo() {
echo "demo\n";
}
namespace A;
demo(); // 会报错, 由于当前命名空间下, 没有demo()
复制代码
<?php
namespace A\B;
function demo() {
echo "demo\n";
}
namespace A;
\A\B\demo(); // 这就会正常了
复制代码
<?php
namespace A\B;
function demo() {
echo "demo\n";
}
namespace A;
$a = '\A\B\demo'; // 效果同样, 由于都是彻底限定名称
$a = 'A\B\demo';
$a();
复制代码
<?php
namespace A\B;
function demo() {
echo "demo\n";
}
namespace A;
$a = 'B\demo'; // 报错, 不支持相对路径
$a();
复制代码