如何覆盖性状功能和重写的函数调用它呢?(How to override trait function

2019-06-17 17:17发布

场景:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A;

    function calc($v) {
        $v++;
        return A::calc($v);
    }
}

print (new MyClass())->calc(2); // should print 4

此代码不能正常工作,我无法找到一个方法来调用一个函数特征就像是继承。 我试着给self::calc($v) static::calc($v) parent::calc($v) A::calc($v)及以下内容:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as traitcalc;
    }

    function calc($v) {
        $v++;
        return traitcalc($v);
    }
}

没有什么作品。

有没有一种方法,使工作或我必须完全覆盖特征函数,它是比这要复杂得多:)

Answer 1:

你的最后一个几乎有:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    use A {
        calc as protected traitcalc;
    }

    function calc($v) {
        $v++;
        return $this->traitcalc($v);
    }
}

性状是不是一类。 你不能将它的成员直接访问。 它基本上只是自动复制和粘贴...



Answer 2:

如果该类直接实现方法,它不会使用的特点版本。 也许你在想什么的是:

trait A {
    function calc($v) {
        return $v+1;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}

class MyChildClass extends MyClass{
}

class MyTraitChildClass extends MyClass{
    use A;
}

print (new MyChildClass())->calc(2); // will print 4

print (new MyTraitChildClass())->calc(2); // will print 3

因为子类都不能直接实现的方法,他们将首先使用特质的,如果有以其他方式使用父类的。

如果你想,性状可以用在父类的方法(假设你知道的方法将在那里)如

trait A {
    function calc($v) {
        return parent::calc($v*3);
    }
}
// .... other code from above
print (new MyTraitChildClass())->calc(2); // will print 8 (2*3 + 2)

您也可以提供各种方法来覆盖,但仍可访问特性的方法如下:

trait A {
    function trait_calc($v) {
        return $v*3;
    }
}

class MyClass {
    function calc($v) {
        return $v+2;
    }
}


class MyTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }
}


class MySecondTraitChildClass extends MyClass{
    use A {
      A::trait_calc as calc;
    }

    public function calc($v) {
      return $this->trait_calc($v)+.5;
    }
}


print (new MyTraitChildClass())->calc(2); // will print 6
echo "\n";
print (new MySecondTraitChildClass())->calc(2); // will print 6.5

你可以看到它在工作http://sandbox.onlinephpfunctions.com/code/e53f6e8f9834aea5e038aec4766ac7e1c19cc2b5



Answer 3:

如果有兴趣的另一种方法 - 用一个额外的中级班正常使用的方式OOO。 这简化了与父:: methodName的用法

trait A {
    function calc($v) {
        return $v+1;
    }
}

// an intermediate class that just uses the trait
class IntClass {
    use A;
}

// an extended class from IntClass
class MyClass extends IntClass {
    function calc($v) {
        $v++;
        return parent::calc($v);
    }
}


Answer 4:

使用另一种特质:

trait ATrait {
    function calc($v) {
        return $v+1;
    }
}

class A {
    use ATrait;
}

trait BTrait {
    function calc($v) {
        $v++;
        return parent::calc($v);
    }
}

class B extends A {
    use BTrait;
}

print (new B())->calc(2); // should print 4


文章来源: How to override trait function and call it from the overridden function?
标签: php traits