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.