Use getter/setter methods in interface - java

My question is how can I write setter/getter methods and static fields in an interface and implement it in another class.
An example:
public interface MyInterface {
int number = 0;
public int setNumber(int num);{
}
}
// Use it
public MyClass implements MyInterface{
...
public int setNumber(int num) {
number = num; // Error, Why?
}
}
I get error on number = num but it get no error in the setName(...) method!

You cannot define instance fields in interfaces (unless they are constant - static final - values, thanks to Jon), since they're part of the implementation only. Thus, only the getter and setter are in the interface, whereas the field comes up in the implementation.
And setNumber should return a void instead of int. For getting I suggest you to add int getNumber().
public interface MyInterface {
void setNumber(int num); // public is implicit in interfaces
int getNumber(); // obviously
}
public class MyClass implements MyInterface {
private int number = 0;
public void setNumber(int num) { this.number = num; }
public int getNumber() { return this.number; }
}
As you can see, only setNumber is part of MyInterface. Consumers do not need to know about how the number is stored, therefore it is an implementation detail.
Besides, in Java you name classes and interfaces in PascalCase rather than camelCase.

When you define a value in an interface it is implicitly public static final i.e. it's immutable and not an instance field.
Interfaces are used for defining a contract, not behaviour so it doesn't make sense to insist that all implementations have this field.
BTW You can do this if you have an abstract class as well as or instead of an interface

You cannot change the fields declared in an interface as they are by deafulat public static final.
You see final so they cannot be changed once initialized.
And in an interface you cannot give implementation of a method as you are doing in your code.
just put ; after the method signature and not {} (not even empty {}) :
public int setNumber(int num);

Interface can not contain method body definition and field are public, final and static by default which normally use for constant declaration. It will be defined where you are going to implement this interface.
In the Java programming language, an interface is a reference type, similar to a class, that can contain only constants, method signatures, and nested types. There are no method bodies. Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces.
ref
But abstract class can contain concrete method as well as abstract method.

Fields in interface are by default public static final i.e., constants.remember you have already initialized number in your interface and trying to change its value in your implementing class which breaks the laws of final variables .
From JLS:
A variable can be declared final. A final variable may only be
assigned to once. Declaring a variable final can serve as useful
documentation that its value will not change and can help avoid
programming errors.
It is a compile-time error if a final variable is assigned to unless
it is definitely unassigned (§16) immediately prior to the assignment.
Also methods in interface are by default public abstract. i dont understand your method signature in your interface. it should be something like below.
public void method();

Related

Is there any difference when a field is static or not when it belongs to an abstract class?

public abstract class Test {
private static int value = 100;
}
And
public abstract class Test {
private int value = 100;
}
Since Test is abstract, it can't be instantiated, and therefore it doesn't make any difference whether value is static or not, right?
Is there any difference when a field is static or not when it belongs to an abstract class?
Yes, there is. Even thou your class is abstract, it can have non-abstract non-static methods working with non-static private fields. It is usefull sometimes.
Dummy exaple:
Consider following: you want to hold one integer and give everyone the ability to change it, but you dont want them to set negative values, or values bigger then 15, but the condition isn't known (in general) by everyone, so you want to ensure that when someone sets incorect value, it gets fixed automaticly.
Here is one possible solution:
abstract class MyInt {
private int myInt;
public int getMyInt() {
return myInt;
}
public void setMyInt(int i) {
myInt = checkMyInt(i);
}
protected abstract int checkMyInt(int i);
}
Now you can inplement any logic in checkMyInt() and hand over the instance declared as MyInt
pastebin exaplme
PS: this probably isnt the best solution and i would use interfaces here, but as an example it is enought i hope
Abstract classes can't be instantiated directly. But the whole point of abstract classes is to have subclasses that are instantiated:
public abstract class Test
protected int value;
}
public class TestImpl extends Test {
public TestImpl(int value) {
this.value = value;
}
}
In the above example, each instance of TestImpl (and thus of Test) has its own value. With a static field, the field is scoped to the Test class, and shared by all instances.
The difference between static and non-static fields is thus exactly the same as with any other non-abstract class.
An abstract class is a normal (base) class, just declared to be missing some things, like abstract methods.
So there is definite a difference.

Most concise and efficient way to share common handling code for a per-class object?

I have a series of classes, A,B,C... (several dozen in total) that share common code. There can be many instance of each class A,B,C... . I'm planning to create a superclass, Abstract, that will contain that code instead.
Problem is, the common stuff works on an object that is unique on a per-class (not per-instance) basis. This is currently solved by A,B,C... each having a static field with the corresponding value. Obviously, when I refactor the functionality into Abstract, this needs to be changed into something else.
In practice, it currently looks like this (note that the actual type is not String, this is just for demonstrative purposes) :
public class A implements CommonInterface {
private static final String specificVar = "A";
#Override
public void common() {
specificVar.contains('');
}
}
public class B implements CommonInterface {
private static final String specificVar = "B";
#Override
public void common() {
specificVar.contains('');
}
}
The best idea I've come up with until now is to have a Map<Class<? extends Abstract>,K> (where K is the relevant type) static field in Abstract, and A,B,C... each containing a static initalization block that places the relevant value into the map. However, I'm not convinced this is the best that can be done.
Note that I'm not using any DI framework.
So, what would be the most concise, in terms of code contained in the subclasses, way to refactor the static fields in A,B,C... handled by the common code, without sacrificing field access efficiency?
Perhaps an enum is what you want.
enum MyInstances implements MyInterface {
A {
fields and methods for A
}, B {
fields and methods for B
};
common fields for all MyInstances
common methods for all MyInstances
}
// To lookup an instance
MyInstances mi = MyInstances.valueOf("A");
As you haven't shown any source code, we can't really tell if the use of static fields is a good or a bad design choice.
Considering the use of static fields by the subclasses is indeed a good design choice, the first way of having common code in a superclass to access them is by calling abstract methods that would be implemented in the subclasses.
Example:
public abstract class SuperClass {
public void processCommonLogic() {
// Common logic
// Execute specific logic in subclasses
processSpecificLogic();
}
public abstract void processCommonLogic();
}
public class ASubClass extends SuperClass {
public static int SPECIFIC_SUBCLASS_CONSTANT = 0;
public void processSpecificLogic() {
// Specific subclass logic
doSomethingWith(ASubClass.SPECIFIC_SUBCLASS_CONSTANT);
}
}
You could use the Template Method Pattern.
Have an abstract method getValue() defined in your abstract class and used within your abstract class wherever you require the value. Then each of your subclasses simply need to implement the getValue method and return the correct value for that subclass.

define common variables across multiple classes using interfaces

I have a sample interface
public interface SampleVariables {
int var1=0;
int var2=0;
}
and I want to use var1 and var2 across multiple classes i am trying to do this using
public class InterfaceImplementor extends Message implements SampleVariables{
private int var3;
public int getVar1(){
return var1;
}
public void setVar1(int var1){
SampleVariables.var1=var1; // ** error here in eclipse which says " remove final modifier of 'var1' " Though I have not defined it as final
}
public int getVar3() {
return var3;
}
public void setVar3(int var3) {
this.var3 = var3;
}
}
where class Message is a pre-defined class which I try to use and I cannot define var1, var2 in the class Message.
Is there a better way to do this? Or am I missing something really simple ?
All fields in an interface are implicitly static and final, hence your warning above. See this SO question for more details.
It seems to me that you want a base class with these variables, but as you've noted you can't do this since you're deriving from a 3rd party class.
I would not derive from that 3rd-party class, since you don't control its implementation. I would rather create a class that wraps it and provides your additional functionality. That gives you a level of comfort that if/when that 3rd-party class changes, you can limit the scope of the changes that you have to subsequently make.
Unfortunately Java doesn't support mixins, which is what you're trying to achieve here.
In interface by default variables are static final you cannot change there value ie. you cannot do SampleVariables.var1=var1;
what you can do is
public class InterfaceImplementor extends Message { // do not implement interface here
private int var3;
private int var1;
public void setVar1(int var1){
this.var1=var1; // will work
}
and to access variable of interface SampleVariables.var1
Since member variable of Interface are by default static, final so you can't reassign the value again once you have initialized.
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.
See Java Language Specification.
You should use an abstract class for this.
example:
public abstract class AbstractClass {
protected int var1;
}
class SubClass1 extends AbstractClass {
}
class SubClass2 extends AbstractClass {
}
This way SubClass1 and SubClass2 will have a var1. Note that you can do the same with getters and setters, but for making the point this was shorter.

How to create an "abstract field"?

I know abstract fields do not exist in java. I also read this question but the solutions proposed won't solve my problem. Maybe there is no solution, but it's worth asking :)
Problem
I have an abstract class that does an operation in the constructor depending on the value of one of its fields.
The problem is that the value of this field will change depending on the subclass.
How can I do so that the operation is done on the value of the field redefined by the subclass ?
If I just "override" the field in the subclass the operation is done on the value of the field in the abstract class.
I'm open to any solution that would ensure that the operation will be done during the instantiation of the subclass (ie putting the operation in a method called by each subclass in the constructor is not a valid solution, because someone might extend the abstract class and forget to call the method).
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Edit:
My subclasses are actually some tools used by my main program, so the constructor has to be public and take exactly the arguments with which they will be called:
tools[0]=new Hand(this);
tools[1]=new Pencil(this);
tools[2]=new AddObject(this);
(the subclasses are Hand, Pencil and AddObject that all extend the abstract class Tool)
That's why I don't want to change the constructor.
The solution I'm about to use is to slightly change the above code to:
tools[0]=new Hand(this);
tools[0].init();
tools[1]=new Pencil(this);
tools[1].init();
tools[2]=new AddObject(this);
tools[2].init();
and use an abstract getter to acces the field.
How about abstract getter/setter for field?
abstract class AbstractSuper {
public AbstractSuper() {
if (getFldName().equals("abc")) {
//....
}
}
abstract public void setFldName();
abstract public String getFldName();
}
class Sub extends AbstractSuper {
#Override
public void setFldName() {
///....
}
#Override
public String getFldName() {
return "def";
}
}
Also, I don't want to give the value
of the field as an argument of the
constructor.
Why not? It's the perfect solution. Make the constructor protected and offer no default constructor, and subclass implementers are forced to supply a value in their constructors - which can be public and pass a constant value to the superclass, making the parameter invisible to users of the subclasses.
public abstract class Tool{
protected int id;
protected Main main;
protected Tool(int id, Main main)
{
this.id = id;
this.main = main;
}
}
public class Pencil{
public static final int PENCIL_ID = 2;
public Pencil(Main main)
{
super(PENCIL_ID, main);
}
}
How about using the Template pattern?
public abstract class Template {
private String field;
public void Template() {
field = init();
}
abstract String init();
}
In this way, you force all subclasses to implement the init() method, which, since it being called by the constructor, will assign the field for you.
You can't do this in the constructor since the super class is going to be initialized before anything in the subclass. So accessing values that are specific to your subclass will fail in your super constructor.
Consider using a factory method to create your object. For instance:
private MyClass() { super() }
private void init() {
// do something with the field
}
public static MyClass create() {
MyClass result = new MyClass();
result.init();
return result;
}
You have an issue in this particular sample where MyClass can't be subclassed, but you could make the constructor protected. Make sure your base class has a public / protected constructor also for this code. It's just meant to illustrate you probably need two step initialization for what you want to do.
Another potential solution you could use is using a Factory class that creates all variants of this abstract class and you could pass the field into the constructor. Your Factory would be the only one that knows about the field and users of the Factory could be oblivious to it.
EDIT: Even without the factory, you could make your abstract base class require the field in the the constructor so all subclasses have to pass in a value to it when instantiated.
Also, I don't want to give the value of the field as an argument of the constructor.
Is there any solution to do that, or should I just change my design ?
Yes, I think you should change your design so that the subclass passes the value to the constructor. Since the subclass portion of your object isn't initialized until after the superclass constructor has returned, there's really no other clean way of doing it. Sure, this'd work:
class Super {
protected abstract int abstractField();
protected Super() { System.out.println("Abstract field: " + abstractField); }
}
class Sub {
protected int abstractField(){ return 1337; }
}
... since the implementation of abstractField() doesn't operate on object state. However, you can't guarantee that subclasses won't think it's a great idea to be a little more dynamic, and let abstractField() returns a non-constant value:
class Sub2 {
private int value = 5;
protected int abstractField(){ return value; }
public void setValue(int v){ value = v; }
}
class Sub3 {
private final int value;
public Sub3(int v){ value = v; }
protected int abstractField(){ return value; }
}
This does not do what you'd expect it to, since the initializers and constructors of subclasses run after those of the superclass. Both new Sub2() and new Sub3(42) would print Abstract field: 0 since the value fields haven't been initialized when abstractField() is called.
Passing the value to the constructor also has the added benefit that the field you store the value in can be final.
If the value is determined by the type of subclass, why do you need a field at all? You can have a simple abstract method which is implemented to return a different value for each subclass.
I think you need a factory (aka "virtual constructor") that can act on that parameter.
If it's hard to do in a given language, you're probably thinking about it incorrectly.
If I understand you correctly: You want the abstract class's constructor to do something depending on a field in the abstract class but which is set (hopefully) by the subclass?
If I got this wrong you can stop reading ...
But if I got it right then you are trying to do something that is impossible. The fields of a class are instantiated in lexical order (and so if you declare fields "below", or "after", the constructor then those will not be instantiated before the constructor is called). Additionally, the JVM runs through the entire superclass before doing anything with the subclass (which is why the "super()" call in a subclass's constructor needs to be the first instruction in the constructor ... because this is merely "advice" to the JVM on how to run the superclass's constructor).
So a subclass starts to instantiate only after the superclass has been fully instantiated (and the superclass's is constructor has returned).
And this is why you can't have abstract fields: An abstract field would not exist in the abstract class (but only in the subclass) and so is seriously(!) "off limits" to the super (abstract) class ... because the JVM can't bind anything references to the field (cause it doesn't exist).
Hope this helps.

Why can't I declare static methods in an interface?

The topic says the most of it - what is the reason for the fact that static methods can't be declared in an interface?
public interface ITest {
public static String test();
}
The code above gives me the following error (in Eclipse, at least): "Illegal modifier for the interface method ITest.test(); only public & abstract are permitted".
There are a few issues at play here. The first is the issue of declaring a static method without defining it. This is the difference between
public interface Foo {
public static int bar();
}
and
public interface Foo {
public static int bar() {
...
}
}
The first is impossible for the reasons that Espo mentions: you don't know which implementing class is the correct definition.
Java could allow the latter; and in fact, starting in Java 8, it does!
The reason why you can't have a static method in an interface lies in the way Java resolves static references. Java will not bother looking for an instance of a class when attempting to execute a static method. This is because static methods are not instance dependent and hence can be executed straight from the class file. Given that all methods in an interface are abstract, the VM would have to look for a particular implementation of the interface in order to find the code behind the static method so that it could be executed. This then contradicts how static method resolution works and would introduce an inconsistency into the language.
I'll answer your question with an example. Suppose we had a Math class with a static method add. You would call this method like so:
Math.add(2, 3);
If Math were an interface instead of a class, it could not have any defined functions. As such, saying something like Math.add(2, 3) makes no sense.
The reason lies in the design-principle, that java does not allow multiple inheritance. The problem with multiple inheritance can be illustrated by the following example:
public class A {
public method x() {...}
}
public class B {
public method x() {...}
}
public class C extends A, B { ... }
Now what happens if you call C.x()? Will be A.x() or B.x() executed? Every language with multiple inheritance has to solve this problem.
Interfaces allow in Java some sort of restricted multiple inheritance. To avoid the problem above, they are not allowed to have methods. If we look at the same problem with interfaces and static methods:
public interface A {
public static method x() {...}
}
public interface B {
public static method x() {...}
}
public class C implements A, B { ... }
Same problem here, what happen if you call C.x()?
Static methods are not instance methods. There's no instance context, therefore to implement it from the interface makes little sense.
Now Java8 allows us to define even Static Methods in Interface.
interface X {
static void foo() {
System.out.println("foo");
}
}
class Y implements X {
//...
}
public class Z {
public static void main(String[] args) {
X.foo();
// Y.foo(); // won't compile because foo() is a Static Method of X and not Y
}
}
Note: Methods in Interface are still public abstract by default if we don't explicitly use the keywords default/static to make them Default methods and Static methods resp.
There's a very nice and concise answer to your question here. (It struck me as such a nicely straightforward way of explaining it that I want to link it from here.)
It seems the static method in the interface might be supported in Java 8, well, my solution is just define them in the inner class.
interface Foo {
// ...
class fn {
public static void func1(...) {
// ...
}
}
}
The same technique can also be used in annotations:
public #interface Foo {
String value();
class fn {
public static String getValue(Object obj) {
Foo foo = obj.getClass().getAnnotation(Foo.class);
return foo == null ? null : foo.value();
}
}
}
The inner class should always be accessed in the form of Interface.fn... instead of Class.fn..., then, you can get rid of ambiguous problem.
An interface is used for polymorphism, which applies to Objects, not types. Therefore (as already noted) it makes no sense to have an static interface member.
Java 8 Had changed the world you can have static methods in interface but it forces you to provide implementation for that.
public interface StaticMethodInterface {
public static int testStaticMethod() {
return 0;
}
/**
* Illegal combination of modifiers for the interface method
* testStaticMethod; only one of abstract, default, or static permitted
*
* #param i
* #return
*/
// public static abstract int testStaticMethod(float i);
default int testNonStaticMethod() {
return 1;
}
/**
* Without implementation.
*
* #param i
* #return
*/
int testNonStaticMethod(float i);
}
Illegal combination of modifiers : static and abstract
If a member of a class is declared as static, it can be used with its class name which is confined to that class, without creating an object.
If a member of a class is declared as abstract, you need to declare the class as abstract and you need to provide the implementation of the abstract member in its inherited class (Sub-Class).
You need to provide an implementation to the abstract member of a class in sub-class where you are going to change the behaviour of static method, also declared as abstract which is a confined to the base class, which is not correct
Since static methods can not be inherited . So no use placing it in the interface. Interface is basically a contract which all its subscribers have to follow . Placing a static method in interface will force the subscribers to implement it . which now becomes contradictory to the fact that static methods can not be inherited .
With Java 8, interfaces can now have static methods.
For example, Comparator has a static naturalOrder() method.
The requirement that interfaces cannot have implementations has also been relaxed. Interfaces can now declare "default" method implementations, which are like normal implementations with one exception: if you inherit both a default implementation from an interface and a normal implementation from a superclass, the superclass's implementation will always take priority.
Perhaps a code example would help, I'm going to use C#, but you should be able to follow along.
Lets pretend we have an interface called IPayable
public interface IPayable
{
public Pay(double amount);
}
Now, we have two concrete classes that implement this interface:
public class BusinessAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
public class CustomerAccount : IPayable
{
public void Pay(double amount)
{
//Logic
}
}
Now, lets pretend we have a collection of various accounts, to do this we will use a generic list of the type IPayable
List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());
Now, we want to pay $50.00 to all those accounts:
foreach (IPayable account in accountsToPay)
{
account.Pay(50.00);
}
So now you see how interfaces are incredibly useful.
They are used on instantiated objects only. Not on static classes.
If you had made pay static, when looping through the IPayable's in accountsToPay there would be no way to figure out if it should call pay on BusinessAcount or CustomerAccount.

Categories

Resources