Why Are Variables Declared with Their Interface Name in Java

Why are variables declared with their interface name in Java?

When you read

List<String> list = new ArrayList<String>();

you get the idea that all you care about is being a List<String> and you put less emphasis on the actual implementation. Also, you restrict yourself to members declared by List<String> and not the particular implementation. You don't care if your data is stored in a linear array or some fancy data structure, as long as it looks like a List<String>.

On the other hand, reading the second line gives you the idea that the code cares about the variable being ArrayList<String>. By writing this, you are implicitly saying (to future readers) that you shouldn't blindly change actual object type because the rest of the code relies on the fact that it is really an ArrayList<String>.

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

variable declaration: why interface

You should always declare variables and return types as the least specialized classes possible, or, ideally, as interfaces, so that you can at any time change the implementation.

For example, if at some point you decide you want to use a TreeMap instead of a HashMap, then you'd only need to change:

private Map<String,String> namespaceMappings = new HashMap<String,String>();

to:

private Map<String,String> namespaceMappings = new TreeMap<String,String>();

No other change needed in the code.

The most value you get out of this though is with what your class makes public. So for example, if you had the method getNamespaceMappings() return a Map, then every piece of code using that method will simply know that they will be using a Map. If at some point you decide to internally represent this map as something other than a HashMap, then you'll keep this internal to your class.

If you make the method return a HashMap instead, then you're exposing implementation details. In the future, if you want to use something other than a HashMap, then all the code using this class will need to be changed to accommodate this.

How to declare a variable of type Interface and then assign to the variable an object of a Class that implements the Interface, and how to test this?

(I will use uppercase for the start of class and interface names)

Is my method valid in terms of declaring a variable of interface example and then assigning to the variable an object of exampleImpl that implements example?

Yes, but in this case it isn't needed and you shouldn't do it like this anyway. You assume that the object coming via the parameter e will always be a ExampleImpl instance because you have a hard coded cast of that variable. If it is not such a class you will get a ClassCastException. In this case you can remove the

Example eInst = (ExampleImpl)e;

line and use the variable e instead.

It must also return a variable of type example, but I do not know where newVar1 and newVar2 go when this happens since they are not defined in the interface.

You already have written the code

Example summedE = new ExampleImpl(normalisedNewVar1, normalisedNewVar2);
return summedE;

which will return an object, which implements the Example interface. So everything is fine here. If you want to use newVar1 and newVar2 depends on your implementation and requirement for the manipulate method.

Can I create an object within the test class to call this test on?

Yes, that's the normal way to do so. Write

Example obj = new ExampleImpl(4, 5);

in your test method to create an Example object you can work with. You can call the manipulate() method with a different Example object like this:

Example obj = new ExampleImpl(4, 5);
Example obj2 = new ExampleImpl(10, 20);
Example obj3 = obj.manipulate(obj2);

I want to check it returns the right manipulation based on an object "this" and the new object "e". Is there a way to do this?

That depends on what other methods are defined on your Example interface. You have written that it extends from a different interface, also named Example. Base on what is defined in that interface, you might call other methods on your Example object like this:

 Assert.assertEquals(42, obj3.getDifference()); // or whatever other methods you have

Variable named interface

In general my interface names start with I, like, IMyInterface. And I use 'i' as prefix for variable name where I need to indicate the variable is interface, like iMyInterfaceVar. But no such restriction or standard rule.

Just for sake of completeness, here is The Java Code Convention Guide

variable of Interface type

You cannot instantiate an interface, i.e. you cannot do

MyInterface foo = new MyInterface(); // Compile-time error.

What you can do is instantiate a class that implements the interface. That is, given a class MyClass

public class MyClass implements MyInterface {
// ...

@Override
void method_one() {
// ...
}
@Override
int method_two() {
// ...
}
}

you can instantiate it and place a reference to it in your variable like this:

MyInterface foo = new MyClass();

If you had another class implementing MyInterface

class MyClass2 implements MyInterface {
// ...
}

you can also substitute a reference to this class's instance under your variable:

MyInterface foo = new MyClass2();

This is where the power of interfaces lies: they define types, not a particular implementation and let you refer to any implementation of a given type.

It is a very good programming practice to make classes implement interfaces and to use these to refer to instances of these classes. This practice facilitates a great deal of flexibility and reuse.

Therefore, you should use interface type arguments and variables whenever it is conceivable that different implementations may be passed into the method you're implementing. For example, if you're working with a HashSet<T> instance, you should use a variable of type Set<T> to refer to it (class HashSet<T> implements interface Set<T>).

Use interface or type for variable definition in java?

List<T> is interface, where ArrayList<T> is class, and this class implements List<T> interface.

I would prefer 2nd form, which is more general, ie if you do not use methods specific to ArrayList<T> you can declare its type as interface List<T> type. With 2nd form it will be easier to change implementation from ArrayList<T> to other class that implements List<T> interface.

EDIT:
As many of SO users commented both forms can be arguments to any method that accept List<T> or ArrrayList<T>. But when I declare method I would prefer interface:

 void showAll(List <String> sl) ...

and use:

 void showAllAS(ArrayList <String> sl) ...

only when my method uses method specific to ArrayList<T>, like ensureCapacity().

Response with information that we should use typed List<T> instead of just List is very good (of course if we do not use ancient Java).

Java - declaring variables in an interface but not assigning them

You can't force a class to have a variable, but with an interface you can force it to have a method. Change your edges variable in your interface to a method.

public interface Shapeable {
int getNumEdges();
}

Then implementers must implement the method, but they're free to return any number of edges they want.

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.



Related Topics



Leave a reply



Submit