Reputation: 79
In my current project, I have encountered a rather counter-intuitive difference between accessing a field with this
and without this
. Apparently, if I access my field without this
, for some reason, I get a boolean instead of the field I'm trying to access:
//Weapon extends Simple extends Entity extends Matter extends Object
@groovy.transform.TypeChecked
abstract class Action {
Matter tool
boolean setTool(Matter t) {
if (isValidTool(t)) {
tool = t
return true
} else {
return false
}
}
boolean isValidTool(Matter m) {
return true
}
}
@groovy.transform.TypeChecked
class Attack extends Action {
boolean isValidTool(Matter m) {
return (m instanceof Entity)
}
boolean setTool(Matter t) {
if (isValidTool(t)) {
if (t instanceof Weapon) {
tool = t
} else {
tool = new ImprovisedWeapon((Entity)t)
//ImprovisedWeapon extends Weapon
}
return true
} else {
return false
}
}
@Override
Weapon getTool() {
return (Weapon)this.tool
}
void test() {
Weapon a = this.tool //compile-time error
Weapon b = (Weapon)this.tool //works fine
Weapon c = tool //compile-time error
Weapon d = (Weapon)tool //compile-time error
}
}
The errors I get, in order:
[Static type checking] - Cannot assign value of type project.matter.Matter to variable of type project.matter.simple.Weapon
[Static type checking] - Cannot assign value of type boolean to variable of type project.matter.simple.Weapon
[Static type checking] - Inconvertible types: cannot cast boolean to project.matter.simple.Weapon
The first error is explainable, I don't get to use getTool()
after all, and instead effectively use this.@tool
, which obviously returns a Matter. The other two errors, however, are very weird - no local variable tool
is declared, the only tool
around is the one inherited from Action
, which is a Matter
. The locally declared getTool()
would even return a Weapon, and not a boolean. So, my question is, what exactly do I access here when I use tool
, and why is it different from this.tool
?
Upvotes: 1
Views: 102
Reputation: 2017
Note: This might be better as a comment than an answer, but I don't have the reputation to comment.
I'm not sure why, but the error seems to have something to do with the return type of setTool. I think it might be more normal to have setters that don't return anything.
I've given this a try in a groovyConsole (groovy 2.2.1), and with your code (along with dummy classes for the missing ones), I experienced the last two errors that you see (not the first one). Once I set the return type of the setTool methods to void (and removed the return statements), those errors went away, but the first error then appeared for the third line (Weapon c = tool
).
Unfortunately I can't explain why any of this is happening, but I hope it is of some help to you! Maybe someone else can give the reasoning behind the behaviour.
Upvotes: 1