[Tutor] Multiple inheritance - Need clarity
Dennis Lee Bieber
wlfraed at ix.netcom.com
Fri Nov 26 22:14:18 EST 2021
On Sat, 27 Nov 2021 07:21:48 +0530, Manprit Singh
<manpritsinghece at gmail.com> declaimed the following:
>Dear sir,
>
>Below given is a toy example , that calculates the surface area of a
>cylinder (area of circles on both sides + area of cylinder wall)
>
>import math
>class Circle:
>
> def __init__(self, radius):
> self.radius = radius
>
> def circle_area(self):
> return math.pi * self.radius**2
>
>class Rectangle:
>
> def __init__(self, s1, s2):
> self.side1 = s1
> self.side2 = s2
>
> def rectangle_area(self):
> return self.side1 * self.side2
>
>class Cylinder(Circle, Rectangle):
>
> def __init__(self, rad, ht):
> Circle.__init__(self, rad)
> Rectangle.__init__(self, 2*math.pi*rad, ht)
>
> def cylinder_surface_area(self):
> return 2 * self.circle_area() + self.rectangle_area()
>
>cyl = Cylinder(3, 10)
>cyl.cylinder_surface_area()
>
>Gives the answer =
>
>245.04422698000386
>
>Just need to know that the way i have called __init__ of circle & rectangle
>inside the init of Cylinder ok or not ? the way i have used circle_area &
>rectangle_area inside cylinder_surface_area is correct or not ?
>
>Kindly guide to do this problem in a better way
And again you are asking for stylistic approval, not if the code is
"correct" or "incorrect".
Personally, I would not use inheritance for this example but
composition.
cyl.cylinder_surface_area() is somewhat redundant. You just want the
surface area of /whatever/ object is of interest. Consider the situation
of...
objs = [ cylinder, cube, dodecahedron ]
for obj in objs:
sa = obj.surface_area()
You would want a common name for surface area of 3D objects -- not a
name specific to each object.
But that also means your 2D components (circle and rectangle) should
similarily have just an
obj.area()
method to be called.
But with your multiple inheritance, you would have to explicitly call
top_bottom_area = 2 * Circle.area()
column_area = Rectangle.area()
as using super... will only call the first item in the MRO.
Using composition it would be something like...
class Cylinder():
def __init__(self, height, radius):
top_bottom = Circle(radius)
column = Rectangle(height, radius)
def area(self):
return self.top_bottom.area() * 2 + self.column.area()
class Sphere():
#I'm not going to derive the area of dodecahedron <G>
def __init__(self, radius):
self.radius = radius
def area(self):
return 4 * math.pi * self.radius ** 2
There is no inheritance, and no overridden methods, in this structure.
There is only the .area() method for all classes which allows a list of all
object types to be processed with the same logic. Obviously, for 2D
Circle() and Rectangle() objects, .area() returns the planar area, while
for 3D Cylinder() and Sphere() it returns surface area.
objs = [ Cylinder(10, 3),
Circle(4),
Rectangle(3, 4),
Sphere(5) ]
for obj in objs:
print( obj.area() )
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/
More information about the Tutor
mailing list