美文网首页
父类实现调用子类的方法

父类实现调用子类的方法

作者: 云龙789 | 来源:发表于2019-04-12 18:05 被阅读0次
<?php

class Test
{

    public function getAge()
    {
        static::getName();
    }

}


class Person extends Test
{
    protected function getName()
    {
        echo 'person';
    }
}

$person = new Person();
$person->getAge();  // person

被调用的函数 getName 的修饰符可以是 public 或者 protected,但是不能使用 private

大家要明白类与对象的区别。实例化后才是对象。static 是针对的当前的类。$person->getAge(); 中,static 就是指的 Person

<?php

class ParentClass
{
    protected static $instance;

    public function __construct()
    {
        echo 'construct';
        echo '<br>';
    }

    public static function getInstance()
    {
        if (self::$instance) {
            return self::$instance;
        }
        return self::$instance = new static();
    }

    public function getName()
    {
        echo ('ParentClass');
        echo '<br>';
    }
}

class ChildClass extends ParentClass
{
    public function getAge()
    {
        echo 'age';
        echo '<br>';
    }

    public function getName()
    {
        echo ('ChildClass');
        echo '<br>';
    }

}

ChildClass::getInstance()->getName();
ChildClass::getInstance()->getName();
ChildClass::getInstance()->getName();

image.png

但是还要注意一种现象

<?php

class ParentClass
{

    protected static $instance;

    public function __construct()
    {
        echo 'construct';
        echo '<br>';
    }

    public static function getInstance()
    {
        if (self::$instance) {
            return self::$instance;
        }
        return self::$instance = new static();
    }

    public function getName()
    {
        echo ('ParentClass');
        echo '<br>';
    }
}

class ChildClass extends ParentClass
{
    public function getName()
    {
        echo ('ChildClass1');
        echo '<br>';
    }
}

class ChildClass2 extends ParentClass
{
    public function getName()
    {
        echo ('ChildClass2');
        echo '<br>';
    }
}

ChildClass::getInstance()->getName();
ChildClass::getInstance()->getName();

ChildClass2::getInstance()->getName();
ChildClass2::getInstance()->getName();
image.png

如果将父类做个调整

class ParentClass
{
    public function __construct()
    {
        echo 'construct';
        echo '<br>';
    }

    public static function getInstance()
    {
        static $instance;
        if ($instance){
            return $instance;
        }
        return $instance = new static();
    }

    public function getName()
    {
        echo('ParentClass');
        echo '<br>';
    }
}

或者


    protected static $instance;

    public static function getInstance()
    {
        if (self::$instance instanceof static){
            return self::$instance;
        }
        return self::$instance = new static();
    }

或者

        if (self::$instance instanceof static) {
            return self::$instance;
        }
        return self::$instance = new static();

类型运算符

instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例:

image.png

这是因为 public static function getInstance() 针对的是当前的类,哪个类使用,就是谁。
new static(); 也是针对的当前类

public static function getInstance()
    {
        static $instance;
        if ($instance){
            return $instance;
        }
        return $instance = new static();
    }
 static $instance;  作用域当前类中的 getInstance 方法

而 protected static $instance; 的作用域是谁继承谁都可以读取这个方法。当 ChildClass 读取后,赋值了,ChildClass2 也可以赋值

但实际中我们会发现上面的方案并不能帮助我们解决问题,如果A类 getInstance() 之后,另一个类B,再使用 getInstance() 方法,A如果再次调用,发现又会重新实例化一次。而,首次实例化之后赋值的数据又会清空,又相当于是首次实例化。只有A getInstance() 之后,后面没有其他类使用此方法,这个实例化才会是单利.

<?php

class Base
{

    private static $instance;

    /**
     *  获取当前类
     * @return static
     */
    public static function getInstance()
    {
        if (self::$instance instanceof static) {
            return self::$instance;
        }
        echo '1' . '<br>';
        echo '<br>';
        return self::$instance = new static();
    }

    public static function getIn()
    {
        var_dump(self::$instance);
    }
}

class A extends Base
{
    public function get()
    {
        echo 'a' . '<br>';
    }
}

class B extends Base
{
    public function get()
    {
        echo 'b' . '<br>';
    }
}

A::getInstance()->get();
B::getInstance()->get();
Base::getIn();
B::getInstance()->get();
A::getInstance()->get();
B::getInstance()->get();
A::getInstance()->get();
图片.png
  • 解决方案就是将 $instance 做成一个数组,当前类如果已经实例化过了,则直接返回上次示例话的数据
    /**
     *  获取当前类
     * @return static
     */
    public static function getInstance()
    {
        if (isset(self::$instance[get_called_class()]) && self::$instance[get_called_class()] instanceof static) {
            return self::$instance[get_called_class()];
        }
        echo '1' . '<br>';
        var_dump(get_called_class());
        echo '<br>';
        return self::$instance[get_called_class()] = new static();
    }
图片.png

特别函数

get_called_class() 是系统自带函数,得到的是子类的类名,(此DEMO表示A,B)
  get_class(); 得到的是当前类,此demo  得到的是 Base

相关文章

  • iOS 小知识点总结

    子类实现父类方法时,监测子类是否调用super方法。 在父类中声明方法时: 子类中实现该父类方法: 图片压缩

  • scala 调用java通过父类调用子类方法实现

    scala 调用java通过父类调用子类方法实现 java 父类 A 抽象类: java 子类 B 继承A类,并...

  • javascript设计模式-抽象工厂模式

    目的:对子类实现进行规范,防止因子类没实现调用了父类的方法,所以当调用父类方法时,抛出异常

  • iOS 父类调用子类的方法

    在子类实现父类的方法,当父类调用子类的方法的时候,就可以了,但是父类也需要实现该方法,我懂了

  • iOS开发坑01-KVO

    01.UIView 实现了KVO监听回调方法,子类在实现则无法调用父类方法,直接走了父类,需要实现 super调用...

  • Objective-c 子类继承父类私有方法

    笔记: 在OC中 如果子类重写了父类的私有方法,父类不会再调用本类的实现,而是直接调用子类的实现。切记,切记。

  • 继承使用注意

    子类不能定义与父类同名的成员变量 子类可以重写父类的成员方法(覆盖父类的实现) 可以用super指针调用父类的实现...

  • OC 中子类如何调用父类的私有方法

    OC中能实现子类调用父类的私有方法吗? 调用父类的私有方法无非是想做两种操作:1.父类的实现完全不适用于子类(需完...

  • 模板方法模式

    模板方法模式 父类抽象出子类共有的方法,并且自己实现他子类实现各自不同的业务父类实现的方法按照一定的逻辑调用抽象方...

  • python 面向对象: super()

    python 关于 super 的使用 子类对象调用父类方法 :super(B,b).hh() 子类中调用父类方法...

网友评论

      本文标题:父类实现调用子类的方法

      本文链接:https://www.haomeiwen.com/subject/ghrhwqtx.html