How can an anonymous class implement two (or more) interfaces? Alternatively, how can it both extend a class and implement an interface?
For example, I want to create an object of anonymous class that extends two interfaces:
// Java 10 "var" is used since I don't know how to specify its type
var lazilyInitializedFileNameSupplier = (new Supplier<String> implements AutoCloseable)() {
private String generatedFileName;
#Override
public String get() { // Generate file only once
if (generatedFileName == null) {
generatedFileName = generateFile();
}
return generatedFileName;
}
#Override
public void close() throws Exception { // Clean up
if (generatedFileName != null) {
// Delete the file if it was generated
generatedFileName = null;
}
}
};
Then I can use it in a try-with-resources block as AutoCloseable as lazily-initialized utility class:
try (lazilyInitializedFileNameSupplier) {
// Some complex logic that might or might not
// invoke the code that creates the file
if (checkIfNeedToProcessFile()) {
doSomething(lazilyInitializedFileNameSupplier.get());
}
if (checkIfStillNeedFile()) {
doSomethingElse(lazilyInitializedFileNameSupplier.get());
}
}
// By now we are sure that even if the file was generated, it doesn't exist anymore
I don't want to create an inner class because I'm absolutely sure that this class won't be used anywhere except the method I need to use it in (and I also might want to use local variables declared in that method that might be of var type).
Anonymous classes must extend or implement something, like any other Java class, even if it's just java.lang.Object.
For example:
Runnable r = new Runnable() {
public void run() { ... }
};
Here, r is an object of an anonymous class which implements Runnable.
An anonymous class can extend another class using the same syntax:
SomeClass x = new SomeClass() {
...
};
What you can't do is implement more than one interface. You need a named class to do that. Neither an anonymous inner class, nor a named class, however, can extend more than one class.
An anonymous class usually implements an interface:
new Runnable() { // implements Runnable!
public void run() {}
}
JFrame.addWindowListener( new WindowAdapter() { // extends class
} );
If you mean whether you can implement 2 or more interfaces, than I think that's not possible. You can then make a private interface which combines the two. Though I cannot easily imagine why you would want an anonymous class to have that:
public class MyClass {
private interface MyInterface extends Runnable, WindowListener {
}
Runnable r = new MyInterface() {
// your anonymous class which implements 2 interaces
}
}
I guess nobody understood the question. I guess what this guy wanted was something like this:
return new (class implements MyInterface {
#Override
public void myInterfaceMethod() { /*do something*/ }
});
because this would allow things like multiple interface implementations:
return new (class implements MyInterface, AnotherInterface {
#Override
public void myInterfaceMethod() { /*do something*/ }
#Override
public void anotherInterfaceMethod() { /*do something*/ }
});
this would be really nice indeed; but that's not allowed in Java.
What you can do is use local classes inside method blocks:
public AnotherInterface createAnotherInterface() {
class LocalClass implements MyInterface, AnotherInterface {
#Override
public void myInterfaceMethod() { /*do something*/ }
#Override
public void anotherInterfaceMethod() { /*do something*/ }
}
return new LocalClass();
}
Anonymous classes always extend superclass or implements interfaces. for example:
button.addActionListener(new ActionListener(){ // ActionListener is an interface
public void actionPerformed(ActionEvent e){
}
});
Moreover, although anonymous class cannot implement multiple interfaces, you can create an interface that extends other interface and let your anonymous class to implement it.
// The interface
interface Blah {
void something();
}
...
// Something that expects an object implementing that interface
void chewOnIt(Blah b) {
b.something();
}
...
// Let's provide an object of an anonymous class
chewOnIt(
new Blah() {
#Override
void something() { System.out.println("Anonymous something!"); }
}
);
An anonymous class is extending or implementing while creating its object
For example :
Interface in = new InterFace()
{
..............
}
Here anonymous class is implementing Interface.
Class cl = new Class(){
.................
}
here anonymous Class is extending a abstract Class.
Related
I have a code like this :
interface Contract {
createSomething(); //not common
updateSomething(); //not common
getSomething(); //method who is supposed to be common between all strategies
}
interface Strategy {
createSomething();
updateSomething();
getSomething();
}
Abstract class AbstractStrategy implements Strategy {
#Override
getSomething() {
// the common code
}
}
class strategyA extends AbstractStrategy {
#Override
createSomething() {...}
#Override
updateSomething() {...}
}
class ContractImpl implements Contract {
#Override
createSomething() {
//get the good strategy
//call the strategy.createSomething();
}
#Override
updateSomething() {
//get the good strategy
//call the strategy.updateSomething();
}
#Override
getSomething() {
**Here is the question**
}
}
Question:
How could I rewrite this code so I could call the getSomething() method without having to instanciate a random subclass just to call it with the super keyword ?
You can't. Rather, you could extract the code into a static method and subsequently call it from getSomething(). This would allow you to call it statically when you need to, and from an instance when needed as well.
In other words, your AbstractStrategy class should look like:
Abstract class AbstractStrategy implements Strategy {
public static void sharedCode(parameters needed) {
// the common code
}
#Override
(signature) getSomething() {
sharedCode(this.parametersNeeded);
}
}
You basically can't. An abstract class can't be instantiated, so you can't call an instance method without having an object of a concrete implementation (in your case any concrete subclass of AbstractStrategy).
One option that you have is to create an anonymous class so that you can call the method without instantiating any of your subclasses of AbstractStrategy:
AbstractStrategy strategy = new AbstractStrategy() {
#Override
createSomething() {...}
#Override
updateSomething() {...}
}
strategy.getSomething();
But this feels hacky.
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 :
When to implement interface in class and when to instantiate an anonymous implementation of an interface. Below are two interfaces.
public interface InterfaceOne {
void one();
}
public interface InterfaceTwo {
void two();
}
Approach 1: Implement interface in class
public class A implements InterfaceOne, InterfaceTwo {
private void doSomething() {
Hello hello = new Hello();
hello.hi(this);
hello.bye(this);
}
#Override
public void one() {
//One
}
#Override
public void two() {
//Two
}
}
Approach 2: Instantiate an anonymous implementation of an interface
public class B {
private void doSomething() {
Hello hello = new Hello();
hello.hi(interfaceOne);
hello.bye(interfaceTwo);
}
private InterfaceOne interfaceOne = new InterfaceOne() {
#Override
public void one() {
//One
}
};
private InterfaceTwo interfaceTwo = new InterfaceTwo() {
#Override
public void two() {
//Two
}
};
}
What are the scenarios in which we need to use Approach 1 and Approach 2?
With Java8 things slightly changed because with functional interfaces you are allowed to define lambdas with are internally managed as anonymous classes so the awkward syntax is somewhat saved.
In any case an anonymous class makes sense only when you are dealing with something which doesn't need to be named (think about an ActionListener for a button). A named class instead always makes sense, there is no explicit reason to avoid naming a class.
In Java, is it possible to prevent a class for being extended anonymously?
For example
public class A () {
public void hello() {}
}
I want to allow a named class extension:
public class B extends A {
}
but not anonymously:
A a = new A() {
public void hello() {
}
}
This is for serialization purpose.
Yes, there is a way to accomplish this, through the use of a runtime exception:
class MyData implements Serializable {
public MyData() {
if (getClass().isAnonymousClass()) {
throw new IllegalStateException("Anonymous subclasses are not serializable.");
}
}
}
Technically, anonymous classes are serializable, but it might be a good idea taking a look at this before trying to live with that.
Imagine we have a class:
class A {
public void m() {
System.out.println("A - > m()");
}
}
...and I want to override the method m on class creation without making a second subclass B to extend A.
public static void main(String[] args) {
A a = new A() {
#Override
public void m() {
System.out.println("Override - > m()");
new Thread(new Runnable() {
#Override
public void run() {
// I want to be able to call the super method.
// This is illegal!
A.super.m();
}
}).start();
}
};
a.m();
}
Currently my solution is to create a private method that calls the super.m()
A a = new A() {
private void superMethod() {
super.m();
}
#Override
public void m() {
System.out.println("Overrided - > m()");
new Thread(new Runnable() {
#Override
public void run() {
superMethod();
}
}).start();
}
};
a.m();
I want to know why I am not able to write A.super.m() and if there another way to perform this task.
I want to know why I am not able to write A.super.m()...
This is because A is in fact not a directly enclosing class. The directly enclosing class of the Runnable is new A() { ... } which is an anonymous subclass of A.
In other words, if you would have had
class A extends Base {
new Runnable() { ... }
}
then A.super would have worked, but now you have
class <Anonymous subclass of A> extends A {
new Runnable() { ... }
}
which means that something like A.super isn't possible, since there's no syntax for <Anonymous subclass of A>.super.m.
...and, is there another way to perform this task.
The way you've solved it is reasonable in my opinion. Another way would be to create a local subclass of A (just to introduce an identifier to use in ____.super.m) as follows:
public static void main(String[] args) {
class SubA extends A {
#Override
public void m() {
System.out.println("Override - > m()");
new Thread(new Runnable() {
#Override
public void run() {
SubA.super.m();
// ^^^^ we now have a name of the directly enclosing class
}
}).start();
}
}
A a = new SubA();
a.m();
}
Writing A.super.m(), suppose that A has a superclass with a m method.
But in your code, you don't specify a superclass, and by default, the only superclass you have is Object.
But Object class doesn't have a 'm' method, so you could not call it.
A good way to do something like that is to use design pattern, like decorator.
I don't think there would be a simpler way to do it other than the way you already have it.
The problem is that the anonymous class A itself (not the base class A) cannot be referenced inside the Runnable class. The anonymous class is represented as something like package.A$1 when compiled to its own class file. For example, when you call superMethod inside the run of the thread, the following bytecode is executed:
getfield mypackage/Test$1$1/this$1 Lmypackage/Test$1;
invokestatic mypackage/Test$1/access$0(Lmypackage/Test$1;)V
In order to reference its base class A, there is no reference to this inner class instance so that you call the super.m() expression.