I just went through this exact thing. You don't need to extend it. Make a class that holds SimpleXMLElement objects. I believe this is what Nikola meant.
class XmlResultSet
{
public $xmlObjs = array();
public function __construct(array $xmlFiles)
{
foreach ($xmlFiles as $file) {
$this->xmlObjs[] = new XmlResult($file);
}
}
}
class XmlResult
{
private $xmlObj;
public function __construct($file)
{
try {
$this->xmlObj = new SimpleXMLElement($file, 0, true);
}
catch (Exception $e) {
throw new MyException("Invalid argument ($this)($file)(" . $e .
")", PHP_ERRORS);
}
}
public function otherFunctions()
{
return $this->xmlObj->movie['name']; // whatever
}
}
Answer from vcardillo on Stack OverflowI just went through this exact thing. You don't need to extend it. Make a class that holds SimpleXMLElement objects. I believe this is what Nikola meant.
class XmlResultSet
{
public $xmlObjs = array();
public function __construct(array $xmlFiles)
{
foreach ($xmlFiles as $file) {
$this->xmlObjs[] = new XmlResult($file);
}
}
}
class XmlResult
{
private $xmlObj;
public function __construct($file)
{
try {
$this->xmlObj = new SimpleXMLElement($file, 0, true);
}
catch (Exception $e) {
throw new MyException("Invalid argument ($this)($file)(" . $e .
")", PHP_ERRORS);
}
}
public function otherFunctions()
{
return $this->xmlObj->movie['name']; // whatever
}
}
I would use Delegate wrapper design in this case. You should consider composition instead of inheritance here.
I have often read that classes should only be made 'final' on rare/special occasions.
Whoever wrote that is wrong. Use final liberally, there’s nothing wrong with that. It documents that a class wasn’t designed with inheritance in mind, and this is usually true for all classes by default: designing a class that can be meaningfully inherited from takes more than just removing a final specifier; it takes a lot of care.
So using final by default is by no means bad. In fact, amongst OOP experts it’s widely agreed that final should be the default, e.g. Jon Skeet:
Classes should be sealed by default in C#
Or Joshua Bloch:
Design and document for inheritance or else prohibit it [Effective Java, 3rd Ed, Item 19]
Or Scott Meyers [More Effective C++, Item 33].
Which is why modern OO langauges such as Kotlin have final-by-default classes.
You wrote:
Maybe it screws up Mock object creation …
And this is indeed a caveat, but you can always recourse to interfaces if you need to mock your classes. This is certainly superior to making all classes open to inheritance just for the purpose of mocking.
If you want to leave a note to yourself that a class has no sub-classes, then by all means do so and use a comment, thats what they are for. The "final" keyword is not a comment, and using language keywords just to signal something to you (and only you would ever know what it means) is a bad idea.
edited by original author to add: I completely disagree with this now. I cannot even create a model of my mental state 11 years ago that would explain why I would say this. I think this answer, and my comments defending it below, are ridiculous. The accepted answer is right.