How to extends Enum in Java? - java

I have a class from sample project.But when I am using this class it shows some errors.The class is given below.
public class q extends Enum
{
private int i = -1;
private String s = null;
private q(String s, int i)
{
// super(s, i);
this.s = s;
this.i = i;
}
public static q valueOf(String s)
{
return (q)Enum.valueOf(q.class, s);
}
public static q[] values()
{
return (q[])a.clone();
}
public static final q ANDROID_VERSION;
public static final q APP_VERSION_CODE;
public static final q APP_VERSION_NAME;
public static final q AVAILABLE_MEM_SIZE;
private static final q a[];
static
{
APP_VERSION_CODE = new q("APP_VERSION_CODE", 1);
APP_VERSION_NAME = new q("APP_VERSION_NAME", 2);
ANDROID_VERSION = new q("ANDROID_VERSION", 6);
AVAILABLE_MEM_SIZE = new q("AVAILABLE_MEM_SIZE", 11);
q aq[] = new q[34];
aq[0] = APP_VERSION_CODE;
aq[1] = ANDROID_VERSION;
aq[2] = APP_VERSION_NAME;
aq[3] = AVAILABLE_MEM_SIZE;
a = aq;
}
}
When extending Enum it shows "The type q may not subclass Enum explicitly" error.How can i create an enum using these fields?
How can i modify this class to use like enum(ie,I want to use the default enum methods like ordinal(),valueOf(...) etc.. on this.)?

You cannot extend from Enum. You have to declare an Enum class like:
public enum Q {
TYPE1, TYPE2, TYPE3;
}
And you also cannot instantiate an enum class directly. Each type of your enum class is instantiated exactly once by the virtual machine.
public class MyClass {
public enum MyEnum{
TYPE1("Name", 9,1,100000), TYPE2("Name2", 10, 1, 200000);
private final int androidVersion;
private final int appVersionCode;
private final int availableMemSize;
private final String appVersionName;
private MyEnum(String appVersionName, int androidVersion, int appVersionCode, int availableMemSize) {
this.androidVersion = androidVersion;
this.appVersionCode = appVersionCode;
this.availableMemSize = availableMemSize;
this.appVersionName = appVersionName;
}
}
MyEnum mType = MyEnum.TYPE1;
}

Enums basically boil down to something like this:
public Enum Q
{
TYPE1, TYPE2, TYPE3:
}
// is roughy translated to
public final class Q
{
private Q() {}
public static final Q TYPE1 = new Q();
public static final Q TYPE2 = new Q();
public static final Q TYPE3 = new Q();
}
There is more you can do, but this should explain why you can not instantiate Q.

- Think of the enum keyword as syntatic sugar. It sets up classes with normal inheritance trees for you, but will not allow you to extend java.lang.Enum.
Eg:
public enum TEST {
ONE, TWO, THREE;
}

Related

Enum with generic base class passed as contructor parameter

I'm attempting to create an enum whose constructor accepts an object whose base class is a generic class.
I seem to be unable to fetch the underlying generic type from within the enum however, Object gets returned instead of T.
Is there a way to do this?
abstract public class Field<T> {
abstract public T get();
}
public class IntegerField extends Field<Integer> {
public Integer get() {
return 5;
}
}
public class StringField extends Field<String> {
public String get() {
return "5";
}
}
public enum Fields {
INTEGER (new IntegerField()),
STRING (new StringField());
private final Field<?> field; // <<--- I can't have Field<T>, enum's can't be generic. :(
<T> Fields(Field<T> field) {
this.field = field;
}
public <T> T get() {
return field.get(); // <<--- Returns Object, not T
}
}
The issue is that enums can't be generically typed so even if you cast that get call ((T) field.get()) you won't have type safety because it will agree with any assignment (you could compile this successfully for instance: boolean b = Fields.INTEGER.get()).
Just use constants instead:
public final class Fields {
public static final Field<Integer> INTEGER = new IntegerField();
public static final Field<String> STRING = new StringField();
}
Why do you think an enum is preferable to this?
public final class Fields {
public static final Field<Integer> INTEGER = new IntegerField();
public static final Field<String> STRING = new StringField();
//private ctor
}
or if you prefer
public final class Fields {
public static Field<Integer> integerField() {
return new IntegerField();
}
public static Field<String> stringField() {
return new StringField();
}
//private ctor
}
Why would I want to call Fields.INTEGER.get() when I can just use Fields.INTEGER?

howto handle objects of private class, got as parameter

I learn Java at university and I have to do following excercise.
(simplified example)
import java.util.*;
public class A{
private static class B{
Integer b;
private B(int b){this.b = b;}
}
private static class B_Comparable extends B implements Comparable<B_Comparable> {
private B_Comparable(int b){super(b);}
#Override
public int compareTo(B_Comparable that) {
return this.b.compareTo(that.b);
}
}
private static class C<T> implements myList<T> { // see below
private ArrayList<T> lst = new ArrayList<>();
private static C<B_Comparable> createComparable() {
C<B_Comparable> ust = new C<B_Comparable>();
for (int i =0; i < 9; i++)
ust.lst.add(new B_Comparable(i));
return ust;
}
#Override
public T fetch(int index){
return lst.get(index);
}
}
private void test(){
C<B_Comparable> ustComparable = C.createComparable();
A result = ClassD.handle(ustComparable,3,4);
}
}
//--------------------------------------------------------
public class ClassD{
public static <T, S> T handle( S ustC, int pos1, int pos2 ){
// how can I compare elems of object ustC ?
ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
//how can I fetch obj at pos1 ?
return ustC.fetch(pos1);
}
}
//-----------------------------------------
public interface myList<T> {
T fetch(int index);
}
static method handle gets an object (ustC) which is private. How can I
use methods, compareTo and fetch for this object? I have tried parametrisation, but if its the right way, I don't know how to solve.
Thanks for any help.
As discussed in comments, ustC, by virtue of the way handle is called in this context is of type C, which implements the myList interface. This interface exposes the fetch method, and is visible to your handle method.
The modification you arrived at in your comments would allow you to call fetch:
//Solution
public class ClassD {
public static <S extends Comparable> S handle(myList<S> ustC, int pos1, int pos2 ){
int y = ustC.fetch(pos1).compareTo(ustC.fetch(pos2));
return ustC.fetch(pos1);
}
}

java enum type getting a bit obfuscated

Hi I am practicing java enum these days and have been given the task of debugging some codes on these out of all i have found one very challenging here it is
public final class ParkingAttributes extends Enum
{
public static final ParkingAttributes BIKE;
public static final ParkingAttributes CAR;
public static final ParkingAttributes CYCLE;
private static final ParkingAttributes ENUM$VALUES[];
private ParkingAttributes(String s, int i)
{
super(s, i);
}
public static ParkingAttributes valueOf(String s)
{
return (ParkingAttributes)Enum.valueOf(com/tilzmatictech/mobile/navigation/delhimetronavigator/metro/ParkingAttributes, s);
}
public static ParkingAttributes[] values()
{
ParkingAttributes aparkingattributes[] = ENUM$VALUES;
int i = aparkingattributes.length;
ParkingAttributes aparkingattributes1[] = new ParkingAttributes[i];
System.arraycopy(aparkingattributes, 0, aparkingattributes1, 0, i);
return aparkingattributes1;
}
static
{
CAR = new ParkingAttributes("CAR", 0);
BIKE = new ParkingAttributes("BIKE", 1);
CYCLE = new ParkingAttributes("CYCLE", 2);
ParkingAttributes aparkingattributes[] = new ParkingAttributes[3];
aparkingattributes[0] = CAR;
aparkingattributes[1] = BIKE;
aparkingattributes[2] = CYCLE;
ENUM$VALUES = aparkingattributes;
}
}
One thing i know that enum is a final class and cannot be extended what i didnt find anywhere here is that enum be defined and work of ENUM$VALUES[]
Can anyone explain me the working of this code and some good tutorials to master enum
thanks.
You are doing it wrong.
If you want to declare an enum, do it like this :
public enum ParkingAttributes { //Implicitly a final class that extends Enum
BIKE, CAR, CYCLE//Implicitly static (but not final!) instances of ParkingAttributes.
}

Is it the right way to do what Im trying? Abstract static variable?

Look on the code below. It seems to be like there is easier way to do it.
For each new Class I want to add to the system, I have to do the following in order to set the class variable(static -> maxPlayers)?
Something like Abstract static variable?
protected abstract class Class{
protected abstract int getMaxPlayers();
public class Soldier extends Class{
public static final int maxPlayers = 4;
#Override
protected int getMaxPlayers() {
return Soldier.maxPlayers;
}
}
public class Demoman extends Class{
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Demoman.maxPlayers;
}
}
public class Scout extends Class{
public static final int maxPlayers = 4;
#Override
protected int getMaxPlayers() {
return Scout.maxPlayers;
}
}
public class Medic extends Class{
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Medic.maxPlayers;
}
}
}
its just like i have to repeat this template:
public static final int maxPlayers = 2;
#Override
protected int getMaxPlayers() {
return Medic.maxPlayers;
}
And i think it is not correct to do so.
First of all, you shouldn't name your class Class (not even for examples). Choose a better name.
Secondly, it seems like an enum is what you really need here:
public enum Army {
SOLDIER(4),
DEMOMAN(2),
SCOUT(4),
MEDIC(2);
private final int maxPlayers;
private Army(int maxPlayers) {
this.maxPlayers = maxPlayers;
}
public int getMaxPlayers() {
return maxPlayers;
}
}
No, you can't have an static variable in a base class that has a different value for each subclass (as far as I can tell, this is what you'd ideally want to do).
The way you did it is one option, another is using a non-static variable, as below.
And your variable should preferably have less scope than your getter function.
class Class
{
private final int maxPlayers;
Class(int max)
{
maxPlayers = max;
}
public int getMaxPlayers()
{
return maxPlayers;
}
}
class Soldier extends Class
{
Soldier()
{
super(4);
}
}
To increase readability and modifiability, you may want to consider replacing 4 here with an enum or similar.
Another way:
abstract class Class
{
public static int MAX_PLAYERS_SOLDIER = 4,
MAX_PLAYERS_DEMOMAN = 2,
...;
protected abstract int getMaxPlayers();
}
class Soldier extends Class
{
#Override
protected int getMaxPlayers()
{
return MAX_PLAYERS_SOLDIER;
}
}

Extending enum in Java

public enum myEnum {
VAL1(10), VAL2(20), VAL3("hai") {
public Object getValue() {
return this.strVal;
}
public String showMsg() {
return "This is your msg!";
}
};
String strVal;
Integer intVal;
public Object getValue() {
return this.intVal;
}
private myEnum(int i) {
this.intVal = new Integer(i);
}
private myEnum(String str) {
this.strVal = str;
}
}
In the above enum what exactly happens when I add a constant specific class body for VAL3?
The type of VAL3 is definetly a subtype of myEnum as it has overloaded and additional methods. (the class type comes as 'myEnum$1' )
But how can the compiler creates a subtype enum extending myEnum as all the enums are already extending java.lang.enum ?
Your class myEnum inherits from java.lang.Enum. VAL3 is an anonymous inner class that inherits from myEnum called myEnum$1. Think of the enum keyword as syntatic sugar. It sets up classes with normal inheritance trees for you, but will not allow you to extend java.lang.Enum or myEnum directly.
From decompiler
package com.sun.tools.xjc.outline;
public final class Aspect extends Enum
{
public static final Aspect EXPOSED;
public static final Aspect IMPLEMENTATION;
private static final Aspect $VALUES[];
static
{
EXPOSED = new Aspect("EXPOSED", 0);
IMPLEMENTATION = new Aspect("IMPLEMENTATION", 1);
$VALUES = (new Aspect[] {
EXPOSED, IMPLEMENTATION
});
}
public static final Aspect[] values()
{
return (Aspect[])$VALUES.clone();
}
public static Aspect valueOf(String name)
{
Aspect arr$[] = $VALUES;
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
Aspect aspect = arr$[i$];
if(aspect.name().equals(name))
return aspect;
}
throw new IllegalArgumentException(name);
}
private Aspect(String s, int i)
{
super(s, i);
}
}

Categories

Resources