Пожалуйста, обратите внимание, что прошло много времени с тех пор, как я попробовал свои силы в php и oop …
Я хочу помочь своему партнеру следить за нашей огромной коллекцией карт Magic: The Gathering.
В Magic, как правило, карты выпускаются в блоках расширения. Внутри блока есть три расширения. Первое расширение имеет то же имя, символ и т. Д., Что и весь блок, они на самом деле более или менее одинаковы, но я хочу провести различие между Блоком и Расширением в моем коде.
В то же время я хотел бы избежать ввода одной и той же информации дважды при добавлении первого расширения в блок;
$block = new Block('Innistrad', 'isd', '130927');
$exp = $block->addExpansion(new Expansion('Innistrad', 'isd', '130927')); // not DRY!
$firstExp = $block->addExpansion(new Expansion('Innistrad')); // This is more DRY, only name is needed
Все расширения имеют ту же дату ротации, что и блок. Это мне удалось установить в методе addExpansion (Expansion $ exp);
$exp->rotationDate = $this->rotationDate;
Каким-то образом я хотел бы добавить условие в конструктор Expansion, чтобы сравнить имя расширения с именем блока. Если они равны, символ раскрытия совпадает с символом блока, иначе символ раскрытия устанавливается в методе конструктора. Я пытался использовать $block = get_parent_class($this);
а потом $this->name == $block->name
как условие, но (конечно?) это не сработало, как ожидалось, и символ расширения «input» имеет значение null? Вместо «isd.png» символом является «.png».
Notice: Trying to get property of non-object in - on line 178
Expansion Object
(
[name:protected] => Innistrad
[symbol:protected] => .png
[rotationDate] => 130927
)
«Полный» код с классами и комментариями, где я попробовал и потерпел неудачу …
// BLOCK
class Block {
protected static $imgType = '.png';
protected $name;
protected $symbol;
public function __construct($name, $symbol, $rotationDate) {
$this->name = $name;
$this->symbol = $symbol.self::$imgType;
$this->rotationDate = $rotationDate;
}
public function addExpansion(Expansion $exp) {
$exp->rotationDate = $this->rotationDate;
return $exp;
}
}
// EXPANSION
class Expansion extends Block {
public function __construct($name, $symbol = null) {
$this->name = $name;
$block = get_parent_class($this); // this is what I tried, the principle of what I try to achieve
if ($this->name == $block->name) {
// if the instantiated child object has the same name as the parent object, "adopt" the parent object's properties
$this->symbol = $block->symbol;
}
else {
$this->symbol = $symbol.parent::$imgType;
}
}
}
$block = new Block('Innistrad', 'isd', '130927');
$exp = $block->addExpansion(new Expansion('Innistrad'));
print_r($exp);
Вы издеваетесь над ребенком — родителем здесь. Если вы создаете Expansion
есть только один объект, Expansion
сам. Расширение родительского класса не означает instance
из родительского будет создан, это просто делает, что дочерний класс наследует все функциональные возможности родительского класса.
Вы должны изменить свой addExpansion
метод и построить свой Expansion
что-то вроде этого:
public function addExpansion(Expansion $exp) {
$exp->setParentBlock($this);
$exp->rotationDate = $this->rotationDate;
return $exp;
}
class Expansion extends Block {
private $parent = null;
public function setParentBlock(Block $b) {
$this->parent = $b;
}
public function __construct($name, $symbol = null) {
$this->name = $name;
//create getName() because u can't access protected outside the class
if ($this->parent != null && $this->name == $parent->getName()) {
// if the instantiated child object has the same name as the parent object, "adopt" the parent object's properties
$this->symbol = $block->symbol;
}
else {
$this->symbol = $symbol.parent::$imgType;
}
}
}
Я думаю, что я случайно решил свою проблему. Вместо того, чтобы указывать условие if в конструкторе Expansion, я помещаю его в метод addExpansion () класса Block. Это дает желаемый результат «принятых» значений свойств, но я не уверен, является ли это правильным решением.
// BLOCK
class Block {
protected static $imgType = '.png';
protected $name;
protected $symbol;
protected $rotationDate;
public function __construct($name, $symbol, $rotationDate) {
$this->name = $name;
$this->symbol = $symbol.self::$imgType;
$this->rotationDate = $rotationDate;
}
public function addExpansion(Expansion $exp) {
$exp->rotationDate = $this->rotationDate;
if ($exp->name == $this->name) { // if Expansion name equals Block name
$exp->symbol = $this->symbol; // use Block symbol as Expansion symbol
}
return $exp;
}
}
// EXPANSION
class Expansion extends Block {
public function __construct($name, $symbol = null) {
$this->name = $name;
$this->symbol = $symbol.parent::$imgType;
}
}
$block = new Block('Innistrad', 'isd_exp_symbol', '20130927');
$exp = $block->addExpansion(new Expansion('Innistrad'));
print_r($exp);
Возвращает:
Expansion Object
(
[name:protected] => Innistrad
[symbol:protected] => isd_exp_symbol.png
[rotationDate:protected] => 20130927
)
Я отвечаю, потому что думаю, что есть проблема с решением @ DarkBee, но у меня недостаточно репутации, чтобы комментировать, поэтому вместо этого я предложу полное решение (проблема в том, что $ this-> parent всегда будет нулевым в конструктор Expansion, потому что setParentBlock не вызывается до окончания строительства).
Я скептически отношусь к тому, что вам нужен класс Expansion для расширения класса Block, но я все равно оставил это — он работает так же хорошо (лучше IMO), если вы закомментируете «extends Block». Любые вопросы, не стесняйтесь спрашивать.
// BLOCK
class Block {
protected static $imgType = '.png';
protected $name;
protected $symbol;
protected $expansions = array();
public function __construct($name, $symbol, $rotationDate) {
$this->name = $name;
$this->symbol = $symbol.self::$imgType;
$this->rotationDate = $rotationDate;
}
public function addExpansion($name, $symbol = null) {
// We only have room for 3 expansions.
if (count($this->expansions) >= 3) return null;
// If the expansion to be created and added to this block has the
// same name as this block, or if no symbol is supplied,
// then "adopt" this block's symbol.
$symbol = ($name == $this->name || $symbol === null)
? $this->symbol
: $symbol.self::$imgType;
$exp = new Expansion($name, $symbol, $this->rotationDate);
$this->expansions[] = $exp;
return $exp;
}
}
// EXPANSION
class Expansion extends Block {
public function __construct($name, $symbolWithType, $rotationDate) {
$this->name = $name;
$this->symbol = $symbolWithType;
$this->rotationDate = $rotationDate;
}
}
$block = new Block('Innistrad', 'isd', '130927');
$exp = $block->addExpansion('Innistrad');
print_r($exp);