I have a lot of subclasses of an abstract class and each of them declare a public static final field with the same name. I was thinking of having this field in the abstract superclass without initializing it and hoping that each subclass would be forced to initialize it.
I was thinking of this because all of my subclasses of the abstract class declare a public static final String field called UNIQUE_ID, and it is necessary for every subclass to declare such a field with exactly that name.
I hope my question is clear enough, if not please tell me so.
Can something more or less equivalent to this be done?
EDIT: Code added:
My abstract class looks like:
public abstract class ExperimentPanelModel extends Panelizable {
protected String nextButtonText;
protected String backButtonText;
protected String skipButtonText;
protected Properties currentFile;
protected List<Properties> pastFiles = new ArrayList<Properties>();
public ExperimentPanelModel(Properties argcurrentfile, List<Properties> argpastfiles) {
currentFile = argcurrentfile;
pastFiles = argpastfiles;
nextButtonText = "Next";
backButtonText = "Back";
skipButtonText = "Skip";
}
...
}
Some of the non-abstract subclasses of that abstract class look like (note that all of them declare public static final String UNIQUE_ID) :
public class ConfigurationGUI extends ExperimentPanelModel {
public static final String UNIQUE_ID = "ConfigurationGUI";
public static final String DATA_MODIFIED = "DataModified";
Date dateOfLastSession;
int ExperimentalSession;
int ExperimentOrder;
boolean nextButtonEnabled = false;
public ConfigurationGUI(Properties argcurrentfile, List<Properties> argpastfiles) {
super(argcurrentfile, argpastfiles);
nextButtonText = "Confirm";
backButtonText = "Abort";
}
...
}
One example more:
public class Introduction extends ExperimentPanelModel {
public static final String UNIQUE_ID = "Introduction";
public static final String INSTRUCTIONS_XML_FILE = "instructions.xml";
public static final String THIS_INSTRUCTION_PROPERTY = UNIQUE_ID;
private String thisInstructionText = UNIQUE_ID;
Properties readInstructionsProperties = new Properties();
public Introduction(Properties argcurrentfile, List<Properties> argpastfiles) {
...
And the last one:
public class Instruction1 extends ExperimentPanelModel {
public static final String UNIQUE_ID = "Instruction1";
public static final String INSTRUCTIONS_XML_FILE = "instructions.xml";
public static final String THIS_INSTRUCTION_PROPERTY = UNIQUE_ID;
...
}
The field idea won't work, because static fields can't be overridden in subclasses. What you can do is you can declare an abstract method on the abstract class so that your subclasses must implement it.
Also note you can't make it a static method because those don't get overridden either.
In your case I would define the variable in the ancestor. No point in having a variable in each of the extending classes, unless you have a particularly good reason, which you don't sound like having.
+1 for Nathan's reply though. In quite a few cases, that's a better thing to do.
Put the public final field UNIQUE-ID in the abstract class and declare a protected constructor which takes the value for UNIQUE-ID. You'll not be able to make it static though as the values are required to be different for different instances.
Related
I must define a class which all it does is hold constants.
public static final String CODE1 = "100";
public static final String CODE2 = "200";
Now I want use these values in other classes. Is it better to use this class as a static class or instantiate it ?
Thanks.
Note : I know enums but in this context, I must use a class.
Just to use the values, you certainly shouldn't instantiate the class. Just because you can access static members as if they were instance members doesn't mean it's a good idea.
If the class really only contains constants - and if you're sure that's a good idea, rather than those constants appearing within classes which are directly related to them - you should make it a final class with a private constructor, so that no-one can pointlessly instantiate it:
public final class Codes {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
// Prevent instantiation
private Codes() {
}
}
Don's answer suggesting using an enum is a very good idea too - it means you can use Code in your API everywhere that you don't need the exact string representation, which prevents you from accidentally using non-code values.
Jons answer is correct, although I want to show you a solution with an enum.
There is a disadvantage in accessing its String value as you have to call Code.CODE1.text() instead of Code.CODE1.
public enum Code {
CODE1("100"), CODE2("200");
private String text;
Codes(String text) {
this.text = text;
}
public String text() {
return text;
}
}
java language spec and JVM spec allow you to do anything you wanted, whether instantiate a class or use final or use other way....
Just use Eclipse and try !
while there is some good practice, Jon Skeet's answer is one good practice.
Java Language is not support global variable
public class ComonFun {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
public static String CODE1(){
return CODE1;
}
public static String CODE2(){
return CODE2;
}
}
implement
public class Main {
public static void main(String[] args) {
System.out.println(ComonFun.CODE1());
System.out.println(ComonFun.CODE2());
}
}
i think that you need simply to declare an interface, you won't need to specify the clause "public static final". and it can be usuable throgh the hall project.
Use them as static, don't go for instantiation.
Even use static import as a benefit.
package coma;
import static coma.ImportStatments.*;
public class UsingClass {
public static void main(String[] args) {
System.out.println(CODE1);
}
}
And the class with final variables would look like this:
package coma;
public class ImportStatments {
public static final String CODE1 = "100";
public static final String CODE2 = "200";
}
I'm trying to write more generic class for below code so the type and static variables that define in EvenTypes can be changed by the end developer and give them options to add or remove static variables in EventType.
I'm also think of having generic enum for event type as below.
public interface EventType<T extends Enum<T>>
{
String name();
String getFriendlyName();
Class<T> getDeclaringClass();
T getRaw();
public String getFullClassName();
}
Original Code
public class Event implements Serializable
{
private String eventId;
private String eventType;
.....
}
public class EventTypes
{// below static variables can be changed by the developer based on requirements
public static final String DO_FILE_CONVERSION = "100";
public static final String DO_REMOVE_FILE = "101";
public static final String DO_COPY_FILE = "102";
.....
}
public class EventProcessorFactory
{
#SuppressWarnings("rawtypes")
public IEventProcessor createProcessor(EventType eventType)
throws EventException
{
String eventProcessorClassName = (getEvenClassName based on type from properties files);
Class eventProcessorClazz = Class.forName(eventProcessorClassName);
return (IEventProcessor) eventProcessorClazz.newInstance();
}
}
properties.file
----
100=FileConversion.class
101=FileRemove.class
102= FileCopy.class
Make Event an interface and extend it from Serializable.
Then use an enum to implement that Event interface. Example:
public interface Event extends Serializable {
// Throw in your methods here
}
public enum MyEvents implements Event {
DO_FILE_CONVERSION, DO_REMOVE_FILE, DO_COPY_FILE;
// Implement methods
}
This way you have your interface (namely whatever you want Event capable of doing) seperated from the implementation (which Events exist and the implementation of them).
when you extend a private class. Are the public and protected members of class become private. if not any explanation.
if you extend a nested private class, it wont change public/protected modifiers of the members. Here is an example :
public class Clazz {
private static class NestedClazz {
public int value = 123;
}
public static class NestedClazzExt extends NestedClazz {
}
}
you can now access the inherited member: value from outside
public static void main(String[] args) {
NestedClazzExt nestedClazz = new Clazz.NestedClazzExt();
System.out.println(nestedClazz.value);
}
you can create private class in side a class . We call it as Nested classe. Means a class inside a class. The Concept itself is saying that you can create private class in side another class. The private class will act like as data member to the outer class.
So, You can't extend the private class.
Based on your query I tried to prepare a simple class.
public class pvtClass {
private class As {
public String abc = "private attribute";
public void print(){
System.out.println("privateClass");
}
}
class Ab extends As{
public String ab = "extended attribute";
public void printAb(){
System.out.println("extended class");
print();
System.out.println(abc);
}
}
public static void main(String as[]){
Ab ab1 = (new pvtClass()).new Ab();
As as1 = (new pvtClass()).new As();
ab1.printAb();
as1.print();
System.out.println(as1.abc);
}
}
If you have a look at this class, I have a private class named "As" which has public attribute and public methods. I have another class named "Ab" which extends "As". I have written a main method to invoke the private attribute and methods.
below is the output for the code snippet:
extended class
privateClass
private attribute
privateClass
private attribute
There is a difference between the access of the members of a class and the access to the type itself.
public class C {
private class InnerP1 {
public void m() {
System.out.println("InnerP1.m()");
}
}
private class InnerP2 extends InnerP1 {
public void p() {
this.m();
System.out.println("InnerP2.p()");
}
}
public InnerP1 strange() {
return new InnerP2();
}
}
In this example, the interface I is visible from outside class C. The classes InnerP1 and InnerP2 are not visible from outside C. Jave itself makes not restrictions to the visibility of types you use in your public interface. The method strange() of class C returns a result of class InnerP1. Since outside of C we do not know anything about the class InnerP1 other than it is subtype of Object, the only thing we can do is use the result of strange() as an Object.
public class D {
public static void main(String[] args) {
C c = new C();
Object o = c.strange();
if(o.equals(c.strange())) {
System.out.println("Strange things are going on here!");
}
}
}
As #KnusperPudding pointed out already, the visiblity of public members is not changed, we might just not have enough knowledge of the type itself to access them.
Access to members cannot be restricted by sub-classing. When you mark a class as private then access via the class name is restricted i.e. to the same .java file, however once you have an instance of this class it can be accessed at least as easily as the super class.
If I have an abstract class that has variables of the form
protected static final int blah;
protected static final int blah2;
And i have two classes that extend this abstract class, and set these variables to "static final int" values from a constants file in their constructors, will they clobber eachother's values? If I want to do such a thing, what would you recommend I do?
So, for example, if i have
impl1 class:
public impl1 extends absClass{
public impl1(){
this.blah = CONSTANTS.impl1_blah;
this.blah2 = CONSTANTS.impl1_blah2;
}
}
impl2 class:
public impl2 extends absClass{
public impl2(){
this.blah = CONSTANTS.impl2_blah;
this.blah2 = CONSTANTS.impl2_blah2;
}
}
Is this allowed? If not, what should I do?
this.blah = CONSTANTS.impl2_blah;
this.blah2 = CONSTANTS.impl2_blah;
this allowed?
This isn't allowed, since your blah variables are declared as final. You must initialize them during class initialization, either in their declaration or in a static initializer block.
Furthermore, these variables are static, and so accessing them using this won't work: the variables belong to the class and not an instance.
If not, what should I do?
Use non-final variables in the superclass, or use specific constants in the subclasses.
if classes extending that abstract class are supposed to give their own values for those variables then you should consider a couple of protected abstract methods instead.
static variables can't be overridden. Those will be associated with the classes where you have defined them.
static final variables must be initialized when the class that declares them is initialized. This is before any instances of the class (or any subclass) are created. Your code won't compile without some sort of initialization for blah and blah2—either an initialization expression:
protected static final int blah = 42;
protected static final int blah2 = 1;
or in a static initializer block:
protected static final int blah;
protected static final int blah2;
static {
blah = 42;
blah2 = 1;
}
In either case, subclasses have no say in what blah and blah2 get assigned.
It seems from your example code that you want constants that can vary on a per-instance basis. It doesn't make sense for them to be static. You can do something like this:
public AbsClass {
protected final int blah;
protected final int blah2;
protected AbsClass(int blah, int blah2) {
this.blah = blah;
this.blah2 = blah2;
}
. . .
}
public class Impl1 extends AbsClass {
public Impl1() {
super(CONSTANTS.impl1_blah, CONSTANTS.impl1_blah2);
}
}
public class Impl2 extends AbsClass {
public Impl1() {
super(CONSTANTS.impl2_blah, CONSTANTS.impl2_blah2);
}
}
Polymorphism in Java don't work with attributes. Use some protected abstract getMethods() instead.
First of all this is final+static which means nothing to do with OOP, If you make them not static then It makes sense to talk about OOP on it. If you do not do them as private and access them using getters/setters then you are breaking encapsulation.
And you are making it final, means it can be initialized only once. You will get exception when you try to change the value of final attr.
I am designing a text-only videogame with two characters not often seen together, yet very much alike in heart and disposition.
My problem is that I don't know how to initialise an enum constant through a constructor using a static final inner constant. Otherwise the game is good to go. ;)
Here's the dilemma:
The enum constants must be defined in the first line of the enum, if I am not mistaken
The first line can't refer to anything coming after it (i.e. "cannot reference a field before it is defined")
How do I resolve this catch-22?
Here some sample code released from the game under non-disclosure agreement:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(TYPICAL_QUOTE_FROM_MARIO), ZELDA(TYPICAL_QUOTE_FROM_ZELDA);
private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
public String getQuoteUnderStressfulCircumstances() {
return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
}
private ValiantHeroWithPrincessSavingTendencies(String quote) {
aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote;
}
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
I am trying to initialise SUPERMARIO using TYPICAL_QUOTE_FROM_MARIO but I haven't defined TYPICAL_QUOTE_FROM_MARIO yet. Moving the private static final field before SUPERMARIO is illegal, I think.
The only viable options are to either a) move your constants to another class or b) just put your constants directly into the value initializers.
If you move your constants, you can make the class a static class in the enum:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(Quotes.TYPICAL_QUOTE_FROM_MARIO),
ZELDA(Quotes.TYPICAL_QUOTE_FROM_ZELDA);
private String aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
public String getQuoteUnderStressfulCircumstances() {
return aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive;
}
private ValiantHeroWithPrincessSavingTendencies(String quote) {
aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive = quote;
}
private static class Quotes {
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
}
You can just access them via class name:
enum ValiantHeroWithPrincessSavingTendencies {
SUPERMARIO(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_MARIO),
ZELDA(ValiantHeroWithPrincessSavingTendencies.TYPICAL_QUOTE_FROM_ZELDA);
...
private static final String TYPICAL_QUOTE_FROM_ZELDA = "Have at ya!";
private static final String TYPICAL_QUOTE_FROM_MARIO = "We, wagliu'!";
}
It's simplier than Brian's solution
The private static final constants are local to the enum; just code them in the instance definitions. After that point they can be accessed internally from the aPreparedQuotePurportedToBeSpontaneousAlmostImpulsive variable.
You could always do something hacky like this:
public enum Derp
{
SOMETHING(),
SOMETHINGELSE();
private String herp;
public static final String A = "derp", B = "derp2";
public String getHerp()
{
return herp;
}
static
{
SOMETHING.herp = A;
SOMETHINGELSE.herp = B;
}
}