Inheritance in enum - java

I have given an enum ABC and a class Test and I have to call doSomething but I cannot pass ABC enum as parameter.
enum ABC{
A,B,C;
}
Class Test{
public void doSomething(ABC abc)
{
//some work
}
}
Here I want an enum DEF that should have all member of ABC and it should also have member of enum XYZ (I want an enum DEF that should contain members of two enums(ABC and XYZ)). Example like this.
enum DEF
{
A,B,C,X,Y,Z,D;
}
enum xyz{
X,Y,Z;
}
So that I can call doSomething method which takes only ABC enum as parameter. I want to call doSomething() method with DEF.Example
class Demo{
public static void main(String[] ags)
{
Test test= new Test();
test.doSomething(DEF.A);
}
}
I am fresher. Kindly provide me any help or suggestion.I will be thankful to you.

Enums in Java are final, which means you cannot extend and enum (you cannot add more values to existing enum). In you case the ABC and DEF are completely different entities with simple the same names of enum items. This implicates for example that ABC.A != DEF.A.
There are many ways to handle that, however none of them is perfect or simple. You should evaulate what is needed in your specific case.
First way to handle that is to create a common interface, which your enums can extend:
interface MyInterface{
}
enum ABC implements MyInterface{
A,B,C;
}
enum DEF implements MyInterface{
A,B,C,X,Y,Z,D;
}
This way you can use both ABC and DEF in doSomething():
Class Test{
public void doSomething(MyInterface abc)
{
//some work
}
}
Other approach is to add generics to your class. This way you can create concrete implementations which will support specified enum:
class GenericTest<E extends Enum<E>>{
public void doSomething(E enum){
}
}
class TestWhichAcceptsABC extends GenericTest<ABC>{}
class TestWhichAcceptsDEF extends GenericTest<DEF>{}
Third way is to create multiple methods, one for each enum which need to be handled
Class Test{
public void doSomething(ABC abc)
{
//some work
}
public void doSomething(DEF abc)
{
//some work
}
}
See This thread for more ideas how to solve enum inheritance.

Even though you have mentioned in same name it doesnt mean same in enum.
For Example A in ABC is instance of ABC. But A in DEF is instance of DEF. So its different. You can implement interface in enum.
enum ABC implements X{
A,B,C;
}
public class Test{
public void doSomething(X x)
{
}
}
You will try this.

You can't extend enums but you can do the next best thing by simulating the behaviour of an enum. You can create a class with static value. Like this.
public class abc extends yxz {
public static final int A = 1;
public static final int B = 2;
public static final int C = 3;
}

Related

Declare constant in interface, but define in implementation

I want to be able to do something akin to the following
public interface myInterface{
public final String MY_CONST
}
public class myImpl implements myInterface{
MY_CONST="Hello World"
}
Basically, I want to declare a constant in my interface, and define it in my implementation. Is there a way to do something like this in java/groovy?
In Java, the closest you can come is a getter:
public interface myInterface{
String getConstant();
}
public class myImpl implements myInterface{
public String getConstant() {
return "Hellow world";
}
}
...since interfaces can't have instance fields.
You can use traits in Groovy with similar effect:
trait WithConstant {
final String VALUE = "tim"
}
class MyClass implements WithConstant {
final String VALUE = "steve"
def print() {
println VALUE
}
}
new MyClass().print()

Use method from other class like native methods?

(newbie in Java) I couldn't find exactly this question on SO. I have project, with two files (phseudo-code):
First Java File (class)
public class A {
public void xyz() { System.out.println("hello");}
}
Second Java File (class)
public class B Extends ZZZZZ {
public void callme() {
xyz(); // <----------------- I want to call in this way, but It cant be done like this.
}
}
How to make xyz() to call successfully (like as if was defined inside b() class natively !!).
p.s. again, I don't want to call it with classname in front, like this:
a.xyz();
The whole idea of instance methods, like xyz is in this, is that you are using the state of an instance of A in the method, without having to pass that instance as an argument like this:
... String xyz(A thisInstance, ...) {...}
Instead you use:
A thisInstance = ...;
thisInstance.xyz(...);
That's why you need an instance of A, because it is practically an argument to the function.
However, if you don't need an instance of A, you can make the method static:
static String xyz(...) {...}
Then you can call it without passing an instance of A:
A.xyz(...);
You can use a static import so that you don't have to write A:
import static A.xyz;
...
xyz(...);
Okay several possibilities:
Instantiate A:
A a=new A();
a.xyz();
(you do not want this)
Heredity:
public class B extends A {...}
and
public class A extends ZZZZZ{...}
so you can still extend ZZZZZ;
Interface:
public interface A{...}
public class B extends ZZZZZ implements A{...}
Static Method:
public class A{
public static void xyz()
{
System.out.println("hello");
}
}
public class B{
public void callme()
{
A.xyz());
}
}
This will help you.
class A {
public void xyz() {
System.out.println("hello");
}
}
class ZZZZZ extends A{
}
class B extends ZZZZZ {
public void callme() {
xyz();// <----------------- calling this shows error
}
}

enum implementation inside interface - Java

I have a question about putting a Java enum in the interface.
To make it clearer, please see the following code:
public interface Thing{
public enum Number{
one(1), two(2), three(3);
private int value;
private Number(int value) {
this.value = value;
}
public int getValue(){
return value;
}
}
public Number getNumber();
public void method2();
...
}
I know that an interface consists of methods with empty bodies. However, the enum I used here needs a constructor and a method to get an associated value. In this example, the proposed interface will not just consist of methods with empty bodies. Is this implementation allowed?
I am not sure if I should put the enum class inside the interface or the class that implements this interface.
If I put the enum in the class that implements this interface, then the method public Number getNumber() needs to return the type of enum, which would force me to import the enum in the interface.
It's perfectly legal to have an enum declared inside an interface. In your situation the interface is just used as a namespace for the enum and nothing more. The interface is used normally wherever you use it.
Example for the Above Things are listed below :
public interface Currency {
enum CurrencyType {
RUPEE,
DOLLAR,
POUND
}
public void setCurrencyType(Currency.CurrencyType currencyVal);
}
public class Test {
Currency.CurrencyType currencyTypeVal = null;
private void doStuff() {
setCurrencyType(Currency.CurrencyType.RUPEE);
System.out.println("displaying: " + getCurrencyType().toString());
}
public Currency.CurrencyType getCurrencyType() {
return currencyTypeVal;
}
public void setCurrencyType(Currency.CurrencyType currencyTypeValue) {
currencyTypeVal = currencyTypeValue;
}
public static void main(String[] args) {
Test test = new Test();
test.doStuff();
}
}
In short, yes, this is okay.
The interface does not contain any method bodies; instead, it contains what you refer to as "empty bodies" and more commonly known as method signatures.
It does not matter that the enum is inside the interface.
Yes, it is legal. In a "real" situation Number would implement Thing, and Thing would probably have one or more empty methods.

Super class which uses the values from children

I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}

Interface questions

Suppose that I have interface MyInterface and 2 classes A, B which implement MyInterface.
I declared 2 objects: MyInterface a = new A() , and MyInterface b = new B().
When I try to pass to a function - function doSomething(A a){} I am getting an error.
This is my code:
public interface MyInterface {}
public class A implements MyInterface{}
public class B implements MyInterface{}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
test(b);
}
public static void test(A a){
System.out.println("A");
}
public static void test(B b){
System.out.println("B");
}
}
My problem is that I am getting from some component interface which can be all sorts of classes and I need to write function for each class.
So one way is to get interface and to check which type is it. (instance of A)
I would like to know how others deal with this problem??
Thx
Can you not just have a method on the interface which each class implements? Or do you not have control of the interface?
This would provide both polymorphism and avoid the need to define any external methods. I believe this is the intention of an interface, it allows a client to treat all classes implementing it in a non type specific manner.
If you cannot add to the interface then you would be best introducing a second interface with the appropriate method. If you cannot edit either the interface or the classes then you need a method which has the interface as a parameter and then check for the concrete class. However this should be a last resort and rather subverts the use of the interface and ties the method to all the implementations.
It sounds like you are after something like this:
public static void test(MyInterface obj){
if(obj instanceof A) {
A tmp = (A)obj;
} else if(obj instanceof B) {
B tmp = (B)obj;
} else {
//handle error condition
}
}
But please note this is very bad form and indicates something has gone seriously wrong in your design. If you don't have control of the interface then, as suggested by marcj, adding a second interface might be the way to go. Note you can do this whilst preserving binary compatibility.
I'm unclear on what you're actually asking, but the problem is that you don't have a method that takes a parameter of type MyInterface. I don't know what the exact syntax is in Java, but you could do something like if (b is B) { test(b as B) } but I wouldn't. If you need it to be generic, then use the MyInterface type as the variable type, otherwise use B as the variable type. You're defeating the purpose of using the interface.
I'm not sure if I fully understand the issue, but it seems like one way might be to move the test() methods into the child classes:
public interface MyInterface {
public void test();
}
public class A implements MyInterface{
public void test() {
System.out.println("A");
}
}
public class B implements MyInterface{
public void test() {
System.out.println("B");
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
b.test();
}
}
You could similarly use a toString() method and print the result of that. I can't quite tell from the question, though, if your requirements make this impossible.
I think visitor design pattern will help you out here. The basic idea is to have your classes (A and B) call the appropriate method themselves instead of you trying to decide which method to call. Being a C# guy I hope my Java works:
public interface Visitable {
void accept(Tester tester)
}
public interface MyInterface implements Visitable {
}
public class A implements MyInterface{
public void accept(Tester tester){
tester.test(this);
}
}
public class B implements MyInterface{
public void accept(Tester tester){
tester.test(this);
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
a.accept(this);
b.accept(this);
}
public void test(A a){
System.out.println("A");
}
public void test(B b){
System.out.println("B");
}
}
Use only one public class/interface in one .java file, otherwise it'll throw error. And call the object with the object name.. You declared two methos in Teater class only, then what the purpose of declaring class A,B.
I usually use an abstract class to get around this problem, like so:
public abstract class Parent {}
public class A extends Parent {...}
public class B extends Parent {...}
That allows you to pass Parent objects to functions that take A or B.
You have 3 options:
Visitor pattern; you'll need to be able to change the MyInterface type to include a method visit(Visitor) where the Visitor class contains lots of methods for visiting each subclass.
Use if-else inside your method test(MyInterface) to check between them
Use chaining. That is, declare handlers ATester, BTester etc, all of which implement the interface ITester which has the method test(MyInterface). Then in the ATester, check that the type is equal to A before doing stuff. Then your main Tester class can have a chain of these testers and pass each MyInterface instance down the chain, until it reaches an ITester which can handle it. This is basically turning the if-else block from 2 into separate classes.
Personally I would go for 2 in most situations. Java lacks true object-orientation. Deal with it! Coming up with various ways around it usually just makes for difficult-to-follow code.
Sounds like you need either a) to leverage polymorphism by putting method on MyInterface and implementing in A and B or b) some combination of Composite and Visitor design pattern. I'd start with a) and head towards b) when things get unwieldy.
My extensive thoughts on Visitor:
http://tech.puredanger.com/2007/07/16/visitor/
public interface MyInterface {}
public class A implements MyInterface{}
public class B implements MyInterface{}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
test(b); // this is wrong
}
public static void test(A a){
System.out.println("A");
}
public static void test(B b){
System.out.println("B");
}
}
You are trying to pass an object referenced by MyInterface reference variable to a method defined with an argument with its sub type like test(B b). Compiler complains here because the MyInterface reference variable can reference any object which is a sub type of MyInterface, but not necessarily an object of B.There can be runtime errors if this is allowed in Java. Take an example which will make the concept clearer for you. I have modified your code for class B and added a method.
public class B implements MyInterface {
public void onlyBCanInvokeThis() {}
}
Now just alter the test(B b) method like below :
public static void test(B b){
b.onlyBCanInvokeThis();
System.out.println("B");
}
This code will blow up at runtime if allowed by compiler:
MyInterface a = new A();
// since a is of type A. invoking onlyBCanInvokeThis()
// inside test() method on a will throw exception.
test(a);
To prevent this, compiler disallows such method invocation techniques with super class reference.
I'm not sure what are you trying to achieve but it seems like you want to achieve runtime polymorphism. To achieve that you need to declare a method in your MyInterface and implement it in each of the subclass. This way the call to the method will be resolved at run time based on the object type and not on the reference type.
public interface MyInterface {
public void test();
}
public class A implements MyInterface{
public void test() {
System.out.println("A");
}
}
public class B implements MyInterface{
public void test() {
System.out.println("B");
}
}
public class Tester {
public static void main(String[] args){
MyInterface a = new A();
MyInterface b = new B();
b.test(); // calls B's implementation of test()
}
}

Categories