И така, най-накрая започнах да си играя с черти и те са много удобни, проблемът, който имах е, че искам да имам някои черти, за да добавя функционалност към моите обекти с данни. Само по себе си това е просто, с изключение на това, че при това използвам методи, които са дефинирани в моя обект с основни данни
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
Тогава проблемът ми е, ако някой друг в екипа ми реши да използва чертата Extended_Object
върху обект, който не разширява Base_Object
. Мислех да поставя отметка в метода _addToUpdate
, но в идеалния случай бих искал да се показва грешка при създаването на екземпляра.
Измислих решение, което работи, но ме кара да се чувствам малко мръсен и е далеч от идеалното
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
abstract protected function _addToUpdate($field, $value);
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
Чрез добавяне на абстрактен метод към Extended_Object
мога поне да съм сигурен, че ще се покаже грешка, ако методът, от който се нуждая в Base_Object
, не присъства, но не съм гарантиран, че въпросният метод действително ще направи това, което искам да направи.
В идеалния случай бих искал да мога да стартирам нещо като кода по-долу, когато даден обект се инстанцира с помощта на чертата Extended_Object
if (!($this instanceof Base_Object)) {
throw new Inheritance_Exception("Base_Object");
}
Надявам се, че някой е намерил начин да направи това или поне по-добро решение от моето.
Забележка: знам, че бих могъл да направя това с конструктор, но това би било жизнеспособно само при използване на една характеристика, ако реша на по-късна дата да създам още няколко черти за разширение на обект, ще стане много объркващо много бързо
Редактиране: осъзнавам, че характеристиките наистина не са предназначени за това, което се опитвам да направя, но те поне отчасти ми позволяват да заобиколя проблема с единичното наследяване и знам, че не съм единственият разработчик, който планира използвайте ги по този начин