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.
Related
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
In java, i can do this:
public class A {
//...
}
public class B extends A {
//...
}
public interface I {
void test(A a);
}
public class C implements I {
//i can use class B as parameters in java but how to do in .net ?
// not work in .net
#override
public void test(B b){
}
}
I can use class B as parameters in java but how to do in .net ?
In order to implement the interface member I.test(A a), the the test() method of the C must be public, non-static, and have the same name and signature as the interface member.
C.test fails one criterion: it does not have the same signature as I.test.
Option 1: Implement the Interface
public class A {
//...
}
public class B extends A {
//...
}
public interface I {
void test(A a);
}
public class C implements I {
public void test(A a){
}
}
of course you can still pass B instances into C.test:
var b = new B();
var c = new C();
c.test(b);//works just fine
Option 2: Change the Interface
Say your implementation of I in C depends on a property present on B but not on A. Suppose further that it makes sense that I.test is a perfectly valid method to write so long as the parameter being passed in extends A.
In that scenario, you can try something like this:
public class A
{
//...
}
public class B : A
{
//...
}
public interface I<T> where T : A
{
void test(T a);
}
public class C : I<B>
{
public void test(B b)
{
}
}
Which utilizes generics as well as generic type constraints and seems like it may be a little closer to what you are trying to represent/accomplish.
So suppose I have 2 classes:
public class A
{
public void
f()
{
}
}
public class B
{
public void
f()
{
}
}
I would like to write a generic static method that could call f when passed an instance of A or B. I tried:
public class C
{
public static <T extends A & B> void
g(T t)
{
t.f();
}
public static void main(String[] args)
{
A a = new A();
g(a);
}
}
But the compiler claims A is not a valid substitute for "T extends A & B", which I assume is because T must extend BOTH A and B, which obviously A does not. I could not find a way to specify something like "T extends A OR B". Is something like this not achievable? I am a java neophyte, so any help with this would be appreciated.
You can only specify one generic type. Use interfaces instead.
An interface specifies a certain set of methods, each member of it has to have. A class can implement multiple interfaces.
In your example, I would define an interface with the method f():
public interface MyInterface {
void f();
}
Let A and B implement the interface:
public class A implements MyInterface
{
#Override
public void f() {
// ...
}
}
public class B implements MyInterface
{
#Override
public void f() {
// ...
}
}
Then you can just specify the interface as type of the argument for your method:
public static void g(MyInterface obj)
{
obj.f();
}
For more detail on interfaces, check the Java documentation: What Is an Interface?
Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.
I wonder if it's possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.
interface A {
default void foo() {
System.out.println("A.foo");
}
}
class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
// how to invoke A.foo() here?
}
}
Considering the code above, how would you call A.foo() from a method of class B?
As per this article you access default method in interface A using
A.super.foo();
This could be used as follows (assuming interfaces A and C both have default methods foo())
public class ChildClass implements A, C {
#Override
public void foo() {
//you could completely override the default implementations
doSomethingElse();
//or manage conflicts between the same method foo() in both A and C
A.super.foo();
}
public void bah() {
A.super.foo(); //original foo() from A accessed
C.super.foo(); //original foo() from C accessed
}
}
A and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.
Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.
This answer is written mainly for users who are coming from question 45047550 which is closed.
Java 8 interfaces introduce some aspects of multiple inheritance. Default methods have an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.
class ParentClass {
public void hello() {
System.out.println("Hello ParentClass!");
}
}
interface InterfaceFoo {
public default void hello() {
System.out.println("Hello InterfaceFoo!");
}
}
interface InterfaceBar {
public default void hello() {
System.out.println("Hello InterfaceBar!");
}
}
public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
public static void main(String[] args) {
new Example().hello();
}
}
Output:
Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!
The code below should work.
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
void aFoo() {
A.super.foo();
}
public static void main(String[] args) {
B b = new B();
b.foo();
b.aFoo();
}
}
interface A {
default void foo() {
System.out.println("A.foo");
}
}
Output:
B.foo
A.foo
You don't need to override the default method of an interface. Just call it like the following:
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
A.super.foo();
}
public static void main(String[] args) {
B b=new B();
b.afoo();
}
}
Output:
A.foo
It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)
Consider the following example:
interface I{
default void print(){
System.out.println("Interface");
}
}
abstract class Abs{
public void print(){
System.out.println("Abstract");
}
}
public class Test extends Abs implements I{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}
Let's say I have three classes A, B and C.
B extends A
C extends B
All have a public void foo() method defined.
Now from C's foo() method I want to invoke A's foo() method (NOT its parent B's method but the super super class A's method).
I tried super.super.foo();, but it's invalid syntax.
How can I achieve this?
You can't even use reflection. Something like
Class superSuperClass = this.getClass().getSuperclass().getSuperclass();
superSuperClass.getMethod("foo").invoke(this);
would lead to an InvocationTargetException, because even if you call the foo-Method on the superSuperClass, it will still use C.foo() when you specify "this" in invoke. This is a consequence from the fact that all Java methods are virtual methods.
It seems you need help from the B class (e.g. by defining a superFoo(){ super.foo(); } method).
That said, it looks like a design problem if you try something like this, so it would be helpful to give us some background: Why you need to do this?
You can't - because it would break encapsulation.
You're able to call your superclass's method because it's assumed that you know what breaks encapsulation in your own class, and avoid that... but you don't know what rules your superclass is enforcing - so you can't just bypass an implementation there.
You can't do it in a simple manner.
This is what I think you can do:
Have a bool in your class B. Now you must call B's foo from C like [super foo] but before doing this set the bool to true. Now in B's foo check if the bool is true then do not execute any steps in that and just call A's foo.
Hope this helps.
To quote a previous answer "You can't - because it would break encapsulation." to which I would like to add that:
However there is a corner case where you can,namely if the method is static (public or protected). You can not overwrite the static method.
Having a public static method is trivial to prove that you can indeed do this.
For protected however, you need from inside one of your methods to perform a cast to any superclass in the inheritance path and that superclass method would be called.
This is the corner case I am exploring in my answer:
public class A {
static protected callMe(){
System.out.println("A");
}
}
public class B extends A {
static protected callMe(){
System.out.println("B");
}
}
public class C extends B {
static protected callMe(){
System.out.println("C");
C.callMe();
}
public void accessMyParents(){
A a = (A) this;
a.callMe(); //calling beyond super class
}
}
The answer remains still No, but just wanted to show a case where you can, although it probably wouldn't make any sense and is just an exercise.
Yes you can do it. This is a hack. Try not to design your program like this.
class A
{
public void method()
{ /* Code specific to A */ }
}
class B extends A
{
#Override
public void method()
{
//compares if the calling object is of type C, if yes push the call to the A's method.
if(this.getClass().getName().compareTo("C")==0)
{
super.method();
}
else{ /*Code specific to B*/ }
}
}
class C extends B
{
#Override
public void method()
{
/* I want to use the code specific to A without using B */
super.method();
}
}
There is a workaround that solved my similar problem:
Using the class A, B, and C scenario, there is a method that will not break encapsulation nor does it require to declare class C inside of class B. The workaround is to move class B's methods into a separate but protected method.
Then, if those class B's methods are not required simply override that method but don't use 'super' within that method. Overriding and doing nothing effectively neutralises that class B method.
public class A {
protected void callMe() {
System.out.println("callMe for A");
}
}
public class B extends A {
protected void callMe() {
super.callMe();
methodsForB(); // Class B methods moved out and into it's own method
}
protected void methodsForB() {
System.out.println("methods for B");
}
}
public class C extends B {
public static void main(String[] args) {
new C().callMe();
}
protected void callMe() {
super.callMe();
System.out.println("callMe for C");
}
protected void methodsForB() {
// Do nothing thereby neutralising class B methods
}
}
The result will be:
callMe for A
callMe for C
It's not possible, we're limited to call the superclass implementations only.
I smell something fishy here.
Are you sure you are not just pushing the envelope too far "just because you should be able to do it"? Are you sure this is the best design pattern you can get? Have you tried refactoring it?
I had a problem where a superclass would call an top class method that was overridden.
This was my workaround...
//THIS WOULD FAIL CALLING SUPERCLASS METHODS AS a1() would invoke top class METHOD
class foo1{
public void a1(){
a2();
}
public void a2(){}
}
class foo2 extends foo1{
{
public void a1(){
//some other stuff
super.a1();
}
public void a2(){
//some other stuff
super.a2();
}
//THIS ENSURES THE RIGHT SUPERCLASS METHODS ARE CALLED
//the public methods only call private methods so all public methods can be overridden without effecting the superclass's functionality.
class foo1{
public void a1(){
a3();}
public void a2(){
a3();}
private void a3(){
//super class routine
}
class foo2 extends foo1{
{
public void a1(){
//some other stuff
super.a1();
}
public void a2(){
//some other stuff
super.a2();
}
I hope this helps.
:)
Before using reflection API think about the cost of it.
It is simply easy to do. For instance:
C subclass of B and B subclass of A. Both of three have method methodName() for example.
public abstract class A {
public void methodName() {
System.out.println("Class A");
}
}
public class B extends A {
public void methodName() {
super.methodName();
System.out.println("Class B");
}
// Will call the super methodName
public void hackSuper() {
super.methodName();
}
}
public class C extends B {
public static void main(String[] args) {
A a = new C();
a.methodName();
}
#Override
public void methodName() {
/*super.methodName();*/
hackSuper();
System.out.println("Class C");
}
}
Run class C Output will be:
Class A
Class C
Instead of output:
Class A
Class B
Class C
In my simple case I had to inherit B and C from abstract class, that incapsulates equal methods of B and C. So that
A
|
Abstr
/ \
B C
While it doesn't solve the problem, it can be used in simple cases, when C is similar to B. For instance, when C is initialized, but doesn't want to use initializers of B. Then it simply calls Abstr methods.
This is a common part of B and C:
public abstract class Abstr extends AppCompatActivity {
public void showProgress() {
}
public void hideProgress() {
}
}
This is B, that has it's own method onCreate(), which exists in AppCompatActivity:
public class B extends Abstr {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Call from AppCompatActivity.
setContentView(R.layout.activity_B); // B shows "activity_B" resource.
showProgress();
}
}
C shows its own layout:
public class C extends Abstr {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Call from AppCompatActivity.
setContentView(R.layout.activity_C); // C shows "activity_C" resource.
showProgress();
}
}
This is not something that you should do normally but, in special cases where you have to workaround some bug from a third party library (if it allow to do so), you can achieve calling a super super class method that has already been overwritten using the delegation pattern and an inner class that extends the super super class to use as a bridge:
class A() {
public void foo() {
System.out.println("calling A");
}
}
class B extends A() {
#Overwrite
public void foo() {
System.out.println("calling B");
}
}
class C extends B() {
private final a;
public C() {
this.a = new AExtension();
}
#Overwrite
public void foo() {
a.foo();
}
private class AExtension extends A {
}
}
This way you will be able to not only call the super super method but also combine calls to other super super class methods with calls to methods of the super class or the class itself by using `C.super` or `C.this`.