implementing static methods for interface - java

suppose I have an interface:
public interface abcd{
public int a();
public void b();
public void c();
public String d(String h, String j);
}
and I implement it in some class:
public class xyzw implements abcd{
}
but I want the method d() to be static, but I can't do this:
public class xyzw implements abcd{
public static void c(){
//some code
}
}
neither can I do this:
public interface abcd{
public int a();
public void b();
public static void c();
public String d(String h, String j);
}
I wonder if there is something or some workaround or some language construct which allows me to make a method defined by an interface a static method?

You can define a static method in interface, but only with implementation.
public interface A {
public static void b() {
System.out.println("Hi");
}
}
Overriding of static methods is not allowed in Java, because you call it on Class object, not on implementation object.

If you can implement a static method in an interface, but you cannot overwrite it, remember that a static method is referenced by the class itself and not by an instance of it.
To solve your problem maybe you could define an abstract class

No, its not possible and doesn't make any sense. An interface is meant to be implemented by subclasses you can only hava a non-abstract, implemented, static method in an interface. You could not statically call your interface method with
abcd.c()
when it has no implementation. Thats why static elements can not be overridden.

It's not possible to override static methods in java.
However, in the subclass, you can declare static method with the same name and "mask it as" the original method - which is as close as you can get.
interface a {
public static int f() {
return 0;
}
}
interface b extends a {
public static int f() {
return 1;
}
}
System.out.println(a.f());
>> 0
System.out.println(b.f());
>> 1

Related

static inheritance: is it possible? Are there better solutions?

Consider this example (warning-very bad code):
public abstract class A {
static float foo;
public static void loadfoo(float incomingfoo) {
foo = incomingfoo;
}
public static void displayfoo() {
System.out.println("your foo is" +foo);
}
}
Class B extends Class A
public class B extends A {
static float foo;
//#Override (overide is not allowed for static methods. dis is a problem...)
public static void loadfoo(float incomingfoo){
foo = incomingfoo;
}
}
Class C is pretty much the same as B
public class C extends A {
static float foo;
//#Override
public static void loadfoo(float incomingfoo) {
//I would like a different static variable loaded into this class using this method
foo = incomingfoo;
}
}
finally the main Class runs the thing
public class Main {
public static void main(String whatever[]){
B.loadfoo(5);
C.loadfoo(8);
B.displayfoo();
C.displayfoo();
}
}
so the output of this is :
your foo is0.0
your foo is0.0
and I am aware this is because the displayfoo class reference the static foo in Class A, so please disregard this. I assume I have now been specific enough about describing my problem and goal. solutions anyone?
Edit: I feel like an idiot I completely forgot to actually state what I wanted to accomplish, but really all I want is for B and C to have there own static variables loaded into them without altering A's variable, which should be the default.
It looks like you need static access to two stateful objects with the same structure. In this case, an enum might be a solution:
public enum A {
B, C;
private float foo;
// getter and (optional) setter for foo here
public void displayFoo() { System.out.println("This foo is " + foo); }
}
This way you can still access your object statically, but don't need to duplicate anything else:
A.B.setFoo(5);
A.C.setFoo(8);
A.B.displayFoo(); // 5
A.C.displayFoo(); // 8
If you then need a static default, I would make it a method on A:
enum A {
A getDefault() { return A.B; }
}
A.getDefault().displayFoo();
It seems that first you want to load the values using loadfoo to foo and then display the value of that foo using the displayfoo method. Well, I don't think there is anyway to do it using static methods.You can do this by making displayfoo() method abstract and overriding the same in the subclasses B and C.
Here is the code:
abstract class A {
float foo;
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
public abstract void displayfoo();
}
class B extends A{
#Override
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
class C extends A{
#Override
public void loadfoo(float incomingfoo){
this.foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
public class Main {
public static void main(String whatever[]){
B b = new B();
C c = new C();
b.loadfoo(5);
c.loadfoo(5);
b.displayfoo();
c.displayfoo();
}
}
You can also check the same kind of question here.
Static methods should be used by static method access and not by object instance. It's not supposed to be virtual because it's not belong to the object.
If you call B.loadfoo() then a method of B class is called.
If you call C.loadfoo() then a method of C class is called.
You cannot call a static method if it doesn't exist in the class.
There's no point to use static methods if you want to use polimorphism.

overriding instance method with static keyword

How can I override instance methods of super class as static in subclass? I think this is impossible but is there any indirect way?
public class A {
public void test(){
System.out.println("");
}
}
public class B extends A{
public static void test(){//test() in B cannot override test() in A
//overriding method is static
}
}
You can't, since a static method is not an instance method. You could override the instance method with an instance method that calls the static method.
public class B extends A {
#Override
public void test(){
staticTest();
}
public static void staticTest() {
}
}
I'm not sure how much sense that would make though.

Calling class's methods into an interface

I have created some interface such that:
public interface A{
}
and i would like to call the method a that I have already implemented in class B in interface A such that:
public class B{
public boolean a(){
return true;
}
}
public interface A{
public void call {
a();
}
}
without any errors, any help please?
What you want to do is strictly speaking impossible, as you cannot define method implementations in an interface. You can get something similar by defining an implementation of the interface that extends B. Hopefully that is close enough.
public class AImplementation extends B implements A{
public void call(){
a();
}
}
If you are using any java version before 8, then stick with the answers of #tinker and #Davis Broda. They provide better design since they do not couple your interface to the B class. If you insist however, in java 8 you can have default method implementations as well as static methods in an interface.
If your method is for inheritance then you have to use a default method. Add the default keyword:
default void call() {
...
}
Now the problem is how to get a reference to the class in order to call the method since you cannot have instance fields in interfaces. You have two choices:
Pass the object of B as a method parameter:
public interface A{
default void call(B b) {
b.a();
}
}
or make the method in B static
public interface A{
default void call() {
B.a();
}
}
If your method is not for inheritance but just a utility than you can make it static as :
public interface A{
public static void call() {
B.a();
}
}
I agree with #Davis Broda's answer, there is no way to have a method definition in an interface. But I have another way to address this.
You can have the interface and then have an abstract class implement this interface, and then have all other classes extend the abstract class. The abstract class doesn't have to extend the class from where you want to call the method, you could call it from an instance of that class too.
public interface A {
void caller();
}
public class B {
public void callMe() {
}
}
public class AbstractA implements A {
private B b;
public AbstractA(B b) {
this.b = b;
}
#Override
public void caller() {
b.callMe();
}
}
This way, all implementations of AbstractA will be able to call B's callMe method. And you can access this directly from the interface using this code:
A anInstance = someInstance;
anInstance.caller();
Your question is not very clear, but if I'm guessing right, you want interface A to be kind of a generic caller.
If you're using Java 8, you can achive that using a method reference:
public class B {
public boolean a() {
return true;
}
}
public interface A<T> {
default T call(Supplier<T> s) {
return s.get();
}
}
public class AImpl
implements A<Boolean> {
}
public class Sample {
public static void main(String[] args) {
AImpl a = new AImpl();
B b = new B();
boolean result = a.call(b::a);
System.out.println(result); // true
}
}
This uses Supplier<T> because your method a() in class B returns a boolean and does not receive any arguments.

Inheritance and Private Methods

Given the following block of code:
public class Trial {
public static void main (String[] args){
B obj = new B();
obj.doMethod(); #prints "From A".
}
}
class A {
private void method(){System.out.print("from A");}
public void doMethod(){method();}
}
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
It turns out that the method() from class A is invoked. Why is this?
You explicitly implement it that way. super calls method from base class which is A
public void doMethod(){super.doMethod();}
So the method chaining is like this:
B.doMethod() -> A.doMethod() -> A.method() -> "from A"
I think your question is if in class A private void method(){System.out.print("from A");} is private then why is printing "from A" in class B.
Answer is very simple you can't call method() of A class form any other class .But you can call it with object of its own.
when you calls super.doMethod(); then its function of super and method() is its own method so it can call it.
Because, see below:
class B extends A {
public void method(){System.out.print("from B");}
public void doMethod(){super.doMethod();}
}
Here in Class B's doMethod() you're invoiking Class A's doMethod() using super.doMethod(). So obviously it's printing Class A's doMethod().
You call the doMethod with super keyword. It's means it will call parent implementation
More on super keyword
Your code gives simple object creation (B obj = new B();) and a call using super. Super is used like other people mentioned for parent class. Things could have been different if you try something like (A obj = new B();), which is more interesting.
method() in class A is private and private methods can't be overriden. And when overriding it's better to use #Override annotion.
class B extends A {
#Override
public void method(){System.out.print("from B");} // Compile error
}
A similar thing happens, if you change the method to a static method.
class A {
public static void method(){System.out.print("from A");}
}
class B extends A {
public static void method(){System.out.print("from B");}
}

What to do with static method overrides?

For example,
public class A {
public static int f() { return 1; }
}
public class B extends A {
public static long f() { return 100L; }
}
Unfortunately B.f() couldn't be compiled because B.f() tries to override A.f(), and so the name clashes because the return types aren't compatible.
I'm weired what's purpose to override a static method? Any use case? Can I just hide away A.f() in class B?
Actual usage:
class EntityDTO {
public static List<EntityDTO> marshal(Collection<? extends Entity> entities) {
...
}
}
class BookDTO extends EntityDTO {
public static List<BookDTO> marshal(Collection<? extends Book> books) {
...
}
}
Strictly speaking, static methods can not be overridden. Method overriding is exclusively a feature of object polymorphism, and static methods doesn't belong to any object but the class itself.
Having clarified that, you should not make any of your methods static. That would solve your problem in hand, at least. As the method arguments are different, it will not be considered as overriding, but overloading.
static methods are not overriden...But it is called method hiding. The benefits of using the same method name and parameters are just like any other method overriding benefits
static method can not be overridden.
Notice: your B.f() should return int rather than long to pass compile.
I can't think of a use case where overriding static functions (in Java) can be useful, but if you ever absolutely must achieve it, here's how:
import java.lang.reflect.Method;
class A {
public static void callOut() {
System.out.println("A.callOut");
}
}
public class B extends A {
public static void callOut() {
System.out.println("B.callOut");
}
public static void main(String[] args) throws Exception
{
A a = new A();
A b = new B();
Method aM = a.getClass().getMethod("callOut");
Method bM = b.getClass().getMethod("callOut");
aM.invoke(null); // prints A.callOut
bM.invoke(null); // prints B.callOut
}
}
Maybe you need to rethink you design, if you have a need to override the marshal method, then it shouldn't be static in the first place.

Categories

Resources