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
Related
I have a set of data model classes, e.g. DataModel1, DataModel2 and so on. The parameters that are part of each data class are totally different. The only thing common about these data classes is the objects which are going to use their values.
I have an interface 'Investigator', and only different implementation of these Investigator can use different type data of above model classes.
Initially I was having an empty interface for all data classes, like this
public interface DataModel {}
But then I realised that my scenario fits the visitor pattern.
So, I made changes as below:
I now have a DataModel interface
public interface DataModel {
void accept (Investigator investigator);
}
public class DataModel1 implements DataModel {
private String attribute1;
private String attribute2;
#Override
public void accept(Investigator investigator) {
investigator.investigate(this);
}
}
public class DataModel2 implements DataModel {
private String attribute3;
private String attribute4;
#Override
public void accept(Investigator investigator) {
investigator.investigate(this);
}
}
and an Investigator interface:
public interface Investigator {
void investigate(DataModel dataModel);
}
public class Investigator1 implements Investigator {
#Override
public void investigate(DataModel dataModel) {
// do some investigations of Type 1 here
}
}
public class Investigator2 implements Investigator {
#Override
public void investigate(DataModel dataModel) {
// do some investigations of Type 2 here
}
}
Now, for any kind of investigator and data model implementations,
I just have to do:
dataModel.accept(investigator)
and the correct type of investigation will be done.
Now, my problem comes when I want to actually return a result from the investigation that was done.
Similar to above requirements, an Investigator can return different types of InvestgationResult, so I have the interface and its implementations:
public interface InvestigationResult {
}
public class InvestigationResult1 implements InvestigationResult {
public String investigationText1;
public String detailedResults1;
}
public class InvestigationResult2 implements InvestigationResult {
public String investigationText2;
public String detailedResults2;
}
and the Investigator interface be changed to:
public interface Investigator {
InvestigationResult investigate(DataModel dataModel);
}
Here, an instance of a InvestigationResult implementation is only created by an Investigator implementation class. (once Investigator completes the investigation, he builds the investigation results)
My question here is that I don't want the 'InvestigationResult' interface to be am empty interface, but I am not very sure what common method it should contain?
Any help is appreciated.
I'm working on a simple project using Interfaces, but I am having an issue making my class conform to the interface.
My thought process is that since Article implements IDedObject, I should be able to pass an Article as a parameter in my overridden functions within my Article Class definition. Unfortunately this throws the error "The type Article must implement the inherited abstract method IDedObject.getID()"
Interface
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
Class
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
#Override
public int getID(Article article){
return article.articleID;
}
#Override
public void printID(Article article){
System.out.println(article.articleID);
}
}
What is missing or incorrect?
Only a guess since we don't have your requirements, but I think that your interface is broken, that your methods shouldn't require parameters much less parameters of its own type. Consider changing:
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
to:
public interface IDedObject{
public int getID();
public void printID();
}
Then the implementation would be trivial
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
// constructor and other getter and setter methods here
#Override
public int getID(){
return articleID;
}
#Override
public void printID(){
System.out.println("" + articleID);
}
}
As for your compiler error -- the signature of any overridden methods must match those of the interface methods. So for instance in your Rectangle example in your link, if you extend that class or interface, then the method parameter must take the interface parameter as declared in the interface.
For example, say you had the following interface:
public interface FooInterface {
int getValue();
void printValue();
int difference(FooInterface fi);
}
The concrete class that implements this interface must use a FooInterface parameter for the difference method. For example:
class FooClass implements FooInterface {
private int value;
#Override
public int getValue() {
return this.value;
}
#Override
public void printValue() {
System.out.println(String.valueOf(value));
}
#Override // can't use FooClass for parameter here
public int difference(FooInterface fi) {
return value - fi.getValue();
}
}
The getID and putID methods are not being overriden in Article class. They are being overloaded.
When you change the parameter type, it is an overload and not an override. This may seem a bit confusing at first but the key thing to understand is that Article inherits the two methods from the interface. When you change the parameter type, you are actually overloading these inherited methods rather than overriding them.
That said, the purpose of a getter method is to return the value of an instance variable and optionally perform some operations on this value before returning it.
Your override
public int getID(Article article)
Doesn't override the method of the interface because of a mismatch in the parameter - it should be IDedObject.
You could use a generic parameter to IDedObject, and use a wildcard constraint to make sure it implements IDedObject, but as far as I know, there is no way to tell Java that you want to inherit with the same type as the wildcard.
You need to cast to the implementation of the interface (Article). The method signatures in the interface and the class need to be the same.
public interface IDedObject{
public int getID(IDedObject object);
public void printID(IDedObject object);
}
public class Article implements IDedObject{
private int articleID;
private String articleName;
private String authorName;
#Override
public int getID(IDedObject object) {
Article article = (Article) object;
return article.articleID;
}
#Override
public void printID(IDedObject object) {
Article article = (Article) object;
System.out.println(article.articleID);
}
}
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.
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";
}
}
I am trying to create a generic Identifier class which I would be able to use as follows:
public class TestGenericIdentifier {
public static void main(String[] args) {
Identifier<Car> carId = new Identifier<>(Car.IdentifierType.LICENSE_PLATE, "123 XYZ");
Identifier<Person> personId = new Identifier<>(Person.IdentifierType.SOCIAL_SECURITY, "123456");
System.out.println(carId);
System.out.println(personId);
}
}
To get there, I started by creating an Identifiable interface:
public interface Identifiable<T extends Enum> {}
The idea being that a class that implements Identifiable needs to provide an enum T in its declaration which is the type of the first parameter of the Identifier constructor:
public class Identifier<E extends Identifiable<T>> { //does not compile
public Identifier(T type, String value) {
//some code
}
}
Now the code above does not compile as I can only use Identifiable (no parameter T) on the first line. If it worked I would be able to write the following two classes:
public class Car implements Identifiable<Car.IdentifierType>{
public enum IdentifierType {
SERIAL_NUMBER,
LICENSE_PLATE;
}
}
public class Person implements Identifiable<Person.IdentifierType> {
public enum IdentifierType {
DATABASE_ID,
SOCIAL_SECURITY;
}
}
Is there a way to do that using generics?
EDIT
One way is to compromise conciseness and keep compile-time type checking by doing:
public class Identifier<T extends Enum> {
public Identifier(T type, String value) {
}
}
and the main function becomes:
Identifier<Car.IdentifierType> carId = new Identifier<>(Car.IdentifierType.LICENSE_PLATE, "123 XYZ");
Identifier<Person.IdentifierType> personId = new Identifier<>(Person.IdentifierType.SOCIAL_SECURITY, "123456");
public class Identifier<E extends Identifiable<? extends Enum>> {
public Identifier(Enum type, String value) {
//some code
}
}
Might be enough for what you want
You can get this to compile by tweaking your code a bit but I'm not sure it's what you want. The following seems to work for me.
Identifier<Car.IdentifierType, Car> carId =
new Identifier<Car.IdentifierType, Car>(Car.IdentifierType.LICENSE_PLATE,
"123 XYZ");
public static class Identifier<T extends Enum, E extends Identifiable<T>> {
public Identifier(T type, String value) {
// some code
}
}
The question is why do you want to do this? If you edit your question some more with the background, I can edit my answer to be more helpful.