We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, I wrote a class named Real that represent a real number with an arbitrary precision. My final purpose is to use this class in other classes and to use the operations like add(x, y), sub(x, y), ... without having to call them by Real.add(x, y). So I moved the add(x, y) function outside my class.
Here is some made up code to help understand what I'm doing :
class Real
{
// ... code
void add(Real R)
{
this = add(this, R);
}
}
// sketch level
Real add(Real S, Real T){/*code*/}
Now I'm happy I can add two Real anywhere in my sketch.
But :
The add(Real R) inside the class doesn't work anymore. The compiler thinks it's recursion (add not applicable for two arguments). Is there a way to access the add function that is outside the class from inside the class ?
Or is there a nicer way to do this, keeping all the code in classes ?
Thanks in advance !
Answers
You should really just call the functions by two different names.
But if you want to access the sketch-level
add()
function from inside theReal
class, you'd want to do this:Here's a small example:
But like I said, this is probably a bad idea. Just rename the functions so it's not confusing.
Say I'm stubborn and I don't want to change the names of the functions, how could I improve your code so I don't have to update the sketch's name in each sketch I use my class ?
Here is a start, but the commented line throws a NoSuchMethodException, and I can't figure out why.
getMethod() documentation
invoke() documentation
And your code does what I want, however I don't understand why
MySketch.this.test()
refers to the sketch-leveltest()
function. I understand that here,this
refers to theTest
class so thetest()
called is the one in theTest
class.Can you clarify this ?
When you're in the
Test
class and call a function, it first looks in theTest
class for a function with that name. If it can't find one, then it looks at the sketch-level functions. UsingSketchName.this.test()
tells it to skip over the class-level and just call the sketch-level function directly.Another approach would be to get a reference to the sketch, something like this:
But honestly, this is pretty hacky. Don't do this. Just rename the method.
Thanks for your help ! I'll follow your advice and just rename the method.
It's also worth noting that this is not method overloading. Method overloading happens when you have two versions of the same function in the same scope that take different parameters:
Method overriding is when you have a subclass that contains a function with the same name:
What you're doing is called method shadowing and as you've seen, it means that methods in the inner class scope are called instead of methods in the outer scope. More info here: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
If you wish your inner class to automatically find out its enclosing PApplet class' reference, try this code out: :ar!
That's even hackier than just doing
MySketch sketch = this;
. None of this should actually be used.How do I trigger a sketch-level method from
getEnclosingPApplet()
then ?You would have to cast it to
MySketch
or whatever. This isn't an improvement.Well, that's wrong in the first place.
You want
x.add(y);
- much shorter.I wouldn't recommend to move
add()
out of the class at all. Just stick to the class and put as much as you can inside the class.https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html
Dunno what you mean by "trigger". But if you've simply meant for an inner class to access members of our sketch via "this$0", we can't by regular means. [-X
Only by some hackish workarounds like 100% reflection or Java's bundled JS Nashorn. :ar!
The reason why we can't is b/c we dunno the name of the enclosing top-class under Processing's IDE (PDE); which is the name of our sketch's folder btW. @-)
Therefore, whatever name is chosen when we save our sketch becomes the datatype of the enclosing PApplet top-subclass. :-B
Regardless, an inner class already has full access to its enclosing class members and vice-versa; as long as the inner class doesn't overshadow an enclosing member's name. :-\"
What I don't understand is why are you attempting to create a library using an inner class! :-/
You should at least create a ".java" tab and put your library class there! *-:)
Pay attention to what koogs just posted. I meant to post that in my original answer.
Basically, what you're trying to come up with has already been developed. Just use the existing
BigDecimal
class.