Explicitly calling a default method in Java - java

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?
}
}

Related

C# vs JAVA instance of Interface

I am not sure how am I suppose to go about my question. It is about Android can Instantiate Interface. I am trying to do in C#. Now I am pretty sure that the rules for both Java and C# is you can't create an Instance of abstract and Interface as being said.
But I would really like to know how Android does this practice.
In Android you can do this.
public interface Checkme{
void Test();
void Test2();
}
public void myFunc(Checkme my){
//do something
}
// Now this is the actual usage.
public void Start(){
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
}
Actually once you press Enter on new Checkme() You will automatically get the Override methods of the Interface. Like auto Implement method of an Interface in C#.
I hope my question make sense.
C# doesn't support anonymously auto-implemented interfaces because it has delegates:
public void Foo(Func<string> func, Action action) {}
// call it somewhere:
instance.Foo(() => "hello world", () => Console.WriteLine("hello world"));
With delegates you can fill the gap and it can be even more powerful than implementing interfaces with anonymous classes.
Learn more about delegates.
This is an Anonymous Class:
public void Start(){
myFunc(new Checkme() {
#Override
public void Test() {
}
#Override
public void Test2() {
}
});
}
An anonymous class is an unnamed class implemented inline.
You could also have done it using a Local Class, but those are rarely seen in the wild.
public void Start(){
class LocalCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
myFunc(new LocalCheckme());
}
These both have the advantage that they can use method parameters and variables directly, as long as they are (effectively) final.
As a third option, you could do it with an Inner Class.
private class InnerCheckme implements Checkme {
#Override
public void Test() {
}
#Override
public void Test2() {
}
}
public void Start(){
myFunc(new InnerCheckme());
}
An inner class cannot access method variables (obviously because it's outside the method), but can be used by multiple methods.
Any local values from the method can however be passed into the constructor and stored as fields of the inner class, to get the same behavior. Just requires a bit more code.
If the inner class doesn't need access to fields of the outer class, it can be declared static, making it a Static Nested Class.
So, all 3 ways above a very similar. The first two are just Java shorthands for the third, i.e. syntactic sugar implemented by the compiler.
C# can do the third one, so just do it that way for C#.
Of course, if the interface only has one method, using a Java lambda or C# delegate is much easier than Anonymous / Local / Inner classes.
If I understand correcly, you're defining a class that implements an interface, and when you specify that the class implements an interface, you want it to automatically add the interface's methods and properties.
If you've declared this:
public interface ISomeInterface
{
void DoSomething();
}
And then you add a class:
public class MyClass : ISomeInterface // <-- right-click
{
}
Right-click on the interface and Visual Studio will give you an option to implement the interface, and it will add all the interface's members to the class.
you mean something like this?
pulic interface Foo{
void DoSomething();
}
public class Bar : Foo {
public void DoSomething () {
//logic here
}
}
myFunc(new Checkme(){
#Override
public void Test()
{
}
#Override
public void Test2()
{
}
});
You're passing into myFunc() something that is called an anonymous class. When it says "new Checkme() { .... }", it is defining an anonymous implementation of the Checkme interface. So, it's not an instance of the interface itself, just an instance of a type that implements it.
In C# anonymously implemented classes for Interface are not auto generated just like in java, you need to follow the below procedure to workout.
public class MyClass {
public void someMethod (string id, IMyInterface _iMyInterface) {
string someResponse = "RESPONSE FOR " + id;
_iMyInterface.InterfaceResponse (someResponse);
}
}
public interface IMyInterface {
void InterfaceResponse (object data);
void InterfaceResponse2 (object data, string x);
}
public class MyInterfaceImplementor : IMyInterface {
private readonly Action<object> actionname;
private readonly Action<object, string> actionInterfaceResponse2;
public MyInterfaceImplementor (Action<object> InterfaceResponse) {
this.actionname = InterfaceResponse;
}
public MyInterfaceImplementor(Action<object> interfaceResponseMethod, Action<object, string> interfaceResponseMethod1) {
this.actionname = interfaceResponseMethod ?? throw new ArgumentNullException(nameof(interfaceResponseMethod));
this.actionInterfaceResponse2 = interfaceResponseMethod1 ?? throw new ArgumentNullException(nameof(interfaceResponseMethod1));
}
public void InterfaceResponse (object data) {
this.actionname (data);
}
public void InterfaceResponse2(object data, string x) {
this.actionInterfaceResponse2(data, x);
}
}
Gist Source : https://gist.github.com/pishangujeniya/4398db8b9374b081b0670ce746f34cbc
Reference :

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.

Java multi-type method parameter?

I wonder if it is possible to require that a java method parameter is of any type from finite set of types. For example - I am using a library where two (or more) types have common methods, but their lowest common ancestor in the type hierarchy is Object. What I mean here:
public interface A {
void myMethod();
}
public interface B {
void myMethod();
}
...
public void useMyMethod(A a) {
// code duplication
}
public void useMyMethod(B b) {
// code duplication
}
I want to avoid the code duplication. What I think of is something like this:
public void useMyMethod(A|B obj){
obj.myMethod();
}
There is similar type of syntax in java already. For example:
try{
//fail
} catch (IllegalArgumentException | IllegalStateException e){
// use e safely here
}
Obviously this is not possible. How can I achieve well designed code using such type of uneditable type hierarchy ?
What about passing the function as a parameter to your useMyMethod function?
If you are using Java < 8:
public interface A {
void myMethod();
}
public interface B {
void myMethod();
}
public void useMyMethod(Callable<Void> myMethod) {
try {
myMethod.call();
} catch(Exception e) {
// handle exception of callable interface
}
}
//Use
public void test() {
interfaceA a = new ClassImplementingA();
useMyMethod(new Callable<Void>() {
public call() {
a.myMethod();
return null;
}
});
interfaceB b = new ClassImplementingB();
useMyMethod(new Callable<Void>() {
public call() {
b.myMethod();
return null;
}
});
}
For Java >= 8, you could use Lambda Expressions:
public interface IMyMethod {
void myMethod();
}
public void useMyMethod(IMyMethod theMethod) {
theMethod.myMethod();
}
//Use
public void test() {
interfaceA a = new ClassImplementingA();
useMyMethod(() -> a.myMethod());
interfaceB b = new ClassImplementingB();
useMyMethod(() -> b.myMethod());
}
Try using Adapter design pattern.
Or, if it's possible, add some base interface:
public interface Base {
void myMethod();
}
public interface A extends Base {}
public interface B extends Base {}
...
public void useMyMethod(Base b) {
b.myMethod()
}
Also, you can use something similar to this
You could write an interface MyInterface with a single method myMethod. Then, for each type you want to consider as part of the finite set, write a wrapper class, like this:
class Wrapper1 implements MyInterface {
private final Type1 type1;
Wrapper1(Type1 type1) {
this.type1 = type1;
}
#Override
public void myMethod() {
type1.method1();
}
}
Then you just need to use a MyInterface rather than one of the finite set of types, and the appropriate method from the appropriate type will always get called.
Note that to actually use these wrapper classes to call the method myMethod you would have to write
myMethod(new Wrapper1(type1));
This is going to get a bit ugly as you are going to have to remember the name of the wrapper class for each type in the set. For this reason, you may prefer to replace MyInterfacewith an abstract class with several static factories that produce the wrapper types. Like this:
abstract class MyWrapper {
static MyWrapper of(Type1 type1) {
return new Wrapper1(type1);
}
static MyWrapper of(Type2 type2) {
return new Wrapper2(type2);
}
abstract void myMethod();
}
then you can call the method using the code
myMethod(MyWrapper.of(type1));
The advantage of this approach is that the code is the same no matter which type you use. If you use this approach you have to replace implements MyInterface in the Wrapper1 declaration with extends MyWrapper.
Well, the correct way to model your requirement would be to have myMethod() declared in a supertype interface C which both A and B extend; your method then accepts type C as its parameter. The fact that you have trouble doing this in the situation you describe indicates you are not modelling the class hierarchy in a way that actually reflects how they behave.
Of course, if you can't change the interface structure then you could always do it with reflections.
public static void useMyMethod(Object classAorB) throws Exception {
classAorB.getClass().getMethod("myMethod").invoke(classAorB);
}
This might not constitute a best practice, but could you make a new class (call it C), that contains the parts from A and B that are duplicated, and the make a new method that takes C, have your methods that take A and B make a C instance and call the new method?
So that you have
class C {
// Stuff from both A and B
}
public void useMyMethod(A a) {
// Make a C
useMyMethod(c);
}
public void useMyMethod(B b) {
// Make a C
useMyMethod(c);
}
public void useMyMethod(C c) {
// previously duplicated code
}
That would also let you keep any non duplicated code in the methods for A and B (if there is any).
This looks to me much like the template pattern:
public interface A {
void myMethod();
}
public interface B {
void myMethod();
}
public class C {
private abstract class AorBCaller {
abstract void myMethod();
}
public void useMyMethod(A a) {
commonAndUseMyMethod(new AorBCaller() {
#Override
void myMethod() {
a.myMethod();
}
});
}
public void useMyMethod(B b) {
commonAndUseMyMethod(new AorBCaller() {
#Override
void myMethod() {
b.myMethod();
}
});
}
private void commonAndUseMyMethod(AorBCaller aOrB) {
// ... Loads of stuff.
aOrB.myMethod();
// ... Loads more stuff
}
}
In Java 8 it is much more succinct:
public class C {
// Expose an "A" form of the method.
public void useMyMethod(A a) {
commonAndUseMyMethod(() -> a.myMethod());
}
// And a "B" form.
public void useMyMethod(B b) {
commonAndUseMyMethod(() -> b.myMethod());
}
private void commonAndUseMyMethod(Runnable aOrB) {
// ... Loads of stuff -- no longer duplicated.
aOrB.run();
// ... Loads more stuff
}
}
A dynamic proxy can be used to create a bridge between a common interface you define and the objects implementing the other interfaces that conform to the new interface. Then, you can have your useMyMethods convert the parameter to the new interface (as a dynamic proxy) and have your common code written in terms only of the new interface.
This would be the new interface:
interface Common {
void myMethod();
}
Then, with this invocation handler:
class ForwardInvocationHandler implements InvocationHandler {
private final Object wrapped;
public ForwardInvocationHandler(Object wrapped) {
this.wrapped = wrapped;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method match = wrapped.getClass().getMethod(method.getName(), method.getParameterTypes());
return match.invoke(wrapped, args);
}
}
You can have your methods like this:
public void useMyMethod(A a) {
useMyMethod(toCommon(a));
}
public void useMyMethod(B b) {
useMyMethod(toCommon(b));
}
public void useMyMethod(Common common) {
// ...
}
private Common toCommon(Object o) {
return (Common)Proxy.newProxyInstance(
Common.class.getClassLoader(),
new Class[] { Common.class },
new ForwardInvocationHandler(o));
}
Note that to simplify matters you could even elect one of your existing interfaces (A or B) to be used as the common interface.
(Look at another example here, and also at other ideas around this subject)
The correct way is to use Java Generics.
See http://docs.oracle.com/javase/tutorial/java/generics/bounded.html

Any way to specify a java generic type variable that extends any one of multiple classes?

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?

How interfaces in Java get method of Object class?

I know that in case of dynamic binding only those method which are present in current class can be called. If child override parent method then the child method is executed otherwise parents method will be executed...
But in case of interfaces what is happening I don't know... Here's an example of what I mean:
interface TestInterface {
public void show();
}
class Test implements TestInterface {
public void show() {
System.out.println("Hello in show");
}
public String toString() {
System.out.println("Hello in To String");
return "";
}
public static void main(String[] args) {
TestInterface obj = new Test();
obj.show();
obj.toString(); // why it run vilate dynamic binding rule..
}
}
This is because interfaces implicitly include all public methods declared in Object.
This is specified in the JLS, section 9.2 Interface Members.
9.2 Interface Members
[...]
If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.
[...]
In case of interfaces in java :-"All interfaces get all public and abstract method of Object class"
Because in case of interfaces its implicitly include all public methods declared in Object
Your code does not compile. I changed your code to:
interface TestInterface {
public void show();
}
class Test implements TestInterface {
#Override
public void show() {
System.out.println("Hello in show");
}
#Override
public String toString() {
return "Hello in To String";
}
public static void main(String[] args) {
TestInterface obj = new Test();
obj.show();
System.out.println(obj.toString());
}
}
The result is:
Hello in show
Hello in To String

Categories

Resources