This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Hi Cameron, In your book you have said interface cannot have instance variables, can you please tell what you mean by that, as variables can be declared in interfaces, so what is it we cannot declare. Please explain.
When used effectively, interfaces become extremely powerful plugin points that make your design incredibly flexible. Applied effectively, they can become one of the most important parts of an application design.
Interfaces express a common behavior, and in Java, behavior translates into methods. So, in Java interfaces, we simply declare methods for which implementing classes will provide an implementation. In fact, the methods we declare in an interface are said to be implicitly abstract, although they don't necessarily need to have the abstract keyword - doesn't hurt to put it in though.
But interfaces are flexible because they allow the implementing classes to deliver a code body in any way that makes sense. If a concrete implementing class needs ten instance variables to implement an interface method, it can declare ten instance variables. If a concrete implementing class doesn't need any instance variables to provide a concrete implementation, then it doesn't need to declare any instance variables. In a world where every programmer has their own idea of the best way to implement something, Java interfaces provide implementation flexibility, appealing to the ego of all of those narcissistic programmers out there.
But an interface indeed does not allow you to declare any instance variables. Using a variable declared in an interface as an instance variable will trigger a compile time error. It simply can't be done.
What you CAN do in an interface is declare a constant, or in Java-speak, you can declare a static final variable. But this is different from an instance variable. A static final variable is really just associated once with the JVM that is running, and it is not tied to any particular instance. I do like declaring constants in an interface, but even then, there is something known as the "constants interface ANTI-pattern' which new developers can fall into if they take the practice too far.
If you do wish to declare instance variables in a component that also declares abstract classes, you can declare an abstract class. An abstract class is that bridge between a highly abstract interface, and a concrete class that provides a full implementation.
Of course, I can spout off all day about Java, and Interfaces, and Abstract classes. The final word always comes down to the compiler. I can have all the opinions in the world, but at the end of the day, they must all be in line with what the compiler spits out.
Take a look at the following code. It might just tackle the source of your confusion with regards to Java interfaces and instance variables.
Curiously, the following code will compile :
Looks like an instance variable, doesn't it?
Here's how you'd use it in code:
This will actually run, and print out 10. But notice, the variable is being referenced as though it were a static variable, not an instance variable.
Now look what happens when you try to change the value of i:
Now, the bolded line that tries to change the value of i generates a compile error, saying:
The final field Instanceable.i cannot be assignedInstanceableRunner.javaline 7
So, as you can see, the instance variable is declared using a syntax that makes it look like it is an instance variable, but when you try to reference or change the value, you see that it is in fact a constant, or static final variable. So, just as any method declared in an interface is implicitly abstract, any variable declared in an interface is implicitly a static final variable. The code really should have been written like this:
Looks like I just wrote a few extra pages for the next printing of my SCJA Study Guide.
Thanks for the question, and if there's anything that's not clear, just post. Create a new thread for new topics, but if it applies to this topic, continue the thead.
Superb explanation makes it simpler to remember that instance variables cannot be used in Interface - full stop. If we need we can use Instance Variables in Abstract class and which can inherited by it's subclasses but not in Interface (which is a highly abstract class). Superb explanation Cameron - thanks.
Need your help in explaining one more thing. While running the program in 'main' class, the compiler asks for necessarily declaring the variable in 'abstract parent class' or 'interface' even when the same is declared in corresponding extending or implementing classes. Further, it takes the value of the variable initialized in abstract class/interface. If you could please help me resolve the problem. I hope I am not doing something wrong. Many thanks.
Cameron Wallace McKenzie wrote:I'm not sure what you're talking about? That is clearly what my post indicates!
Thank goodness for the edit button. See what happens when you write code without a compiler?
I've always said, it's more important to know what I mean, as opposed to what I say. If people just knew what I meant without me having to say anything, the world would be a much better place.