Что такое parent :: scope для черты - PullRequest
0 голосов
/ 27 января 2020

У меня есть класс MyClass, который использует черту MyTrait. У обоих из них есть метод getName () (MyClass наследует его от MyParentClass).

Какой будет родительская область действия для MyTrait :: getName ()? Как правильно вызывать MyClass :: getName () и MyParentClass :: getName () в контексте MyTrait?.

См. Код ниже для справки.

trait MyTrait {
   public function getName() : string
   { 
       return parent::getName() . '_special';
   }
}

class MyParentClass {
   public function getName(): string
   {
      return "MyName";
   }
}
class MyClass extends MyParentClass {
   use MyTrait;

}

Ответы [ 2 ]

1 голос
/ 28 января 2020

Методы черты действуют так, как они объявлены в классе с использованием черты, т.е.

trait MyTrait {
   public function getName() : string
   {
       return parent::getName() . '_special';
   }
}

class MyClass extends MyParentClass {
   use MyTrait;

}

Функционально совпадает с

class MyClass extends MyParentClass {
   public function getName() : string
   {
       return parent::getName() . '_special';
   }
}

Должно быть понятно, что в этом случае parent относится к MyParentClass. Если есть какие-либо сомнения, используя следующий код:

<?php

trait MyTrait {
   public function getName() : string
   {
       return parent::getName() . '_special';
   }
}

class MyParentClass {
   public function getName(): string
   {
      return "MyName";
   }
}
class MyClass extends MyParentClass {
   use MyTrait;

}

$instance = new MyClass();

echo $instance->getName();

Создает следующий вывод:

MyName_special

Это может быть дополнительно проверено / продемонстрировано с использованием return parent::class; ( ref ) в методе trait, который возвращает MyParentClass.

0 голосов
/ 28 января 2020

Вам необходимо определить метод getName() в вашем подклассе. Согласно руководству , прецедент для черт:

Унаследованный член от базового класса переопределяется членом, вставленным Чертой. Порядок приоритета состоит в том, что члены текущего класса переопределяют методы Trait, которые, в свою очередь, переопределяют унаследованные методы.

Это означает, что, поскольку в вашем подклассе нет метода getName(), метод trait имеет приоритет, переопределяя родительский метод. С методом getName() в подклассе он имеет приоритет.

Таким образом, вам нужно будет сделать что-то вроде следующего, обратите внимание на псевдоним метода getName() в использовании черты:

trait MyTrait {
    public function getName() : string
    {
        return parent::getName() . '_special';
    }
}

class MyParentClass {
    public function getName(): string
    {
        return "MyName";
    }
}
class MyClass extends MyParentClass {
    use MyTrait {
        MyTrait::getName as getTraitName;
    }

    public function getName(): string
    {
        return parent::getName();
    }
}

$myClass = new MyClass();
var_dump($myClass->getName()); //string(6) "MyName"
var_dump($myClass->getTraitName()); //string(14) "MyName_special"
...