Tutorials | (back to the list of tutorials) |
SubclassThe following code is an example of creating a subclass. A keyword to define a subclass is "extends".
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup(){
// ...
}
static class MyRotatedModule extends MyModule{
// instance fields
double rotationAngle;
}
static class MyModule{
// ...
}
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.
Constructor of SubclassAn example of constructors of a subclass is below.
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup(){
size(480, 360, IG.GL);
MyRotatedModule module1 =
new MyRotatedModule(new IVec(0,0,0), 20, Math.PI/4);
MyRotatedModule module2 =
new MyRotatedModule(new IVec(50,0,0), Math.PI/4);
}
static class MyRotatedModule extends MyModule{
// instance fields
double rotationAngle;
// instance methods
MyRotatedModule(IVec pos, double sz, double rotAngle){
super(pos, sz);
rotationAngle = rotAngle;
}
MyRotatedModule(IVec pos, double rotAngle){
super(pos);
rotationAngle = rotAngle;
}
}
static class MyModule{
// static fields
static double defaultSize = 10.0;
// instance fields
IVec position;
double size;
// static methods
static IVec randomXShift(IVec pos, double min, double max){
return pos.dup().add(IRandom.get(min,max),0,0);
}
static IVec randomYShift(IVec pos, double min, double max){
return pos.dup().add(0,IRandom.get(min,max),0);
}
// instance methods
MyModule(IVec pos, double sz){ position = pos; size = sz; }
MyModule(IVec pos){ position = pos; size = defaultSize; }
IBox createModule(){ return new IBox(position, size); }
IBox[] createModuleWithArm(double armSize, double armLen){
IBox[] boxes = new IBox[3];
boxes[0] = new IBox(position, size);
IVec armPos1 = randomXShift(position, -(armLen-size), 0).add(0,0,size);
boxes[1] = new IBox(armPos1, armLen, armSize, armSize);
IVec armPos2 = randomXShift(armPos1, 0, armLen-size);
armPos2 = randomYShift(armPos2, -(armLen-size), 0).add(0,0,armSize);
boxes[2] = new IBox(armPos2, armSize, armLen, armSize);
return boxes;
}
}
Overriding MethodsActually 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.
![]()
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup(){
size(480, 360, IG.GL);
MyRotatedModule module1 = new MyRotatedModule(new IVec(0,0,0), 20, PI/3);
IBox box = module1.createModule();
box.clr(1.0,0,0);
MyRotatedModule module2 = new MyRotatedModule(new IVec(50,0,0), PI/4);
IBox[] boxes = module2.createModuleWithArm(5, 40);
for(IBox bx : boxes){ bx.clr(0,0,1.0); }
}
static class MyRotatedModule extends MyModule{
// static fields
static IVec rotationAxis = new IVec(0,0,1);
// instance fields
double rotationAngle;
// instance methods
MyRotatedModule(IVec pos, double sz, double rotAngle){
super(pos, sz);
rotationAngle = rotAngle;
}
MyRotatedModule(IVec pos, double rotAngle){
super(pos);
rotationAngle = rotAngle;
}
IBox createModule(){
IBox box = super.createModule();
box.rot(position, rotationAxis, rotationAngle);
return box;
}
IBox[] createModuleWithArm(double armSize, double armLen){
IBox[] boxes=super.createModuleWithArm(armSize, armLen);
for(IBox box : boxes){
box.rot(position, rotationAxis, rotationAngle);
}
return boxes;
}
}
static class MyModule{
// static fields
static double defaultSize = 10.0;
// instance fields
IVec position;
double size;
// static methods
static IVec randomXShift(IVec pos, double min, double max){
return pos.dup().add(IRandom.get(min,max),0,0);
}
static IVec randomYShift(IVec pos, double min, double max){
return pos.dup().add(0,IRandom.get(min,max),0);
}
// instance methods
MyModule(IVec pos, double sz){ position = pos; size = sz; }
MyModule(IVec pos){ position = pos; size = defaultSize; }
IBox createModule(){ return new IBox(position, size); }
IBox[] createModuleWithArm(double armSize, double armLen){
IBox[] boxes = new IBox[3];
boxes[0] = new IBox(position, size);
IVec armPos1 = randomXShift(position, -(armLen-size), 0).add(0,0,size);
boxes[1] = new IBox(armPos1, armLen, armSize, armSize);
IVec armPos2 = randomXShift(armPos1, 0, armLen-size);
armPos2 = randomYShift(armPos2, -(armLen-size), 0).add(0,0,armSize);
boxes[2] = new IBox(armPos2, armSize, armLen, armSize);
return boxes;
}
}
Use of Subclasssurface12.3dm is the input file used in the code.
![]()
![]()
![]()
![]()
import processing.opengl.*;
import igeo.*;
void setup(){
size(480, 360, IG.GL);
IG.open("surface12.3dm");
ISurface[] surfaces = IG.surfaces();
int unum=40, vnum=40;
double uinc=1.0/unum, vinc=1.0/vnum;
for(ISurface surf : surfaces){
for(int i=0; i < unum; i++){
for(int j=0; j < vnum; j++){
IVec pt = surf.pt(i*uinc, j*vinc);
MyModule module =
new MyRotatedModule(pt, 1.5, i*uinc*PI);
if(IRandom.percent(50)){
IBox box = module.createModule();
box.clr(0.7,0,0);
}
else{
double armLength = IRandom.get(2,10);
IBox[] boxes = module.createModuleWithArm(0.5,armLength);
for(IBox bx:boxes){ bx.clr(IRandom.gray()); }
}
}
}
surf.del();
}
}
static class MyRotatedModule extends MyModule{
// static fields
static IVec rotationAxis = new IVec(0,0,1);
// instance fields
double rotationAngle;
// instance methods
MyRotatedModule(IVec pos, double sz, double rotAngle){
super(pos, sz);
rotationAngle = rotAngle;
}
MyRotatedModule(IVec pos, double rotAngle){
super(pos);
rotationAngle = rotAngle;
}
IBox createModule(){
IBox box = super.createModule();
box.rot(position, rotationAxis, rotationAngle);
return box;
}
IBox[] createModuleWithArm(double armSize, double armLen){
IBox[] boxes=super.createModuleWithArm(armSize, armLen);
for(IBox box : boxes){
box.rot(position, rotationAxis, rotationAngle);
}
return boxes;
}
}
static class MyModule{
// static fields
static double defaultSize = 10.0;
// instance fields
IVec position;
double size;
// static methods
static IVec randomXShift(IVec pos, double min, double max){
IVec shifted = pos.dup();
shifted.add(IRandom.get(min,max),0,0);
return shifted;
}
static IVec randomYShift(IVec pos, double min, double max){
IVec shifted = pos.dup();
shifted.add(0,IRandom.get(min,max),0);
return shifted;
}
// instance methods
MyModule(IVec pos, double sz){ position = pos; size = sz; }
MyModule(IVec pos){ position = pos; size = defaultSize; }
IBox createModule(){ return new IBox(position, size); }
IBox[] createModuleWithArm(double armSize, double armLen){
IBox[] boxes = new IBox[3];
boxes[0] = new IBox(position, size);
IVec armPos1 = randomXShift(position, -(armLen-size), 0);
armPos1.add(0,0,size);
boxes[1] = new IBox(armPos1, armLen, armSize, armSize);
IVec armPos2 = randomXShift(armPos1, 0, armLen-size);
armPos2 = randomYShift(armPos2, -(armLen-size), 0);
armPos2.add(0,0,armSize);
boxes[2] = new IBox(armPos2, armSize, armLen, armSize);
return boxes;
}
}
For more description about class inheritance, please see Java's tutorial page on inheritance.
HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java /
Python)
GALLERY
SOURCE CODE(GitHub)
PRIVACY POLICY
ABOUT/CONTACT