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.
Related
For a project, I have written the following interface:
public interface IManipulation {
void applyManipulation (double value);
}
Since I would like to force all implementing classes to use a certain constructor signature, I have been considering to change the interface into something like the following abstract class:
(edit: I forgot that it's not possible to have an abstract constructor, so I changed the "solution" below a bit)
public abstract class Manipulation {
private Signal signal;
public Manipulation (Signal signal) {
this.signal = signal;
}
public abstract void applyManipulation (double value);
protected Signal getSignal () {
return signal;
}
}
The reason for wanting to force this constructor is because every implentation should have an instance of Signal available. (and it should not be possible to reassign this signal)
Is this a valid reason to replace the interface with an abstract class (and live with the limitations that come with it), or are there any other potential solutions?
instead of an abstract class you should use an init method for that purpose.
public interface MyInterface{
public void init(YourParam p);
//... other methods
}
in the init you check, if the class is allready initialised if yes, just return.
So you have still an interface and can extend from other classes.
Instead of the constructor you will call the init method for your initialization
EDIT:
public interface IManipulation {
void init(Signal s);
void applyManipulation (double value);
}
You should use abstract classes only, if you have implementation details in it, which are shared by all subclasses. For Method signatures use interfaces
You can make empty constructor private in the abstract class:
abstract class AbstractManipulation {
private final Integer signal;
private AbstractManipulation() {
signal = null;
}
public AbstractManipulation (Integer signal) {
this.signal = signal;
}
}
class Manipulation extends AbstractManipulation {
public Manipulation(Integer signal) {
super(signal);
}
// Cannot redeclare
//public Manipulation() {
//}
}
Then:
public static void main(String[] args) {
// Will not work
//Manipulation m = new Manipulation();
// This one will
Manipulation m = new Manipulation(1);
}
You should not choose for technical reasons but rather logical, ie an abstract class is used when you have a realtion with the sub-classes like for example person: student, teacher. An interface is used when you want to impose a service contract for classes that may not have a relationship between them.
I have an abstract java class "BaseOperation". This class only has a single abstract method:
public abstract T execute()
{
...
return T;
}
Subclasses of BaseOperation must implement this method:
public class GetUsersOperation extends BaseOperation<GetUsersResponse>
{
...
#Override
public GetUsersResponse execute()
{
...
return GetUsersResponse;
}
}
This is a great way to put all common "operation" logic in the BaseOperation class, but still have every concrete subclass's execute() method have a different return type.
Now I need to change this structure to allow the execute() methods to have a variable amount of arguments. For example, one concrete subclass would require:
execute(String, int)
and another would need:
execute(Date, Date, String)
This is tricky, because the execute method is declared in the base class. Simply overloading the execute methods in the base is not ideal. Firstly, the amount of overloads would be huge. Secondly, every subclass will only ever use one of the execute methods, what's the point of all the others?
The (in my opinion) easiest solution would be to declare the execute method with varargs:
execute(Object... arguments)
And then downcast all arguments in the subclasses:
execute(Object... arguments)
{
String s = (String) arguments[0];
...
}
Obviously this has 2 major downsides:
Reduced performance because of all the downcasting operations
Calling the execute() methods is no longer strictly typed because any amount of objects can be passed witout compiler warnings.
Are there patterns or other solutions that could don't have these disadvantages?
You could use a bean holding the parameters:
public interface BaseOperation<T, U> {
T execute(U input);
}
public class GetUsersOperation implements BaseOperation<GetUsersResponse, UserInput> {
#Override
public GetUsersResponse execute(UserInput input) {
Date date = input.getDate();
return new GetUsersResponse(date);
}
}
Your abstract class only has one single abstract method: better use an interface. You can implement several interfaces while you can extend only one class.
As already said, the common approach for solving your issue is using a bean holding parameters. But here is another solution, based on a builder approach:
public interface BaseOperation<T> {
public T execute();
}
public class AddOperation implements BaseOperation<Integer> {
private int a, b;
public void setA(int arg){
a = arg ;
return this;
}
public void setB(int arg){
b = arg;
return this;
}
#Override
public Integer execute() {
return a+b ;
}
}
And then use it like this :
new AddOperation().setA(1).setB(2).execute();
You can mix required and optional parameters in this way:
public class MultipleAddOperation implements BaseOperation<Integer> {
private int sum ;
public MultipleAddOperation(int requiredInt){
sum = requiredInt;
}
public void add(int optionalInt){
sum += optionalInt ;
return this;
}
#Override
public Integer execute(){
return sum;
}
}
And so:
new MultipleAddOperation(5).add(1).add(2).execute();
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;
}
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
Hi I just want to make sure I have these concepts right. Overloading in java means that you can have a constructor or a method with different number of arguments or different data types. i.e
public void setValue(){
this.value = 0;
}
public void setValue(int v){
this.value = v;
}
How about this method? Would it still be considered overloading since it's returning a different data type?
public int setValue(){
return this.value;
}
Second question is: what is overriding
in java? Does it relate to inheritance. Let's I have the following:
public class Vehicle{
double basePrice = 20000;
//constructor defined
public double getPrice(){
return basePrice;
}
}
public class Truck extends Vehicle{
double truckPrice = 14000;
//constructor defined
public double getPrice(){
return truckPrice;
}
}
So now let's say I have the following
Truck truck = new Truck();
if I call
truck.super.getPrice()
this would return the price from the Vehicle class, 20,000
if I call
truck.getPrice()
this would return the price in the truck class, 14,000
Is my knowledge correct for both questions?
You are basically correct. Overloading is having multiple methods in a single class where the method has the same name. However, the return value is not seen as part of the signature of the method. Thus, you cannot overload a method by changing only the return value. You cannot have the following code, from your example:
public void setValue() {
this.value = 0;
}
public int setValue() {
return this.value;
}
This will fail to compile.
As Rob identified, I believe you mean overriding, and you have that correct. Note with overriding, you cannot change the return type. As of Java 5, you can return a derived type of what the base class method returned. Before Java 5, it must be the identical type. That is, you cannot do the below until Java 5 and later:
public class AnimalNoise {}
public class Miaw extends AnimalNoise {}
public class Animal {
public AnimalNoise makeNoise() {
return new AnimalNoise();
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
However, even in Java 5 and later, you cannot do the following:
public class Animal {
public String makeNoise() {
return "silence";
}
}
public class Cat extends Animal {
public Miaw makeNoise() {
return new Miaw ();
}
}
public class Miaw {}
Finally, a big difference between overloading and overriding that is often overlooked is that overloading is decided at compile time and overriding is decided at runtime. This catches many people by surprise when they expect overloading to be decided at runtime.
Correct; overloading is providing multiple signatures for the same method.
Overriding, which is what I think you mean by "overwriting" is the act of providing a different implementation of a method inherited from a base type, and is basically the point of polymorphism by inheritance, i.e.
public class Bicycle implements Vehicle {
public void drive() { ... }
}
public class Motorcycle extends Bicycle {
public void drive() {
// Do motorcycle-specific driving here, overriding Bicycle.drive()
// (we can still call the base method if it's useful to us here)
}
}
what you have described is correct.
For more clarification take a look at polymorphism concept. The Wikipedia has a good article
http://en.wikipedia.org/wiki/Polymorphism#Computing
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming