Python Tutorials | (back to the list of tutorials) |
The following code is an example of creating a subclass. A keyword to define a subclass is "extends".
add_library('igeo') def setup() : # ... class MyRotatedModule(MyModule) : # instance methods def method2(self): # ... class MyModule : # ... def method1(self): # ...
This code above defines a subclass named "MyRotatedModule", inheriting the superclass "MyModule". (This code skips the "setup()" method). The inheritance relationship is defined at the line of the class definition of the subclass, by adding "extends MyModule" after the class name of "MyRotatedModule". This subclass only adds one instance field of "double rotationAngle". This subclass doesn't have constructors yet. Constructors of subclass are described in the next section.
An example of constructors of a subclass is below.
add_library('igeo') def setup() : size(480, 360, IG.GL) module1 = MyRotatedModule(IVec(0,0,0), 20, PI/4) module2 = MyRotatedModule(IVec(50,0,0), PI/4) class MyModule : # static fields defaultSize = 10.0 # static methods @staticmethod def randomXShift(pos, min, max) : return pos.dup().add(IRand.get(min,max),0,0) @staticmethod def randomYShift(pos, min, max) : return pos.dup().add(0,IRand.get(min,max),0) # instance methods def __init__(self, pos, sz = defaultSize) : self.position = pos self.size = sz def createModule(self) : return IBox(self.position, self.size) def createModuleWithArm(self, armSize, armLen) : boxes = [] boxes.append(IBox(self.position, self.size)) armPos1 = MyModule.randomXShift(self.position, -(armLen-self.size), 0).add(0,0,self.size) boxes.append(IBox(armPos1, armLen, armSize, armSize)) armPos2 = MyModule.randomXShift(armPos1, 0, armLen-self.size) armPos2 = MyModule.randomYShift(armPos2, -(armLen-self.size), 0).add(0,0,armSize) boxes.append(IBox(armPos2, armSize, armLen, armSize)) return boxes class MyRotatedModule(MyModule) : # instance methods def __init__(self,pos, rotAngle, sz=MyModule.defaultSize) : MyModule.__init__(self, pos, sz) self.rotationAngle = rotAngle
Actually it's natural to override a method by calling the same method in superclass and adding more codes to expand the behavior of the method because subclassing is conceptually expanding functionality. By overriding methods, behaviors of a class with same names of methods can be varied among classes having inheritance relationship. This feature of object-oriented programming is called "polymorphism".
The code below shows an example of overriding methods of the superclass.
add_library('igeo') def setup() : size(480, 360, IG.GL) module1 = MyRotatedModule(IVec(0,0,0), PI/3, 20) box = module1.createModule() box.clr(1.0,0,0) module2 = MyRotatedModule(IVec(50,0,0), PI/4) boxes = module2.createModuleWithArm(5, 40) for bx in boxes : bx.clr(0,0,1.0) class MyModule : # static fields defaultSize = 10.0 # static methods @staticmethod def randomXShift(pos, min, max) : return pos.dup().add(IRand.get(min,max),0,0) @staticmethod def randomYShift(pos, min, max) : return pos.dup().add(0,IRand.get(min,max),0) # instance methods def __init__(self, pos, sz = defaultSize) : self.position = pos self.size = sz def createModule(self) : return IBox(self.position, self.size) def createModuleWithArm(self, armSize, armLen) : boxes = [] boxes.append(IBox(self.position, self.size)) armPos1 = MyModule.randomXShift(self.position, -(armLen-self.size), 0).add(0,0,self.size) boxes.append(IBox(armPos1, armLen, armSize, armSize)) armPos2 = MyModule.randomXShift(armPos1, 0, armLen-self.size) armPos2 = MyModule.randomYShift(armPos2, -(armLen-self.size), 0).add(0,0,armSize) boxes.append(IBox(armPos2, armSize, armLen, armSize)) return boxes class MyRotatedModule(MyModule) : # static fields rotationAxis = IVec(0,0,1) # instance methods def __init__(self, pos, rotAngle, sz=MyModule.defaultSize) : MyModule.__init__(self, pos, sz) self.rotationAngle = rotAngle def createModule(self) : box = MyModule.createModule(self) box.rot(self.position,self.rotationAxis,self.rotationAngle) return box def createModuleWithArm(self, armSize, armLen) : boxes = MyModule.createModuleWithArm(self, armSize, armLen) for box in boxes : box.rot(self.position, self.rotationAxis, self.rotationAngle) return boxes
surface12.3dm is the input file used in the code.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.open("surface12.3dm") surfaces = IG.surfaces() unum=40 vnum=40 uinc=1.0/unum vinc=1.0/vnum for surf in surfaces : for i in range(unum) : for j in range(vnum) : pt = surf.pt(i*uinc, j*vinc) module = MyRotatedModule(pt, i*uinc*PI, 1.5) if IRand.pct(50) : box = module.createModule() box.clr(0.7,0,0) else : armLength = IRand.get(2,10) boxes = module.createModuleWithArm(0.5,armLength) for bx in boxes : bx.clr(IRand.gray()) surf.del() class MyModule : # static fields defaultSize = 10.0 # static methods @staticmethod def randomXShift(pos, min, max) : return pos.dup().add(IRand.get(min,max),0,0) @staticmethod def randomYShift(pos, min, max) : return pos.dup().add(0,IRand.get(min,max),0) # instance methods def __init__(self, pos, sz = defaultSize) : self.position = pos self.size = sz def createModule(self) : return IBox(self.position, self.size) def createModuleWithArm(self, armSize, armLen) : boxes = [] boxes.append(IBox(self.position, self.size)) armPos1 = MyModule.randomXShift(self.position, -(armLen-self.size), 0).add(0,0,self.size) boxes.append(IBox(armPos1, armLen, armSize, armSize)) armPos2 = MyModule.randomXShift(armPos1, 0, armLen-self.size) armPos2 = MyModule.randomYShift(armPos2, -(armLen-self.size), 0).add(0,0,armSize) boxes.append(IBox(armPos2, armSize, armLen, armSize)) return boxes class MyRotatedModule(MyModule) : # static fields rotationAxis = IVec(0,0,1) # instance methods def __init__(self, pos, rotAngle, sz=MyModule.defaultSize) : MyModule.__init__(self, pos, sz) self.rotationAngle = rotAngle def createModule(self) : box = MyModule.createModule(self) box.rot(self.position,self.rotationAxis,self.rotationAngle) return box def createModuleWithArm(self, armSize, armLen) : boxes = MyModule.createModuleWithArm(self, armSize, armLen) for box in boxes : box.rot(self.position, self.rotationAxis, self.rotationAngle) return boxes
For more description about class inheritance, please see Java's tutorial page on inheritance.