PHP底层实现(http://blog.jobbole.com/94475/)

一,抽象类:abstract

abstract class  HeHe{
  public $age=18;//可以定义属性
  public function say(){//可以方法实现 echo "i am say"; }
  abstract public function run();//方法声明 不能有花括号,抽象类可以没有抽象方法
}

抽象类归纳总结:

1定义为抽象的类不能被实例化。

2任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。

3抽象类可以没有抽象方法,但是抽象类依然不能被实例化,被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现

4继承一个抽象类的时候,非抽象子类必须定义父类中的所有抽象方法;另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。

例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,而不能定义为私有的。

补充:

抽象类可以有成员属性

2有人问:抽象方法是否可以定义为私有,答案是不可以,因为抽象接口的目的就是为了抽象出类模型用来继承,定义为私有,外部访问不到,偏移了设计目的会报错

3抽象类可以实现接口,且可以不实现其中的方法

4抽象类可以继承抽象类,且不能重写抽象父类的抽象方法,否者会报错。这样的用法,可以理解为对抽象类的扩展,使用关键词extends,若重写抽象父类的抽象方法则会报错

class Test extends HeHe{
public $name;
public function __construct($a){
    $this->name=$a;
  }    
  public function run (){
    //注意:抽象方法必须实现------Fatal error: Class Test contains 1 abstract method
    and must therefore be declared abstract or implement the remaining methods echo $this->name;    
  }
public function say($a){
var_dump ($a);
  }
}

二,接口:interface

interface goSchool{interface
const NAME='xiaoming';
/* const和define的区别:
    1、const用于类成员变量的定义,一经定义,不可修改。
    Define不可以用于类成员变量的定义,可用于全局常量。
    2、Const可在类中使用,define不能
    3、Const不能在条件语句中定义常量
   */  
     //接口可以定义常量,但是不能定义成员属性    
    //接口可以有一个或者多个成员方法   
   public function go_111();

class Go implements goSchool{    
  public function go_111(){        
    echo 11111;    
  }
}

接口讲解:

1使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容
2接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的
3接口中定义的所有方法都必须是公有,这是接口的特性,protected和private会报错(Fatal error: Access type for interface method
4常量:接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖。不建议在接口中定义常量,没有什么用处
5要实现一个接口,使用 implements 操作符。非抽象类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称
6可以同时继承抽象类和实现接口,extends要写在前面.
7抽象类实现接口,不需要重新其中的方法
8实现多个接口时,接口中的方法不能有重名
9接口也可以继承,通过使用 extends 操作符接口可以继承另一个或多个接口,使用extends关键字,多个用 ',' 隔开,但是不能实现另一个接口,当然更不能继承抽象类
10类要实现接口,必须使用和接口中所定义的方法完全一致的方式。否则会导致致命错误
 
 

三,特性:trait

 

1如果说:继承可以纵向扩展一个类,那么trait就是横向扩展一个类功能;trait不能被实例化

2trait在php5.4后才支持,是将trait里的代码copy一份到类中(理解这个可以避免很多错误)
3Trait、基类和本类对同名属性或方法的处理:Trait中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖Trait中同名的属性或方法
  (trait优先级:内部方法>trait>extend)
<?php
trait Dog{
public $name="dog";
public function drive(){
echo "This is dog drive";
}
public function eat(){
echo "This is dog eat";
}
} class Animal{
public function drive(){
echo "This is animal drive";
}
public function eat(){
echo "This is animal eat";
}
} class Cat extends Animal{
use Dog;
public function drive(){
echo "This is cat drive";
}
}
$cat = new Cat();
$cat->drive();//This is cat drive
$cat->eat(); //This is dog eat
?>

4一个类可以组合多个Trait,通过逗号相隔 use trait1,trait2

5当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名

<?php
trait trait1{
public function eat(){
echo "This is trait1 eat";
}
public function drive(){
echo "This is trait1 drive";
}
}
trait trait2{
public function eat(){
echo "This is trait2 eat";
}
public function drive(){
echo "This is trait2 drive";
}
}
class cat{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
}
}
class dog{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
trait2::eat as eaten;
trait2::drive as driven;
}
}
$cat = new cat();
$cat->eat();//This is trait1 eat
$cat->drive(); //This is trait1 drive
$dog = new dog(); 
$dog->eat(); //This is trait1 eat
$dog->drive(); //This is trait1 drive
$dog->eaten();//This is trait2 eat
$dog->driven(); //This is trait2 drive
?>

6as 还可以修改方法的访问控制

<?php
trait Animal{
public function eat(){
echo "This is Animal eat";
}
} class Dog{
use Animal{
eat as protected;//写成Animal::eat as protected 规范点
}
}
class Cat{
use Animal{
Animal::eat as private eaten;
}
}
$dog = new Dog();
$dog->eat();//报错,因为已经把eat改成了保护 $cat = new Cat();
$cat->eat();//正常运行,不会修改原先的访问控制
$cat->eaten();//报错,已经改成了私有的访问控制
?>

7Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等

<?php
trait Cat{
public function eat(){
echo "This is Cat eat";
}
} trait Dog{
use Cat;
public function drive(){
echo "This is Dog drive";
}
abstract public function getName(); public function test(){
static $num=0;
$num++;
echo $num;
} public static function say(){
echo "This is Dog say";
}
}
class animal{
use Dog;
public function getName(){
echo "This is animal name";
}
} $animal = new animal();
$animal->getName();//This is animal name
$animal->eat(); //This is Cat eat
$animal->drive(); //This is Dog Drive
$animal::say(); //This is Dog say
$animal->test(); //1
$animal->test(); //2
?>

PHP 抽象类、接口,traint详解的更多相关文章

  1. c#接口使用详解

    c#接口使用详解 c#中接口隐式与显示实现 c#中接口可以隐式实现.显示实现,隐式实现更常使用.显示实现较少使用 其区别在于 显示实现避免接口函数签名冲突 显示实现只可以以接口形式调用 显示实现其子类 ...

  2. “全栈2019”Java第五十九章:抽象类与抽象方法详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  3. Java语言Socket接口用法详解

    Socket接口用法详解   在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...

  4. Java之函数式接口@FunctionalInterface详解(附源码)

    Java之函数式接口@FunctionalInterface详解 函数式接口的定义 在java8中,满足下面任意一个条件的接口都是函数式接口: 1.被@FunctionalInterface注释的接口 ...

  5. SpringMVC(4.2):Controller接口控制器详解(2)

    原文出处: 张开涛 4.5.ServletForwardingController 将接收到的请求转发到一个命名的servlet,具体示例如下: package cn.javass.chapter4. ...

  6. WebApi 接口参数详解

    WebApi 接口参数不再困惑:传参详解   阅读目录 一.get请求 1.基础类型参数 2.实体作为参数 3.数组作为参数 4.“怪异”的get请求 二.post请求 1.基础类型参数 2.实体作为 ...

  7. 微信JS-SDK之图像接口开发详解

    由于现在手头的项目中有一个上传证件照认证的功能(手机端),之前的思路是直接点击上传,然后直接将图片上传到服务器去,这篇文章有讲到(http://www.cnblogs.com/it-cen/p/453 ...

  8. python接口自动化(六)--发送get请求接口(详解)

    简介 如果想用python做接口测试,我们首先有不得不了解和学习的模块.它就是第三方模块:Requests. 虽然Python内置的urllib模块,用于访问网络资源.但是,它用起来比较麻烦,而且,缺 ...

  9. SpringMVC(4.1):Controller接口控制器详解(1)

    原文出处: 张开涛 4.1.Controller简介 Controller控制器,是MVC中的部分C,为什么是部分呢?因为此处的控制器主要负责功能处理部分: 1.收集.验证请求参数并绑定到命令对象: ...

随机推荐

  1. 【tmos】spring data jpa 创建方法名进行简单查询

    参考链接 spring data jpa 创建方法名进行简单查询:http://www.cnblogs.com/toSeeMyDream/p/6170790.html

  2. L3-2 森森快递 (30 分)(贪心+线段树/分块)

    题目链接:https://pintia.cn/problem-sets/1108203702759940096/problems/1108204121661857798 题目大意: 森森开了一家快递公 ...

  3. package-lock.json和package.json区别

    package.json里面定义的是版本范围(比如^1.0.0),具体跑npm install的时候安的什么版本,要解析后才能决定,这里面定义的依赖关系树,可以称之为逻辑树(logical tree) ...

  4. 1173 - The Vindictive Coach

    题目大意:n个不同身高的队员和教练的按照身高排成波浪形……每个人按照身高由低到高编号,其中第m个是教练,他必须在第一个,如果条件允许,排第二的要比m低,如果条件不允许,即其余人都比教练高,则要让差距尽 ...

  5. Linux今日疑问

    问题一:who -r没有反应 ========== 首先我查询了运行等级的含义. 0: 关机 1: 单用户 2: 无网络的多用户 3: 命令行模式 4: 未用 5: GUI(图形桌面 模式) 6 : ...

  6. 【ARTS】01_17_左耳听风-20190304~20190310

    ARTS: Algrothm: leetcode算法题目 Review: 阅读并且点评一篇英文技术文章 Tip/Techni: 学习一个技术技巧 Share: 分享一篇有观点和思考的技术文章 Algo ...

  7. CentOS6.6 双网卡双网关配置

    1.需求: 内网IP:10.63.215.7 网关:10.63.215.254 外网IP:180.168.29.92 网关:180.168.29.89 内外网均可以Ping通,可直接访问 2.IP配置 ...

  8. Go语言中的slice

    Go语言中的slice有点类似于Java中的ArrayList,但在使用上更加灵活,先通过下面一个小例子来体验一下如何通过一个已有的切片来产生一个新切片: func main() { slice := ...

  9. html单选按钮用jQuery中prop()方法设置

    模拟单选按钮时用jQuery,prop方法来设置. 赋默认选中值:$("#" + id).find("input:radio[value='" + state ...

  10. 解决python发送multipart/form-data请求上传文件的问题

    服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...