• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

第6章 0424-类与对象

Data: 2019-10-05 20:30:39Form: JournalClick: 12

问题集合:

1.  现在的PHP是强类型语言了吗?

答:声明变量前, 不加类型的, 都是弱类型,如 String aaa; int num , 这才是强类型, 强类型需要进行预编译, 不能边解释边执行, 不像脚本语言

2.  我发现了一个细节问题   以前 JS 不管什么时候结束都要带个 ;  号  现在PHP不用了。  函数结束不用了 类结束也不用了?

答:同学, 你恰好说反了,  

js语句中的分号是可选的

php语言必须加分号

声明函数,类不算语言,只是代码块, 例如if , while也不加分号, 任何语言都一样的


demo1:文件加载

<?php
// 文件包含
// 本质: 将目录文件复制到当前位置
 
// 1. include
include __DIR__ . '/inc/f1.php';
// $username = '猪老师';
// 被包含文件共享作用域
echo $username . '<br>';
 
// echo $email . '<br>';
$email = include __DIR__ . '/inc/f1.php';
echo $email . '<hr>';
 
// 2. require
require __DIR__ . '/inc/f1.php';
 
echo $username . '<br>';
 
$email = require __DIR__ . '/inc/f1.php';
echo $email . '<br>';
 
// 3. include,require区别
// 区别1
// include: 用到时再加载, 动态
// require: 应该写到顶部, 静态
 
if (false) include __DIR__ . '/inc/f2.php';
echo $site . '<br>';
if (false) require __DIR__ . '/inc/f2.php';
echo $site . '<br>';
 
//  区别2
// include: 加载失败,继续执行不中断
// requrie: 加载失败,中断退出
 
// include __DIR__ . '/inc/hello.php';
@include __DIR__ . '/inc/hello.php';
 
echo 'include后面的代码' . '<br>';
 
require __DIR__ . '/inc/hello.php';
 
echo 'require后面的代码' . '<br>';
 
// include_once: 只包含一次
// require_once: 只包含一次
 
demo4:类与实例
<?php
 
/**
 * 类与实例
 * 1. class
 * 2. new
 */
 
// 类声明
// 1. class
class Goods
{
    // ...
}
 
// 类的实例化: 创建对象的过程, new
$goods = new Goods;
var_dump($goods);
 
// 车: class
// 轿车: obj
// get_class 返回对象的类名
 
echo '<hr>';
 
echo get_class($goods) . '<br>';
 
// 动态类
$str = 'goods';
 
// 大驼峰/帕斯卡
// 把小写转换成大写名称
$class = ucfirst('goods');
// echo $class;
 
$o = new $class;
var_dump($o);
 
var_dump($o instanceof Goods);
 
// typeof
 
demo5:类成员
<?php
 
/**
 * 类成员
 * (一) 常规成员
 *  1. 属性: 可以被其它方法所共享
 *  2. 方法: 自定义, 魔术方法
 *
 * 访问限制符:
 *  1. private: 私有,仅限在当前类中使用
 *  2. protected: 继承, 可在本类或子类中使用, 不对外公开
 *  3. public: 公共/公共,默认
 *
 * (二) 静态成员
 *  1. static, 静态属性, 静态方法
 *  2 . 与类实例无关, 静态成员 不要用$this
 *  3 . 内部用self, 外部用类名
 *  
 */
 
class User1
{
    // 常规成员
    // 1. 属性
    // 语法: 访问限制符 类成员声明
    // 声明为私有, 实现封装
    private $username;
 
    // 2. 方法
    // 2.1 自定义方法: 用户自己声明自己调用
    public function getUsername()
    {
 
        // -> 对象成员访问符
        // 当前实例的引用, $this 与实例绑定的
        return $this->username;
    }
 
    // 2.2 魔术方法: 由系统来调用,用户不能直接调用
    // 构造方法: 实例化进自动调用
    public function __construct(string $username)
    {
        $this->username = $username;
    }
}
 
// 实例化
$user1 = new User1('张老师');
echo $user1->getUsername();
 
echo '<hr>';
 
class User2
{
    // 静态属性
    private static $username = 'admin';
 
    // 类常量: 与实例无关,用类访问
    const APP = '商城';
 
    // 方法
    public static function getUsername()
    {
 
        // self: 功能与$this类似, 与当前类 User2 绑定
        return self::$username;
    }
}
 
// 实例访问静态方法是一个兼容bug, 能成功,但不要再用了
// echo (new User2)->getUsername();
// 应该永远用类来访问静态成员
echo User2::getUsername();
echo User2::APP;
 
demo6:类的扩展/抽象/最终
<?php
 
/**
 * 类的扩展/抽象/最终
 * 1. protected: 受保护/可继承
 * 2. extends: 扩展/继承
 * 3. parent: 父类引用
 * 4. abstract: 抽象
 * 5. final: 最终类
 */
 
// 父类, 基类, 超类
class Person
{
    // protected: 成员可继承,可以在子类中使用
    protected $name;
    // private: 私有, 仅限当前类, 子类,外部都不可见
    private $id = 12345;
    // public: 类中,子类, 类外都可见
    public function __construct($name)
    {
        $this->name = $name;
    }
 
    // getInfo::protected
    // 比protected再严格的是 private, 比它更宽松的是: public
    protected function getInfo()
    {
        return $this->name;
    }
}
 
// 学生类
// extends: Stu这个类,扩展了Person类的功能
class Stu extends Person
{
    // 1. 属性扩展
    private $lesson;
    private $score;
 
    // 2. 方法扩展/重写
    public function __construct($name, $lesson, $score)
    {
        // 引用了父类的构造方法
        // parent: 父类引用 Person
        parent::__construct($name);
        $this->lesson = $lesson;
        $this->score = $score;
    }
 
    public function getInfo()
    {
        // $this->name
        // return $this->name . "同学, ($this->lesson : $this->score 分)";
        return parent::getInfo() . "同学, ($this->lesson : $this->score 分)";
    }
}
 
$stu = new Stu('小狗', 'PHP', 88);
echo $stu->getInfo();
 
echo '<hr>';
$person = new Person('小猪');
// var_dump只打印属性
var_dump($person);
echo '<hr>';
 
// 如果不想让用户直接使用父类,而必须通过继承/扩展的子类来间接使用
// 将父类声明为一个抽象类
abstract class Demo1
{
}
 
// (new Demo1);
 
class Demo2 extends Demo1
{
}
//返回当前脚本中已声明类的名称
echo 'Demo2的父类是: ' . get_parent_class(new Demo2);
 
echo '<hr>';
 
abstract class Demo3
{
    // hello 方法已经被实现了
    // protected function hello()
    // {
    //     // ...
    // }
    //程序中,有些类的作用只是用来继承,无须实例化;
    //为了满足类的这种需求,php提供了抽象类的概念 ,关键词abstract;
    // 抽象方法: 只有方法名,参数列表,没有具体实现(大括号)
    // 抽象类不能被实例化
    // 有抽象方法的类一定是抽象类;类必须要abstract修饰
    // 抽象方法不能有函数体;即abstract function fun();
    // 抽象类中的非抽象方法,可以被子类调用
    // 非抽象子类继承抽象类,子类必须实现父类的所有抽象方法
    // 抽象子类继承抽象类,无需继承父类的抽象方法
    abstract protected function hello($name);
}
 
class Demo4 extends Demo3
{
    // 工作类Demo4中必须实现父类中的抽象成员
    public function hello($name)
    {
        return 'Hello , ' . $name;
    }
}
// call_user_func 调用类下的 hello方法,并替换参数传递
echo call_user_func([new Demo4, 'hello'], '牛老师');
 
echo '<hr>';
 
// 如果一个类不用扩展,直接当成工作类/直接干活的,直接new
// 为了防止被继承, 可声明为最终类
// final class Demo5
// {
// }
 
// class Demo6 extends Demo5
// {
// }


 
//抽象类的具体说明
//作用:抽象类不实现具体方法,具体方法由子类完成。
//定义抽象类 abstract
abstract class A{
    //abstract 定义抽象类的方法,这里没有花括号。子类必须实现这个抽象方法。
    abstract public function say();
    //抽象类可以有参数
    abstract public function eat($argument);
    //在抽象类中可以定义普通的方法。
    public function run(){
      echo '这是run方法';
    }
}
class B extends A{
//子类必须实现父类的抽象方法,否则是致命的错误。
public function say(){
    echo '这是say方法,实现了抽象方法';
}
public function eat($argument){
    echo '抽象类可以有参数 ,输出参数:'.$argument;
}
}
$b =new B;
$b->say();
echo '<br>';
$b->eat('apple');
echo '<br>';
$b->run();
 
demo7:接口: 大号的抽象类
<?php
// 接口: 大号的抽象类
// 接口的所有成员,必须是抽象
// interface: 声明接口
// implements: 实现接口
interface iUser
{
    // 1. 类常量
    const NATION = 'CHINA';
 
    // 2. 必须是抽象,必须是public
    public function m1();
    public function m2();
 
    // 官方手册: 不建议声明抽象构造方法
}
 
// 接口不能直接用, 要用一个类来实现它
 
// 1. 用普通类来实现一个接口, 必须将接口中的所有抽象方法全部实现
class Demo1 implements iUser
{
    public function m1()
    {
    }
    public function m2()
    {
    }
}
 
// 2. 用抽象类来实现一个接口, 允许有不实现的抽象成员
abstract class Demo2 implements iUser
{
    public function m1()
    {
    }
}
 
// php默认只支持单继承
// class A extends B, C , D
 
// 可通过接口,间接实现多继承
interface A
{
}
interface B
{
}
interface C
{
}
 
class Test implements A, B, C
{
}
 
// 查看当前类实现的所有接口
$arr = class_implements('Test');
 
printf('<pre>%s</pre>', print_r($arr, true));


 
// 本文实例讲述了PHP接口类(interface)的定义、特点和应用。分享给大家供大家参考,具体如下:
 
// 一、接口的定义:
// 简单形象的说,接口是类的模板,定义实现它的类需要实现哪些功能。
 
// 二、接口的特点:
// 接口通过&ldquo;interface&rdquo;关键词来定义;
// 上下级接口可以通过&ldquo;extends&rdquo;关键词继承;
// 接口所有方法都是&ldquo;public&rdquo;权限(爱E族);
// 接口可以定义常量成员,但不能定义变量成员;
// 类通过&ldquo;implements&rdquo;关键词来实现接口,类必须完全实现接口定义的所有功能;
// 一个类可以同时&ldquo;implements&rdquo;(实现)一个到多个接口;
 
// 三、为什么需要接口:
//   PHP 类是单继承,也就是不支持多继承,当一个类需要多个类的功能时,继承就无能为力了,为此 PHP 引入了类的接口技术。
 
// 四、举例:
 
// 1、定义一个接口:
//   早些年的博客网站,都有一个发布文章的功能,比如你现在看到的就是一篇介绍接口的文章,下面我们定义一个文章接口:
 
//定义一个文章接口
interface Article {
  //接口中有一个发布文章的接口
  public function publishArticle();
}
interface Ask {
  public function question();
  public function answer();
}
 
// 2、接口的继承:
//   后来随着社交网络的兴起,很多网站的文章多了一个转发功能,文章模块功能升级了,我们把它叫做文章2.0&ldquo;Article2&rdquo;,&ldquo;Article2&rdquo;继承了Article的发布文章功能:
 
//定义Article2接口,继承Article接口
interface Article2 extends Article {
  //Article2接口比Article多了一个转发文章功能(爱E族)
  public function relayArticle();
}
 
// 3、接口的实现(接口的应用):
//   上面的接口已经定义好了,现在我们要实现接口了,比如就说您现在访问的网站爱E族(aiezu.com)吧,它既有发布文章功能,又有问答功能。所以我们的类Aiezu(爱E族)要同时两个接口:&ldquo;Article&rdquo;,&ldquo;Ask&rdquo;。
 
//Aiezu(爱E族)类要实现Article(文章)和问答(Ask)接口功能
class Aiezu implements Article,Ask {
  public function publishArticle() {
    echo "发布了一篇文章\n";
  }
  public function relayArticle() {
    echo "转发了一篇文章\n";
  }
  public function question() {
    echo "发表了一个问题\n";
  }
  public function answer(){
    echo "回答一个问题\n";
  }
}
$aiezu = new Aiezu();
$aiezu->relayArticle();
$aiezu->question();
// 注意,Aiezu类必须完全实现&ldquo;Article&rdquo;接口和&ldquo;Ask&rdquo;接口的所有功能,否则会报告下面错误:
// PHP Fatal error:  Class Aiezu contains 1 abstract method and must therefore be declared
// abstract or implement the remaining methods (Article::publishArticle) in /tmp/xxx.php on line xxx
 
Name:
<提交>