简体   繁体   中英

Create child class object in parent class

is it a good design to create object of child class in parent like the example below, it seems to be working but is it a good design, is there a better way to do that?

class parent(object):
    def __init__(self):
        print('Im running')
    def execute(self):
        x = child()
        x.run()
        x.myfun()
    def myfun(self):
        print('parent function')
    def run(self):
        print('parent running')

class child(parent):
    def __init__(self):
        super().__init__()
        print('Im running too')
    def run(self):
        print('child running')


f = parent()
f.execute()

This is definitely not a good design for your problem, and not a good design generally (bar exceptions which I cannot think of any), and is definitely against OOP design and SOLID principles.

Simply in OOP design, or any other software engineering frame of mind, you want clear relations. This makes the relationship between your parent class and your child class inherently more complex. Not to mention most of the other languages (at least languages which run complied code) would not allow such thing to happen.

If you need to have an instance of one in the other and vice versa, maybe inheritance was the wrong pattern to begin with, since your classes seem to be connected in a two-way manner unlike scenarios in which inheritance is employed.

The fact that execute doesn't use self at all suggests it should be a class method, in which case you can use whichever class is actually provided to instantiate x .

Once you've done this, the definition of Parent no longer relies on any particular subclass; in fact, it doesn't rely on the fact that Parent is subclassed at all ; Parent.execute() will continue to work.

For example,

class Parent:
    def __init__(self):
        print('Im running')

    
    def execute(cls):
        x = ()
        x.run()
        x.myfun()

    def myfun(self):
        print('parent function')

    def run(self):
        print('parent running')


class Child(Parent):
    def __init__(self):
        super().__init__()
        print('Im running too')

    def run(self):
        print('child running')


Child.execute()

This will output

Im running
Im running too
child running
parent function

Since Child.execute isn't defined, it resolves to Parent.execute . But Child is still the first argument passed. As a result, x will be an instance of Child , not Parent . x.run() thus runs Child.run , but x.myfun() runs Parent.myfun .

The fact that Parent.execute , though, still depends on x having an attribute specific to cls suggests that you should defer restrict execute to using only things defined by Parent , and let a child override execute to add any child-specific behavior.

Or, execute should be an instance method, but it should simply call self.fun , putting the burden on the caller to call execute with an appropriate object.

c = Child()
c.execute()

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