Please check the Java code below:
public class Test
{
public static void main(String arg[]) throws Throwable
{
Test t = new Test();
System.out.println(t.meth().s); //OP: Old value
System.out.println(t.meth().getVal()); //OP: String Implementation
}
private TestInter meth()
{
return new TestInter()
{
public String s = "String Implementation";
public String getVal()
{
return this.s;
}
};
}
}
interface TestInter
{
String s = "Old value";
String getVal();
}
As you see I have created an interface anonymously. When I access the interface variable directly, it will show "Old value".
t.meth().s => "Old value"
Accessing it through the getVal() method returns proper values,
t.meth().getVal() => "String Implementation"
I don't understand how this code works, can somebody explain it to me?
Yes, Interfaces CAN contain member variables. But these variables have to be implicitly (without any keyword definition) final, public and static. This means that within interfaces, one can only declare constants. You cannot declare instance variables using interfaces.
A normal class can implement any number of interfaces but the anonymous inner class can implement only one interface at a time. A regular class can extend a class and implement any number of interfaces simultaneously. But anonymous Inner class can extend a class or can implement an interface but not both at a time.
Protected members of an interface In general, the protected members can be accessed in the same class or, the class inheriting it. But, we do not inherit an interface we will implement it. Therefore, the members of an interface cannot be protected.
Because the EventHandler<ActionEvent> interface contains only one method, you can use a lambda expression instead of an anonymous class expression. See the section Lambda Expressions for more information. Anonymous classes are ideal for implementing an interface that contains two or more methods.
The s
variable declared in the interface is entirely separate from the s
variable you've declared in your anonymous inner class.
Interface variables are really just designed to be constants - they aren't part of the API each implementation needs to provide. In particular, they're implicitly static and final.
From the JLS section 9.3:
Every field declaration in the body of an interface is implicitly public, static, and final. It is permitted to redundantly specify any or all of these modifiers for such fields.
The fact that you've accessed the field via an implementation instance is irrelevant - this code:
System.out.println(t.meth().s);
is effectively:
t.meth();
System.out.println(TestInter.s);
I would strongly encourage you to avoid using variables in interfaces except for genuine constants... and even then, only where it really makes sense. It's not clear what you're trying to achieve, but declaring a field in an interface isn't a good way forward IMO.
There is nothing like variable-overriding
like method overriding
in java. Name a new type for subclass
, then you will get the "String Implementation"
, when you access through the subclass reference type.
Access privilege protected
only means we can access the variable in a subclass but not that it can be override.
Even if you are using normal class
instead of interface
this won't work. When you refer using super
class type, you only get the instance
variables from super
type and so on....
This example illustrates the first case:
Example:
public class Tester
{
public static void main(String arg[]) throws Throwable
{
Tester t = new Tester();
System.out.println(t.meth().s); // it prints "Old value" because your type is TestInter
}
private TestInter meth()
{
return new TestInter()
{
protected String s = "String Implementation";
};
}
}
class TestInter
{
protected String s = "Old value";
}
This example illustrates the second case:
It prints "String Implementation"
public class Tester
{
public static void main(String arg[]) throws Throwable
{
Tester t = new Tester();
System.out.println(t.meth().s);
}
private SubTestInter meth()
{
return new SubTestInter();
}
}
class SubTestInter extends TestInter{
protected String s = "String Implementation";
}
class TestInter
{
protected String s = "Old value";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With