I was fiddling with Java 8 and came down to the following code which in my opinion could work:
class UnrelatedClass implements UnrelatedInterfaceDefault {
#Override
public void unrelate2() {
System.out.println("Unrelated");
}
}
interface UnrelatedInterfaceDefault extends UnrelatedInterfaceOne, UnrelatedInterfaceTwo {
default public void unrelate() {
UnrelatedInterfaceOne.super.unrelate2();
UnrelatedInterfaceTwo.super.unrelate2();
}
}
interface UnrelatedInterfaceOne {
public void unrelate2();
}
interface UnrelatedInterfaceTwo {
public void unrelate2();
}
On UnrelatedInterfaceOne.super.unrelate(), I get the error:
abstract method unrelate2() in UnrelatedInterfaceOne cannot be accessed directly.
But consider if I would create a class that implements UnrelatedInterfaceDefault, then I actually do have implementations for UnrelatedInterfaceOne and UnrelatedInterfaceTwo, so it could work?
Why is there this specific compiler error in this case?
This is failing because the methods in your interfaces are abstract. If you make it default, then I guess it would compile. I can't test it right now though.
From JLS ยง15.12.3 - Compile-Time Step 3: Is the Chosen Method Appropriate?:
If the form is TypeName . super . [TypeArguments] Identifier, then:
It is a compile-time error if the compile-time declaration is abstract.
Also note that, invocation of a method using super never goes through dynamic dispatch. It wouldn't invoke the overridden method, but only the method defined in the super class, or in this case TypeName.
I tried to make your example work.
As noted #Rohit Jain I needed to change abstract-> default. Then I've got a diamond problem right in interface UnrelatedInterfaceDefault. I resolved it with empty method.
That's all, it works. As for me, results are logical) see below
public class Main {
public static void main(String[] args) throws IOException, Exception {
UnrelatedClass uc = new UnrelatedClass();
uc.unrelate2();
uc.unrelate();
}
}
class UnrelatedClass implements UnrelatedInterfaceDefault {
#Override
public void unrelate2() {
System.out.println("Unrelated");
}
}
interface UnrelatedInterfaceDefault extends UnrelatedInterfaceOne, UnrelatedInterfaceTwo {
#Override
public default void unrelate2() {
}
default public void unrelate() {
UnrelatedInterfaceOne.super.unrelate2();
UnrelatedInterfaceTwo.super.unrelate2();
unrelate2();
}
}
interface UnrelatedInterfaceOne {
public default void unrelate2() {
System.out.println("relatedOne");
}
}
interface UnrelatedInterfaceTwo {
public default void unrelate2() {
System.out.println("relatedTwo");
}
}
Output:
Unrelated
relatedOne
relatedTwo
Unrelated
Related
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 :
Here's the situation: I have a class and I create instances of. I'd like it to inherit the majority of the methods/variables in the class, but I want a few methods to be required to be overridden, similar to how an abstract class works.
Here is my code so far.
public class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public void methodThree() {
//Override Me
}
}
I can't [make the class abstract] because I need to create instances
Making the class abstract does prevent instantiation, but since you want to prevent instantiation unless a method is overridden, this is the right thing to do.
You can make overrides anonymously, so syntactically this would be similar to instantiating the base class:
public abstract class Example {
public void methodOne() {
//Inherited
}
public void methodTwo() {
//Interited
//Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
...
static void main(String[] args) {
Example e = new Example() {
#Override
public void methodThree() {
... // Do something
}
};
}
First of all, requiring people to write code in a particular way can be counter productive. Someone may have a legitimate use-case (that you had not considered !!) for dong it differently, and your restriction may force them to solve the problem in a way that makes things significantly worse than if your restriction wasn't there. Bear this in mind ...
But here's a solution:
public abstract class ExampleBase {
public void methodOne() {
// Inherited
}
public void methodTwo() {
// Interited
// Maybe calls methodThree() as a part of its function
}
public abstract void methodThree();
}
public final class Example {
#Override
public void methodThree() {
// Do stuff.
}
}
We have solved the problem by moving all of the members that you want to inherit to an abstract superclass. Any methods that you want to force people to override are declared as abstract. By declaring your concrete Example class as final, we prevent them from circumventing your requirement and subclassing Example without overriding methodThree.
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?
}
}
I have declared the following interface in Java:
public interface ITest {
void doStuff();
}
which is implemented by another few classes who overwrite the doStuff() method. I then use this interface as the type in a function:
public gonnaDoSomeStuff(ITest fun) {
fun.doStuff();
}
However, Java (and Eclipse) state that the method is undefined for type ITest. What am I doing wrong?
It turns out that the class containing my gonnaDoSomeStuff method was appended with a generic, which was being referenced instead of the actual interface.
Wrong
public class Dog<ITest> {
public gonnaDoSomeStuff(ITest fun) {
// ...
}
}
Right
public class Dog {
public gonnaDoSomeStuff(ITest fun) {
// ...
}
}
You can not access default declared method in a public class because its scope is limited. You should declared it as public for call in public class.
I have a basic question about generics in Java.
I have a class X which is instantiated by another class T. In every class T which will be used has a method called as methodOfT(). However, Java gives me compiler time error since it does not know obj and methodOfT().
public class X<T>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
In order to avoid this problem, what I did is I defined another class XSuper. And every class now which wants to instantiate X will extend this XSuper class. This removes the compile time error and allows me to achieve what I want.
public abstract class XSuper
{
public abstract void methodOfT();
}
public class UserOfX extends XSuper
{
X<UserOfX> objX = new X<UserOfX>();
public void methodOfT()
{
}
}
However, I want to know the cleaner way of doing this thing. Since I want to derive class UserOfX from another Class. Another Problem is that I want to define methodOfT() method as -
public methodOfT(T objOfT)
{
}
In this case, the above solution fails. Could someone help.
public class X<T>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
The compiler doesn't know what T is so it is evaluated as Object. Object does not have a methodOfT method, so compilation fails. Here's how to solve that:
public interface SomeInterface{
void methodOfT();
}
public class X<T extends SomeInterface>
{
T obj;
public void methodOfX()
{
obj.methodOfT();
}
}
In this case, the compiler knows that the supplied T will implement the interface SomeInterface and hence have the method methodOfT. (You can also use classes instead of interfaces, but that's less elegant)
Given your additional requirements, we're going t have to change this code some more:
public interface SomeInterface<X>{
void methodOfT(X object);
}
public class X<T1, T2 extends SomeInterface<T1>>
{
T1 obj1;
T2 obj2;
public void methodOfX()
{
obj2.methodOfT(obj1);
}
}