简体   繁体   中英

Limit what classes can extends another class

I'm currently writing a solution that contains some abstract classes. One of these should only be extended from a few other classes as using it from other places than intended could cause a little bit of a mess. So what I want to do is limit what classes can extend this class.

So if I have a class named ImportantStuff which is abstract I want to say that only Class A and Class B are able to extend it while any other class can't.

You might wonder why I would want to do something like this. Well the code is written for work so there will be lots of other programmers working with it later, so I wish to make it clear for those that this class is not intended to be used from any other places than it already is. Yes I know I can write it in a class description and I have, but I want to make it 100% clear by blocking it as not all programmers are good at reading comments:) Also I'm kinda curious if it can be done in a good fashion as I couldn't find a good answer on the web.

So my question is: what is the best way to make this happen? I guess I can send a key or something that is handled in the constructor, but is there a cleaner way to do this?

hmmm, make the constructor final (but add an init function) and check there which class is currently constrcuted, thats possbilie, but requires at least php 5.3

    abstract class bigOne{
        private $_allowedClasses = array('smallOne');

        final public function __construct() {
            if(!in_array(get_called_class(), $this->_allowedClasses)){
                throw new Exception('can not extend to Class: ' . get_called_class());
            }
            $this->init();
        }

        abstract public function init();
    }

    class smallOne extends bigOne{
        public function init(){

        }
    }

    class badOne extends bigOne{
        public function init(){

        }
    }

    $oSmallOne = new smallOne();
    $obadOne = new badOne();

Possible solution for PHP 5.3+ only :

class Toto {
    function __construct() {
        // list of classes that can extend Toto, including itself obviously:
        if(!in_array(get_called_class(), array(__CLASS__, 'Foo')))
            exit(get_called_class() . " cannot extend " . __CLASS__ . "\n");

        echo "Success\n";
    }
}

class Foo extends Toto {}
class Bar extends Toto {}

new Toto;
new Foo;
new Bar;

Which returns:

Success
Success
Bar cannot extend Toto

NB: this does not work if the constructor is overwritten.

I dont think this is possible. Each class can be extended by any other class.

If you want to limit the classes that extend your abstract class you can make a final method with a whitelist in it. I think this is a dirty but acceptable solution.

Beware that you're working with people who consider themselves to be professional developers. If they are, they should read documentation. It is impossible to prevent them from making mistakes like this. If they don't read documentation they can just open your abstract class and simply add their class to the whitelist. Conclusion: This is not something you should handle in your code, but in the discipline of your colleagues.

I suppose you can use database to accomplish this.

put class name the list of its extendable class in a row like this

-------------------------------------------------------------------
Class       |       Extendable class
-------------------------------------------------------------------
child 1     |       parent1,parent2,parent3
---------------------------------------------------------------

Then use this data in your code to see if a certain class is extendable

May be a sample will be this

$extendableClass = explode(',',$datarow['extendable class']);
$toextendClass = "parent4";
if(in_array($toextendClass,$extendableClass)) {
    //extend
}
else { 
    //dont extend
}

you can also use plain file or xml to store the class name instead of database or storing them in multidimensional-array might also get this done....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM