define common variables across multiple classes using interfaces - java

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.

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.

Use getter/setter methods in interface

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();

Private Access Specifier usage in Java Inheritance

We can access the Super Class methods which consists of operations on private data members and print the results.But why can't I print the private data members of Super Class with the SubClass object calling them in my main function? Someone please explain me.
Here is the example below.
class SuperClass1
{
private int a;
private int b;
SuperClass1(int p,int q)
{
a=p;
b=q;
}
SuperClass1(SuperClass1 obj)
{
a=obj.a;
b=obj.b;
}
SuperClass1()
{
a=-1;
b=-1;
}
int Vol()
{
return a*b;
}
}
class SubClass1 extends SuperClass1
{
int c;
SubClass1(int p,int q,int r)
{
super(p,q);
c=r;
}
SubClass1(SubClass1 obj)
{
super(obj);
c=obj.c;
}
SubClass1()
{
super();
c=-1;
}
}
public class Super
{
public static void main(String[] args)
{
SubClass1 obj1=new SubClass1();
//System.out.println("The values of obj1 are:"+obj1.a+""+obj1.b+""+obj1.c);
int vol=obj1.Vol();
System.out.println("The volume is :"+vol);
}
}
security and encapsulation
The superclass is letting its subclasses use only the public and protected methods/fields.
This allows the designer of the superclass to change the implementation of these methods if he sees it better, without breaking the subclass's correctness.
A text book example is a complex number class.
The programmer using this class only needs its functionality, he doesn't care if the implementation is with imaginary and real fields or with radius and theta fields [two distinct ways to represent complex number].
It allows the designer of the ComplexNumber class more freedom if he wants to change the class in later versions, and it also allows the user less worries: he doesn't need to take care for all the details, some are being taken care of for him.
Bonus: note you can break this behavior and access private fields and methods by using reflection - but when you do so - all bets are off, and you do it on your own responsibility.
Your question isn't very clear without an example, but I suspect that the "methods which consist of operations on private data members" aren't private. It doesn't matter that they work by accessing private data - they're not private themselves. It would be pretty pointless having access modifiers if public methods could only access other public members etc.
The whole point of encapsulation is that only the class itself should care about implementation details such as the fields in question, but can expose a contract in terms of its public (and protected) API. Code outside the class shouldn't care about the private implementation details.
JLS says:
Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.
So, to answer you question. No, private members are not accessible by subclasses.
Private members are not inherited; only the protected and public members are.
If possible, you can do one of the following:
Make the private properties of the superclass protected
Make public getters (and setters if needed) for the private properties

Why not abstract fields?

Why can't Java classes have abstract fields like they can with abstract methods?
For example: I have two classes that extend the same abstract base class. These two classes each have a method that is identical except for a String constant, which happens to be an error message, within them. If fields could be abstract, I could make this constant abstract and pull the method up into the base class. Instead, I have to create an abstract method, called getErrMsg() in this case, that returns the String, override this method in the two derived classes, and then I can pull up the method (which now calls the abstract method).
Why couldn't I just make the field abstract to begin with? Could Java have been designed to allow this?
You can do what you described by having a final field in your abstract class that is initialised in its constructor (untested code):
abstract class Base {
final String errMsg;
Base(String msg) {
errMsg = msg;
}
abstract String doSomething();
}
class Sub extends Base {
Sub() {
super("Sub message");
}
String doSomething() {
return errMsg + " from something";
}
}
If your child class "forgets" to initialise the final through the super constructor the compiler will give a warning an error, just like when an abstract method is not implemented.
I see no point in that. You can move the function to the abstract class and just override some protected field. I don't know if this works with constants but the effect is the same:
public abstract class Abstract {
protected String errorMsg = "";
public String getErrMsg() {
return this.errorMsg;
}
}
public class Foo extends Abstract {
public Foo() {
this.errorMsg = "Foo";
}
}
public class Bar extends Abstract {
public Bar() {
this.errorMsg = "Bar";
}
}
So your point is that you want to enforce the implementation/overriding/whatever of errorMsg in the subclasses? I thought you just wanted to have the method in the base class and didn't know how to deal with the field then.
Obviously it could have been designed to allow this, but under the covers it'd still have to do dynamic dispatch, and hence a method call. Java's design (at least in the early days) was, to some extent, an attempt to be minimalist. That is, the designers tried to avoid adding new features if they could be easily simulated by other features already in the language.
Reading your title, I thought you were referring to abstract instance members; and I couldn't see much use for them. But abstract static members is another matter entirely.
I have often wished that I could declare a method like the following in Java:
public abstract class MyClass {
public static abstract MyClass createInstance();
// more stuff...
}
Basically, I would like to insist that concrete implementations of my parent class provide a static factory method with a specific signature. This would allow me to get a reference to a concrete class with Class.forName() and be certain that I could construct one in a convention of my choosing.
Another option is to define the field as a public (final, if you like) in the base class, and then initialize that field in the constructor of the base class, depending upon which subclass is currently being used. It's a bit shady, in that it introduces a circular dependency. But, at least it's not a dependency that can ever change -- i.e., the subclass will either exist or not exist, but the subclass's methods or fields can not influence the value of field.
public abstract class Base {
public final int field;
public Base() {
if (this instanceof SubClassOne) {
field = 1;
} else if (this instanceof SubClassTwo) {
field = 2;
} else {
// assertion, thrown exception, set to -1, whatever you want to do
// to trigger an error
field = -1;
}
}
}

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