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()
Related
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;
}
Is there a way to inline implementation of an interface without having its default constructor? To understand my question better, Lets say I have an interface MyInterface and one implementation of it called MyImplementation.
public interface MyInterface
{
void myFunction();
}
public MyImplementation implements MyInterface
{
private final String someString;
public MyImplementation(String someString)
{
this.someString = someString;
}
public void myFunction()
{
// do something.
}
}
Is there a way to inline MyImplementation? If I didn't have to pass someString to constructor of implementation I could just say -
MyInterface myInterface = new MyInterface() {
public void myFunction()
{
// do something
}
};
If your question is how to make an anonymous class that references objects that you set up in the constructor, you could "inline" an implementation by making an anonymous class and reference final local variables defined in the same method, like this:
private final String someString = ...; // That's the string that you used to init in the constructor; init it here
MyInterface myInterface = new MyInterface() { // That's the code that you wanted to have
public void myFunction()
{
System.out.println(someString); // This is allowed, because someString is final
}
};
Behind the scene, Java compiler would generate a class that looks very much like your MyImplementation class, make a constructor that looks like your MyImplementation constructor, and pass someString to it.
Anonymous classes are the "old" way to do this. The new way in Java 8, for an interface with exactly one method, is to use lambda expressions.
For instance, let's say you wanted to print someString. Old way:
MyInterface o = new MyInterface() {
#Override
public void myFunction() {
System.out.println(someString);
}
};
new way:
MyInterface o = () -> System.out.println(someString);
You don't even need to make someString final with lambdas! It's good enough that it's "effectively final," which basically means that it could have been marked final and still compiled.
I have the following scenario in Java. Let's say I have an interface, and two classes that implement this interface. As follows:
public interface myInterface {
public String printStuff();
}
public class A implements myInterface {
#Override
public String printStuff(){
return "Stuff";
}
}
public class B implements myInterface {
#Override
public String printStuff(){
return "Stuff";
}
public String printOtherStuff(){
return "Other Stuff";
}
}
How do I call the printOtherStuff method above if I define it as follows:
public static void main(String... args) {
myInterface myinterface = new B();
String str = myinterface.printOtherStuff(); // ? This does not work
}
The above calling code does not seem work. Any ideas?
myInterface myinterface = new B();
The reference type of myinterface is myInterface. That means you can only access the methods defined in the interface. You can cast it to type B in order to make the method call.
NOTE: From here on out I'll be using the proper naming conventions.
Example
MyInterface myInterface = new B();
String str = ((B)myInterface).printOtherStuff();
Just a note on this
If you need to do this, then you need to have a look at your class design. The idea of using an interface in this way is to abstract away from the details of the object's concrete implementation. If you're having to perform an explicit cast like this, then you might want to look into either changing your interface to accommodate the necessary methods, or change your class so that the method is moved into a global location (like a util file or something).
Extra Reading
You should read about reference types here, and you should have a look at casting here. My answer is a combination of the understanding of both of these things.
As an added note, take a look at the Java Naming Conventions. This is a vital piece of information for any Java developer to make understandable code.
Surely this wouldn't work because you have reference type of Interface MyInterface. At the time of method binding compiler would try to find this method in your Interface MyInterface which is not available. So you need to cast it to your class like this.
MyInterface myInterface = new B();
B newB=(B) myInterface ;//casting to class
newB.printOtherStuff();// would work fine
change myInterface
public interface myInterface {
public String printStuff();
public String printOtherStuff();
}
If you cant change myInterface, then extends myInterface
public interface myOtherInterface extends myInterface {
public String printOtherStuff();
}
Then Implements myOtherInterface
public class B implements myOtherInterface {
#Override
public String printStuff(){
return "Stuff";
}
#Override
public String printOtherStuff(){
return "Other Stuff";
}
}
public static void main(String... args) {
myOtherInterface myotherinterface = new B();
String str = myotherinterface.printOtherStuff();
}
I have five cases of enums that look like this one below:
public enum Answers{
A(0), B(1), C(2), D(3), E(4);
Answers(int code){
this.code = code;
}
protected int code;
public int getCode(){
return this.code;
}
}
They all are all virtually the same except consisting of different "codes" and enumerators. I now have this following class where the generic is an extension of an Enum, however, I need to be able to use the getCode(), which is only in my enums, not a basic enum.
public class test<T extends Enum>{
public void tester(T e){
System.out.println(e.getCode()); //I want to be able to do this,
//however, the basic enum does don't
//have this method, and enums can't extend
//anything.
}
}
Thank you
You can make your enums implement an interface:
public interface Coded {
int getCode();
}
Then:
public enum Answers implements Coded {
...
}
And:
public class Test<T extends Enum & Coded> {
public void tester(T e) {
System.out.println(e.getCode());
}
}
Make all your enums implement a common interface:
public interface HasCode {
int getCode();
}
public enum Answers implements HasCode {
...
}
And then
public class Test<T extends HasCode> {
Have your enum classes implement your own HasCode interface:
public interface HasCode {
public int getCode();
}
public enum Answers implements HasCode {
//...
Then you can restrict T to be a HasCode:
public class test<T extends HasCode>{
and then Java will recognize that anything, even an enum, as long it implements HasCode, will have a getCode() method and it can be called in tester.
If that is the only method you want to add to your Enum then you don't have to do it. Every Enum already has ordinal method which returns value that represents it position in Enum. Take a look at this example
enum Answers{
A,B,C,D,E;
}
class EnumTest<T extends Enum<T>>{
public void tester(T e){
System.out.println(e.ordinal());
}
public static void main(String[] args) throws Exception {
EnumTest<Answers> t = new EnumTest<>();
t.tester(Answers.A);
t.tester(Answers.B);
t.tester(Answers.E);
}
}
Output:
0
1
4
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";
}
}