Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Inheritance problem
#1
I have 2 classes sphereclass.py and cubeclass.py , containing respective methods for calculating volume,etc...
Then i make a third class "geometryclass.py" that inherits from both,
geometryclass.py:
from sphereclass import sphere
from cubeclass import cube

class geometry(sphere,cube):
    def __init__(self):   
        # Calling 2 constructors  
        sphere.__init__(self) 
        cube.__init__(self)
Then i write a program that is going to use some methods, like so:
myProgram:
from geometryclass import *

mySpere = sphere(10)
print(mySphere.surface())
myCube = cube(10)
print(myCube.surface())
This works great, but...i cannot instantiate the geometryclass itself in my program.
like:
myGeometry = geometry()
myGeometry.anymethod()
How can i call methods proper to the inheriting class itself and execute them?
Or maybe it is impossible.
Thanks
Paul


i
Reply
#2
Show all your code. If you get any traceback - post it verbatim, in error tags.

All that said - you get the thinks the other way around. You should inherit from general class. i.e. you crate a general base class with common methods, then more specific child class(es) will inherit from it, using common methods or overloading some of them. At the moment sphere.surface will overwrite cube.surface

Here is an example, the way you do it:
from math import pi
class Cube:
    def __init__(self, side):
        self.side = side
    
    @property
    def surface(self):
        print('Cube surface method')
        return 6 * self.side * self.side


class Sphere:
    def __init__(self, radius):
        self.radius = radius
    
    @property
    def surface(self):
        print('Sphere surface method')
        return 4 * pi * self.radius * self.radius


class Geometry(Sphere, Cube):
    def __init__(self, x):
        # you should use super() to initialize the parent classes
        Cube.__init__(self, x)
        Sphere.__init__(self, x)

    
geo = Geometry(5)
print(geo.surface)
print(Geometry.mro())
Sphere surface method
314.1592653589793
[<class '__main__.Geometry'>, <class '__main__.Sphere'>, <class '__main__.Cube'>, <class 'object'>]
as you can see in the Method resolution order Sphere is before Cube
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
OK Buran, thanks, I will adhere to the "state of the art" way of doing things.
(Although i see no overwriting, results come out OK, otherwise i would have spotted it)

Paul
Reply
#4
(May-05-2020, 03:01 PM)DPaul Wrote: OK Buran, thanks, I will adhere to the "state of the art" way of doing things.
(Although i see no overwriting, results come out OK, otherwise i would have spotted it)

Paul
Not sure how to understand that. You said you cannot instantiate class geometry.
My example code is NOT "state of the art" - it was meant to demonstrate the problem with your approach (i.e. what you describe, but that is not running).
can you demonstrate how you would call surface method of a Cube from geometry class? Or how you plan to use geometry class
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
Overwriting is not the right term in this case. Your geometry class inherits from two classes that both have a "surface" method. When calling geometry.surface() which method is used? In your case it uses sphere.surface() because Sphere appears first in
class geometry(sphere,cube):. The geometry.mro() would show the order.

I don't think you want geometry to be a subclass of sphere and cube. Instead I think you want it to be their superclass. Inheritence should be from the generic to the specific. The superclass of sphere should be more generic than a sphere.
import math

class geometry:
    """base class for geometetric shapes"""
    def surface(self):
        """Return surface area"""
        raise NotImplementedError('Subclass responsibility')

class sphere(geometry):
    def __init__(self, radius):
        self.radius = radius

    def surface(self):
        return 4 * math.pi * self.radius * self.radius

class cube(geometry):
    def __init__(self, edge):
        self.edge = edge

    def surface(self):
        return 6 * self.edge * self.edge

shapes = [sphere(3), cube(3), cube(5), sphere(6)]

for shape in shapes:
    print(shape.surface())
Reply
#6
(May-05-2020, 04:01 PM)deanhystad Wrote: Overwriting is not the right term in this case.
yes, you are right. I also demonstrated what method resolution order is, but it looks like DPaul is confused
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#7
OK, I understand, I had hoped to be able to make a class from "loose ends"
that have been created over time.
This is how i get the right results:
from geometryclass import *
 
mySpere = sphere(10)
print(mySphere.surface())
myCube = cube(10)
print(myCube.surface())
I think geometry needs to be a superclass, whatever that is.
I'll investigate :-)
Paul
Reply
#8
that will give correct result, because you are instantiating cube and sphere, not geometry.
Maybe the correct question is - why do you want to create geometry?
(May-05-2020, 04:14 PM)DPaul Wrote: I had hoped to be able to make a class from "loose ends"
is not very clear.
You may want to refactor your code the other way around
create new class with possible "common" methods in the existing classes. Then make your existing classes to inherit from this parent class and remove the common methods from each child class.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#9
Superclass just means "the class I inherit from". Unless specified, the superclass for your class is "object". You may not have known it, but your sphere and cube classes inherited from object. Class "object" is the superclass of class "sphere".

Subclass is the other way around. In my example sphere inherits from geometry. This makes geometry a superclass of sphere. It also makes sphere a subclass of geometry. You will see these terms mentioned fairly often in discussions about object oriented programming.

Unfortunately it is not simple to toss things together and get a logical set of classes. OOP requires some planning or you end up with a mess. Sometimes an inheritance tree can grow organically. You write a bunch of classes and see that they share a lot of common features that they can all inherit from a superclass. But that usually only happens in simple cases. Unless you were thinking about making your classes similar (planning for inheritance, even unconsciously), things tend to get implemented in specific instead of generic ways. Mining the generic-ness out of a collection of classes often requires a lot of refactoring.
Reply
#10
Imagine i have 10 students, and they all receive a different geometric object to study.
They all e.g. come up with the properties "surface" or "volume", and some specific ones for the object.
None are calculated the same.
Different method, different number of arguments.
The # of arguments could be dealt with through *args, I imagine,
but i don't see a "generic" superclass here with the different formula's for volume etc., unless:
i make defs like "cubevolume: " and "spherevolume"... in the generic class

I'm looking for an efficiency gain, otherwise i can leave my sphere class, cube class, circle class, square class etc.. as they are.

(I like your intentions to help, but don't do the progamming for me I lke a challenge :-)

thx,
Paul
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Inheritance problem Maryan 0 1,276 Oct-25-2020, 02:39 PM
Last Post: Maryan

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020