I want to be able to subclass some values in an enum, in order that I don't have to repeat code too much. Is there some way I can do this? Here's an example of what I want to achieve, which Eclipse quickly tells me is an abomination:
public enum Foo {
BAR {
#Override
public void taskA() {
System.out.println("A");
}
#Override
public void taskB() {}
},
BAZ extends BAR {
#Override
public void taskB() {
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
}
BAR would have only the implementation of taskA and an empty taskB, and BAZ would have both methods - BAR's implementation of taskA, and its own implementation of taskB.
I'm not changing the values of the enum after it's declared, so why doesn't this work? I could call BAR's taskA method within BAZ, so why can't I do this?
I want to be able to subclass some values in an enum, in order that I
don't have to repeat code too much.
The usual way to share code among constant-specific methods is to declare a private static method (either in the enum itself or in a utility helper class) which contains the common code that you wish to access from your constant-specific methods.
For example ...
public enum Foo {
BAR {
#Override
public void taskA() {
commonToTaskAandB();
System.out.println("B");
}
#Override
public void taskB() {}
},
BAZ {
#Override
public void taskB() {
commonToTaskAandB();
System.out.println("B");
}
};
public abstract void taskA();
public abstract void taskB();
private static void commonToTaskAandB() {
// shared code here
:
:
}
}
Note that the code "BAZ extends Bar" is illegal because BAZ is not a type. BAZ is an instance of your Enum<Foo> type. An instance cannot extend another type. It is incorrect to apply object-oriented principles like inheritance to enum constants because, in Java, enum constants are instances of a class and not classes themselves.
Enum-Constants are objects (instances), not classes. You can only subclass classes.
However even that will not work: you can only extend enums with anynomous inner classes.
You will have to find another solution for your use case. You could:
use a static method for the shared code
call BAR.taskA() in BAZ
make taskA not abstract and put your code there
use normal constants, instead of enums
But my favorit is:
inject behaviour instead of overriding!
Example code:
class Behavior {
public static Runnable A = new Runnable() {
public void run() {
System.out.println("A");
}
}
public static Runnable B = new Runnable() {
public void run() {
System.out.println("B");
}
}
public static Runnable DO_NOTHING = new Runnable() {
public void run() {
}
}
}
public enum Foo {
BAR(Behavior.A, Behavior.DO_NOTHING),
BAZ(Behavior.A, Behavior.B);
private final Runnable mechanismA;
private final Runnable mechanismB;
private Foo(Runnable mechanismA, Runnable mechanismB) {
this.mechanismA = mechanismA;
this.mechanismB = mechanismB;
}
public void taskA() {
mechanismA.run;
}
public void taskB() {
mechanismB.run;
}
}
Pros of this solution:
The code explicitly defines the behavior of each enum constant - no implicit calculations => easier to read
You can use inheritance, etc in the Behavior-class
You can easily switch behaviorA and behaviorB - or reuse that code anywhere else
If you have Java8 available you can even shorten the code to this:
public static Runnable A = () -> {
System.out.println("A");
};
Related
In java, I'd like to do something like this
public class Tata{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Titi{
public static void f(){
//something
}
public static void g(){
//something
}
}
public class Toto{
private Class c = Tata.class; //or Titi.class
public static void main(String[] args) {
c.f();
c.g();
}
}
To be precise, I'd like to be able to freely switch between classes Tata and Titi, to use their respective methods f or g.
This doesn't work as intended, as I get the cannot resolve method 'f()' error. Simply replacing c.f(); and c.g(); with Tata.f(); and Tata.g(); works fine, but defeats the purpose of using a parameter. How to solve this?
Will turn the comment into answer after all.. The correct (Java) way to deal with what you want is the use of interface. So in your demo code the implementation would be the following:
public interface TheFGFunctions {
void f();
void g();
}
public class Tata implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Titi implements TheFGFunctions {
#Override
public void f() {
//something
}
#Override
public void g() {
//something
}
}
public class Toto {
private TheFGFunctions c;
public Toto(TheFGFunctions c) {
this.c = c;
}
public void notStaticFunction() {
c.f();
c.g();
}
}
This way is totally typesafe with zero exceptions to deal with!
You cannot access a static method polymorphically. The Java language doesn't support it.
The reason your current approach fails is that c is an instance of the class Class, and the class Class doesn't define methods f() or g().
(The methods that it does define are listed in the javadoc for Class. Note that Class is final so you can't create a custom subclass with extra methods.)
The simple alternative is to use reflection; e.g.
Class c =
Method f = c.getMethod("f");
f.invoke(null); // because it is static
But note:
This is not statically type-safe. The compiler cannot tell when you make the mistake of trying to use a static f() on a class that doesn't have such a method.
There are a few exceptions that you need to deal with; e.g. missing methods, incorrect signatures, methods that are not static, methods that don't have the correct access.
Other answers have proposed creating an interface and wrapper classes to make certain static methods dispatchable. It will work and it will be compile-time type-safe (!) but there is a lot of boiler plate code to write.
#Michael Michailidis commented:
Thus interfaces!
Yea ... kind of. You can only dispatch polymorphically on instance methods declared on an interface. That implies that you must have an instance of Tata or Titi, and call the methods on it. My reading of the Question is that the author wants to avoid that.
(IMO, the avoidance is the real problem. You are better of not trying to avoid instance methods.)
FWIW, you can declare static methods in an interface (since Java 8), but they would behave the same as if you declared them in a class. You wouldn't be able to dispatch ...
You could use reflections:
private Class c = Tata.class;
public Toto() throws Exception {
c.getMethod("f").invoke(null);
c.getMethod("g").invoke(null);
}
Here my Tata class
public class Tata {
public static void f() {
System.out.println("ffff");
}
public static void g() {
System.out.println("gggg");
}
}
Output on new Toto() call:
ffff
gggg
Update (call with parameters):
public Toto() throws Exception {
c.getMethod("f", String.class).invoke(null, "paramValue1");
c.getMethod("g", String.class).invoke(null, "paramValue2");
}
public class Tata {
public static void f(String param1) {
System.out.println("ffff " + param1);
}
public static void g(String param2) {
System.out.println("gggg " + param2);
}
}
Output:
ffff paramValue1
gggg paramValue2
Write a wrapper interface
interface CWrapper {
void f();
void g();
}
and wrapper class factory method for each Class containing the methods
class CWrappers {
CWrapper forTiti(Class<Titi> titiClass) {
return new CWrapper() {
void f() { Titi.f(); }
void g() { Titi.g(); }
}
}
// another factory method for Tata
}
Then you can use that:
public class Toto {
private CWrapper c = CWrappers.forTata(Tata.class); //or forTiti(Titi.class)
public static void main(String[] args) {
c.f();
c.g();
}
}
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 :
I'm very new to the java 8 features and try to understand default methods. Is there an easier way to invoke a default method by another default method of the same interface than using an anonymous class?
For example:
public class Frame{
public static void main(String... args){
Frame.C c= new Frame.C();
c.doSomething();
}
public interface A{
public default void doSomething(){
System.out.println("A");
}
}
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
//is there an easier way to invoke that method??
new B(){}.other();
}
default public void other(){
//doSomething();
System.out.println("other");
}
}
public static class C implements B{
#Override
public void other(){
Lambda.B.super.other();
System.out.println("C");
}
}
}
Your intention is not entirely clear, but the construct new B(){}.other(); implies two things:
You don’t want to invoke an overriding method implementation
The instance on which you invoke other() is obviously irrelevant when invoking it on an entirely different instance (new B(){}) is a viable solution
These two things together imply that you should use a static method instead:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
otherInB();
}
default public void other(){
otherInB();
}
static void otherInB() {
//doSomething();
System.out.println("other");
}
}
Since your original method names did not carry useful information, it’s not possible to suggest a useful name for that static method either.
Note that Java 9 is going to introduce support for private methods in interfaces which allows hiding otherInB() to other classes and even making it non-static in case it has to use other methods on the same instance.
If the visibility of the method in Java 8 is an issue, consider that the actual place of a non-polymorphic method is irrelevant, so you can always use a companion class:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other();
}
default public void other(){
BHelper.other();
}
}
…
/* not public */ class BHelper {
/* not public */ static void other() {
//doSomething();
System.out.println("other");
}
}
This even works if the implementation needs the actual B instance as you may pass it as a parameter.
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other(this);
}
default public void other(){
BHelper.other(this);
}
}
…
/* not public */ class BHelper {
/* not public */ static void other(B instance) {
//doSomething();
System.out.println("other");
}
}
I'm looking for a way to be able to define a method for each enum instance. We all know about the code construction at the bottom of this page.
The difference I'm looking for is to be able to define one or more abstract methods for each enum in a separate file that is verified compile-time. Meaning if someone were to add another enum instance I would get a compile-time error and not a run-time error which is what I get with the construction at the bottom of this page.
The reason for the request is that in some code I'm looking at there are many methods that should be defined per enum but are really unrelated to the enum definition so I'd like to place them in separate files but not lose the benefits of the "standard" way of solving this.
public enum MyEnum {
X {
public void calc(Outer o) {
// do something
}
},
Y {
public void calc(Outer o) {
// do something
}
};
// abstract method
abstract void calc(Outer o);
}
Consider the folowing code:
interface Delegate{
void calc();
}
enum TestEnum {
EnumValue1(new Delegate() {
#Override
public void calc() {
}
}),
EnumValue2(new Delegate() {
#Override
public void calc() {
}
});
private Delegate delegate;
TestEnum(Delegate d){
this.delegate = d;
}
public Delegate getDelegate() {
return delegate;
}
}
public class Test {
public static void main() {
TestEnum.EnumValue1.getDelegate().calc();
TestEnum.EnumValue2.getDelegate().calc();
}
}
You cannot define methods for classes outside of a class!
You could define a callback interface that each enum instance had to have an instance of:
public interface MyEnumCallback {
doStuff(final Outer o)
}
Then your enum would look something like
public enum MyEnum {
X(new XCallback()),
Y(new YCallbaxk());
private final MyEnumCallback callback;
public MyEnum(final MyEnumCallback callback) {
this.callback = callback;
}
public <Whatever> call(final Outer o) {
callback.doStuff(o);
}
}
This separates your Enum from the methods as you wanted - it would also throw a compile time error if someone didn't provide an implementation of MyEnumCallback to the constructor of the Enum instance.
If I have a class that I would like to customise by overriding one if its methods the only I can do this is by using inheritance (sub-classing and overriding method) ? Is it possible to use composition in some way to achieve same goal ?
Yes, you can use delegation. Instead of deriving from Foo in the example below, Bar contains a Foo and delegates to it where it chooses.
interface SomeMethods {
void doSomething();
void doSomethingElse();
}
class Foo implements SomeMethod {
public void doSomething() { // implementation }
public void doSomethingElse() { // implementation }
}
class Bar implements SomeMethod {
private final Foo foo = new Foo();
public void doSomething() { foo.doSomething(); }
public void doSomethingElse() { // do something else! }
}
Using composition instead of inheritance is a design choice.
Either your class has been designed with inheritance in mind (i.e. it provides non-final public and protected methods, intended to be overridden by subclasses), or it has been designed with composition or delegation in mind (by using the strategy pattern, for example).
If the class has not been designed for customization at all, you might be able to customize it using inheritance, but not using a composition/delegation mechanism.
Sure. You can use the following patterns.
Simple overriding of method method
Template method pattern
class Base {
public void foo() {
// do something
bar();
// do something
}
protected abstract void bar();
}
class Child {
protected void bar() {
// do something.
}
}
Delegation
class Base {
private Runnable r;
protected Base(Runnable r) {
this.r = r;
}
public void foo() {
r.run();
}
}
class Child extends Base {
Child() {
super(new Runnable() { /* implementation */})
}
}