Using Interface Variables

Why are interface variables static and final by default?

From the Java interface design FAQ by Philip Shaw:

Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.

source

Using Interface variables

You are not creating an instance of the interface - you are creating an instance of something that implements the interface.

The point of the interface is that it guarantees that what ever implements it will provide the methods declared within it.

So now, using your example, you could have:

MyNiftyClass : IMyInterface
{
public void CallSomeMethod()
{
//Do something nifty
}
}

MyOddClass : IMyInterface
{
public void CallSomeMethod()
{
//Do something odd
}
}

And now you have:

IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()

Calling the CallSomeMethod method will now do either something nifty or something odd, and this becomes particulary useful when you are passing in using IMyInterface as the type.

public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
someObject.CallSomeMethod();
}

Now, depending on whether you call the above method with a nifty or an odd class, you get different behaviour.

public void AnotherClass()
{
IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()

// Pass in the nifty class to do something nifty
this.ThisMethodShowsHowItWorks(nifty);

// Pass in the odd class to do something odd
this.ThisMethodShowsHowItWorks(odd);

}

EDIT

This addresses what I think your intended question is - Why would you declare a variable to be of an interface type?

That is, why use:

IMyInterface foo = new MyConcreteClass();

in preference to:

MyConcreteClass foo = new MyConcreteClass();

Hopefully it is clear why you would use the interface when declaring a method signature, but that leaves the question about locally scoped variables:

public void AMethod()
{
// Why use this?
IMyInterface foo = new MyConcreteClass();

// Why not use this?
MyConcreteClass bar = new MyConcreteClass();
}

Usually there is no technical reason why the interface is preferred. I usually use the interface because:

  • I typically inject dependencies so the polymorphism is needed
  • Using the interface clearly states my intent to only use members of the interface

The one place where you would technically need the interface is where you are utilising the polymorphism, such as creating your variable using a factory or (as I say above) using dependency injection.

Borrowing an example from itowlson, using concrete declaration you could not do this:

public void AMethod(string input)
{
IMyInterface foo;

if (input == "nifty")
{
foo = new MyNiftyClass();
}
else
{
foo = new MyOddClass();
}
foo.CallSomeMethod();
}

Can an interface hold any instance variables?

variables declared in interface are by default public, static and final. Since it is static you cannot call it instance variable.

Variables in java interfaces

A common practice in this case is to write both an interface and an abstract class.

The interface defines the contract of the polygon, while the abstract class contains the default implementation - which can include attributes like an array of vertices, and any methods you want to have default implementation for.

So you will have something like:

public interface Polygon { ... }

And in another file

public abstract class BasePolygonImpl implements Polygon {

protected Vertex[] vertices;

// ...
}

The reason for this is that if a person wants to create a Polygon which is implemented in a different way (for example, has a linked list of vertices or keeps its vertices in a database), they can create a class that implements Polygon and ignores the BasePolygonImpl class.

But if they want to implement a polygon which extends rather than replaces the default implementation, they can decide to use BasePolygonImpl as their superclass, and so to avoid repeating the base implementation.

The important point to notice is that interfaces do not define implementation, thus cannot include fields other than constants. Only classes can define implementation.

Variables in Interface

A field declared in an interface can only be a constant anyway, so why would it depend on which instance you use to access it?

Putting fields in interfaces is often poor style anyway these days. The interface is meant to reflect the capabilities of classes that implement it - which is completely orthogonal to the idea of a constant. It's certainly a nasty idea to use an interface just to declare a bunch of constants. I do occasionally find it useful to make the interface type expose constants which are simple implementations - so a filtering interface might have "ALLOW_ALL" and "ALLOW_NONE" fields, for example.

I suppose you could conceive of a scenario where implementing an interface did actually add an instance field to your class - but that would break encapsulation not only in terms of it being implicitly public, but also by specifying part of the implementation instead of the API.

How to use member variables with Interfaces and anonymous implementations

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.

Why can't refer interface variables by using super keyword

The super keyword refers to the parent class, not to any interface. In the code you've provided, Age is an interface. You would see the same behavior regardless of whether you're looking at an anonymous class or a named class.

If you're wondering why the language designers decided not to allow super to refer to an interface, Aggragoth commented on this: a class can implement multiple interfaces, so if they each had a member named number it would be impossible for the compiler to be sure which interface's number you are trying to refer to with super.number.

How am i able to change interface variable value in a class which is implementing that interface

You are actually changing the local variable in the main function. This variable is different from the one you declared in the interface which is indeed public, static and final by default. But there are no such restrictions on local variables.

Also if there is a variable with same name in the local scope then that variable is preferred over the variable with same name in the outer scope.

Edit:

As I explained earlier you are declaring x as local variable in main function and it is different from the variable x in the interface. In your main function do the following if you want a compile error while trying to change the interface x variable:

public static void main(String[] args) {
x=50;
System.out.println("X value is" +x);
}

Now you will see a compile error telling you the interface's x variable cannot be assigned.

C# Interfaces and classes. Variables used in the class needed in the interface can't be private, or private only public. Why?

An interface is a kind of contract that you state. Everything declared in the interface needs to be accessible in the type that inherits from said interface. When you now declare a method as private, you can't access it from the other object which tries to enact the contract, resulting in the interface not being implemented correctly.

This is also the reason, why interfaces do not have accessor declarations. The properties, methods and events defined in the interface are required to be public, because otherwise accessing the class instance through the interface would not work.

In your example, you derive Person from IPerson. Now imagine, you use it like this:

IPerson c = GetCustomer();

where GetCustomer is defined like this:

public IPerson GetCustomer() {
// internal code
}

All you have access to now, is the given values declared in the interface. This means that name and age are defined in the interface and are accessible.

Let's say, Person also declares some other properties, like IPerson parent { get; set; }. In this case, the parent may be of type Person or of any other type that inherits from IPerson. But you can always be sure that the object that gets assigned to this property derives from IPerson and will have the properties name and age defined.

There is also no reason to declare an interface for private members. What would be the benefit your code has from that? Interfaces exist to connect objects that do not know much about the other type, except the interface. Think of it, as a power plug: You plug it into the socket, but it does not care where the power comes from. And likewise, the socket doesn't care where the power is going. It is just the case that both use an interface the other can interact with.

Using an interface in a class just for itself would be pointless, because there is no information that is hidden or needs to be abstracted within a class.



Related Topics



Leave a reply



Submit