Calling a parents function in a child object

Hi there,

I’ve been working on a bigger project but ran into a bit of a problem when trying to organize my functions in the correct objects. The problem is that I cannot seem to call a function that is defined in a parent object. Here’s an example where it says ‘The function “objectFunction()” does not exist’:
Main.pde

Object object = new Object();

void mainFunction() {
  println("I called the MAIN function");
}

Object.pde

class Object {

  SubObject subObject = new SubObject();

  Object() {
    println("setup object");
    subObject.callFunctions();
  }

  void objectFunction() {
    println("I called the OBJECT function");
  }
}

SubObject.pde

class SubObject {
  
  SubObject() {
    println("setup subobject");
  }
  
  void callFunctions() {
    mainFunction();
    objectFunction();
  }
  
}

What is even weirder is that it can call the mainFunction() just fine, maybe because it is the ‘head’ file. My expected output would be it printing all the println() functions, but instead get an error as stated above. Could I maybe make the Object class ‘extra public’? So I can call it wherever I want.

1 Like

check the class Extends documentation to see how child functions work, also check out inheritance.

https://processing.org/reference/extends.html

https://processing.org/examples/inheritance.html

DrawDot dd1 = new DrawDot(50, 80);

void setup() { 
  size(200, 200);
} 
 
void draw() {
  dd1.display();
} 
 
class Dot { 
  int xpos, ypos;
} 

class DrawDot extends Dot {
  DrawDot(int x, int y) {
    xpos = x;
    ypos = y;
  }
  void display() {
    ellipse(xpos, ypos, 200, 200);
  }
}
4 Likes

To create a SubObject you can’t just add Sub to the word :sweat_smile: you have to tell the class that it is extended from another object as @paulgoux said.

As for why the mainFunction still worked, that is because you can call the main functions from anywhere, be it within a class or another main function. The reason for that is the hierarchy within a Sketch. Main>Classes(Parent)>ExtendedClasses(Children)

Bottom can call top, but top can‘t call bottom, so Children can call anything in their parent class (though not unrelated classes, like Apple (estenda Food) can call methods from class Food, but not from class Vehicle for example) and in main, while parents can‘t call methods in their children, but still can in main.

Main can‘t call anything that is not a main method (unless you use a reference, like object.callObjFunction()).

I think that should explain it, but might be missing something :sweat_smile:

2 Likes

I just tried it in my code, but it said something about constructors, so I completely removed the constructor functions. Now I don’t get any red lines, but when I try to run it it says StackOverflowError: This sketch is attempting too much recursion. I don’t think the sketch is but it has shomething to do with the extends function. Here’s my even simpler code:

Main.pde

Object object = new Object();

void setup() {
  size(40, 40);
  object.subObject.callFunctions();
}

Object.pde

class Object {

  SubObject subObject = new SubObject();

  void objectFunction() {
    println("I called the OBJECT function");
  }
}

SubObject.pde

class SubObject extends Object {
  
  void callFunctions() {
    objectFunction();
  }
  
}

Did I implement the extends function wrong? How can I get this code to run?

You created an infinite loop of creating subobjects… and that is why you generally want to avoid defining fields in classes when they are of the same (or extended) classes…

The subObject class has the same fields as the Object class, so you‘re basically doing :

createObject > createSubObject > createSubObject > createSubObject > and so on for eternity…

You can avoid that by declaring and not defining the field.

Declaring : SubObject sub;
Defining : SubObject sub = new SubObject();

3 Likes
//Main.pde
SubObject asubobject = new SubObject();

void setup() {
  size(40, 40);
  println("I called the subcallFunction of class SubObject");
  asubobject.subcallFunction();
}

//Object.pde

class MyObject {

  void myobjectFunction() {
    println("I called the myobjectFunction of class MyObject");
  }
}

//SubObject.pde

class SubObject extends MyObject {

  void subcallFunction() {
    myobjectFunction();
  }
}

prints

I called the subcallFunction of class SubObject
I called the myobjectFunction of class MyObject

works, possibly not what you wanted, please check

3 Likes

Thanks for the help! I still don’t fully understand why it didn’t work, but at least now I know how to make it work :smiley:

class Object {
   SubObject subobject = new SubObject(); 
//this line declares a field of the class Object
//every instance of class Object AND it‘s Child-classes (SubObject) will have this field!

}

//therefore by doing 
class SubObject extends Object{

}

//you‘re Basically doing this
class SubObject {
   SubObject subobject = new SubObject(); 
//this will create a new SubObject, which in turn also has this field
// that creates a new SubObject and so on and so forth

//without the = new SubObject(); you‘re Not creating a new SubObject and thus wouldn‘t have this problem. 
}

Thanks for all the replies, I can call functions fine now. But I am having a slightly different problem with using parents variables. Here’s my code:

Main.pde:

int mainVar = 10;

void setup() {
  Object obj = new Object();
  mainVar = 20;
  obj.setupObject();
}

Object.pde:

class Object {

  int objectVar = 10;

  void setupObject() {
    SubObject sub = new SubObject();
    objectVar = 20;
    sub.readVars();
  }
}

SubObject.pde:

class SubObject extends Object {
  
  void readVars() {
    // 10 is defined, 20 is updated
    println("mainVar: " + mainVar);
    println("objectVar: " + objectVar);
  }
}

I am running into a weird issue that I can access the variables from the SubObject, but only the defined value. When I update the value and try to read it, it just reads the defined value. Again, this does work in the Main.pde. I want to read the updated values so I can use them in the SubObject.

Output:

mainVar: 20
objectVar: 10

Expected output:

mainVar: 20
objectVar: 20

EDIT: I think I now understand why it doesn’t work, but I still don’t get how to make it work.

1 Like

Again, this is completely correct.

What you are printing out is not the objectvar that you set.

You set the objectVar of the object. Then you told the subobject (that you created beforehand) to print out IT‘s objectvar (again, child classes also have their parents fields, in this case subobject has it‘s own objectvar field), which you never set to anything, other than during the declaration, defining it as 10.

1 Like

Here, take a look at this :

class Food {
   String name = "Unspecified";
   int quality;
   boolean poisonous;

   Food (int q) {
      quality = q;

      printFields();
      //Prints „Unspecified 5 false“ lets just assume quality is 5
   }

   void printFields() {
      println(name, quality, poisonous);
   }
}

class Apple extends Food {

   float age;//this is a new field only available in Apple, not in Food!

   Apple (float a, int q) {
      age = a; // sets age to a

      quality = q; //the field from Food is still here, since the class is extended (that‘s what extending is there for)

      name = "Apple"; //again, name is still here

      poisonous = false; //booleans are false by default, so this is meaningless, but just to show it again

      printFields(); 
      //this method is still here from class Food (that‘s what extension does)
      // Prints „Apple 5 false“

      printAppleFields();
      // Prints „Apple 5 false 10days“
   }

   //This is not available in Food class!
   void printAppleFields() {
      println(name, quality, poisonous, age);
   }

}
2 Likes