I want to define a class with a constructor that takes an enum as a formal argument (so only arguments which conform with the enum type can be passed). Here's what I have (generalised as I'm doing college work and don't want to plagiarise):
public class EnumThing
{
private SomeConstant aConstant;
private enum SomeConstant {CONSTANT1, CONSTANT2, CONSTANT3};
public EnumThing(SomeConstant thisConstant)
{
this.aConstant = thisConstant;
}
// Methods
However when I try
EnumThing doodah = new EnumThing(CONSTANT1);
I get an error: cannot find symbol - variable CONSTANT1
This is my first attempt to use enums for anything at all. They seem excitingly powerful but it seems like I'm using them wrong. Any help hugely appreciated!
First of all, you need to make the enum public otherwise you cannot access it outside of the class EnumThing:
public class EnumThing {
public enum SomeConstant {CONSTANT1, CONSTANT2, CONSTANT3}
// ...
}
Then, access the members of the enum correctly:
EnumThing doodah = new EnumThing(EnumThing.SomeConstant.CONSTANT1);
Full working example (note that the correct usage is: SomeConstant.CONSTANT1):
public class EnumThing {
private SomeConstant aConstant;
private enum SomeConstant {CONSTANT1, CONSTANT2, CONSTANT3}
public EnumThing(SomeConstant thisConstant) {
this.aConstant = thisConstant;
}
public static void main(String[] args) {
EnumThing doodah = new EnumThing(SomeConstant.CONSTANT1);
}
}
Note that you can use a private enum. But it will only be accessible within your class (EnumThing).
Related
I'm trying to achieve the following:
I have a parent class, with some logic. In the child class, I "redefine" constants/properties. Is there any way to make the child properties accessible by methods defined in the parent class? Or to be more specific - is there any way to force the "out" method to write extended rather than base in the following example?
public class BaseTest {
public static final String x = "base";
public void out() {
System.out.println(x);
}
}
public class ExtendedTest extends BaseTest{
public static final String x = "extended";
}
public class Main {
public static void main(String[] args) {
BaseTest base = new BaseTest();
ExtendedTest extended = new ExtendedTest();
base.out(); // base (as expected)
extended.out(); // base (extended expected)
System.out.println(extended.x); // extended (as expected)
}
}
I come mainly from the world of PHP, where this approach works just fine. Dunno if I'm missing something or if the very design of Java does not allow this.
Thank you.
Note: This is not important whether the property is static or not. I just wanted to be able to override a property of any kind in a child class (just like I can override a method) which, on basis of the answers I've received so far, doesn't seem to be possible in Java. In PHP it is absolutely possible and that was why I asked the question.
static fields are not subject to inheritance. The x in the body of the out() method refers to BaseTest.x. Since you are not overriding out(), the body of the out() method still prints the value of BaseTest.x.
Static members are resolved at compile-time, and adding an ExtendedTest.x does not affect the also-existing BaseTest.x, which is what the BaseTest#out() method is linked to.
To accomplish what you're wanting, you need an overridden method:
public class BaseTest {
public String x() {
return "base";
}
public final void out() {
System.out.println(x());
}
}
public class ExtendedTest extends BaseTest {
#Override
public String x() {
return "extended";
}
}
This pattern is commonly used with an abstract method in the base class or interface to require the subclass to define an attribute such as a name or a key.
How can static fields of some superclass be protected from alteration (for example in main method), while keeping this possibility via setters in subclasses. As far as i know, making it private won't make the job, because private static fields are not a part of subclasses. Only thing I can excogitate
is making them protected and include those classes (without main class) in a package.
Is there a simplier solution?
class Main{
public static void main(String[] args){
Foo.precious = "nothingness";
}
}
class Foo{
static String precious = "Precious data";
}
class Bar extends Foo{
Foo.precious = "More precious";
}
And if I add a private modifier to the precious in Foo class, then I will protect it from main(), however lose the ability to change it in subclass as well.
There is no access modifier that makes a member/static/method visible to a subclass but not the package.
This is taken from Oracle Documentation
When a subclass is expected to override its super class' behviour, you have to stick to the OOD rules: You'd better make them variables non-static so that the subclasses can re-define them and override its public getters:
class Foo{
private String precious = "Precious data";
public String getPrecious() { return precious; }
}
class Bar extends Foo{
private String precious = "more precious";
#Override
public String getPrecious() { return precious; }
}
class Main{
public static void main(String[] args){
Foo.precious = "nothingness"; // Compilation error: field precious is not visible.
Foo.setPrecious("x"); // Compilation error: No such public method.
}
}
I have a class with a method that takes a single parameter. This parameter is a nested class inside the mocked class, but it is private (And static but I don't think that makes much of a difference to this). How do I go about mocking this method?
Example:
public class myClass {
public anotherObject;
public myClass(AnotherObject anotherObject) {
this.anotherObject = anotherObject;
}
public void exec() {
//Some instructions ...
//This second method is inside another completely seperate class.
anotherObject.secondMethod(new NestedClass());
}
private static class NestedClass {
public NestedClass() {
//Constructor
}
//Variables and methods, you get the picture
}
}
In the above example secondMethod(...) is the method that I want to mock.
All attempts to find other examples of this problem just return results relating to mocking a single private nested class, or mocking static classes, which aren't completely relevant to this and don't seem to provide any work around that I can figure out.
EDIT:
I'm looking for some sort of solution that looks like this:
#Test
public void testExec() {
AnotherObject anotherObject = mock(AnotherObject.class);
when(anotherObject.secondMethod(any(NestedClass.class))).thenReturn(0);
MyClass testThisClass = new MyClass(anotherObject);
}
Notes: I'm not allowed to make modifications to the code I'm afraid, I am only allowed to create these tests to make sure the current implementation works later down the line when modification are made to it.
If I am understanding the requirement correctly, add one method say executeSecondMethod(). Call this method in your main method class.
public class myClass {
public void exec() {
//Some instructions ...
secondMethod(new NestedClass());
}
public void secondMethod(NestedClass example) {
//Some instructions that I want to just mock out...
}
private static class NestedClass {
//Variables and methods, you get the picture
}
public static executeSecondMethod(){
secondMethod(new NestedClass()); // pass the nested class object here
}
}
public class mainClass{
public static void main(){
executeSecondMethod();
}
}
What's wrong with below enum declaration? I want to write a singleton enum, so declared INSTANCE.
I get errors - "misplaced construct(s)"
public enum demo {
INSTANCE;
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
private int code;
private demo(int c) {
code = c;
}
private demo() { }
public int getCode() {
return code;
}
}
In order to get it compiling, just replace the ; with ,, as you haven't finished listing the constants.
Something like this:
INSTANCE,
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
However, since you want to have a singleton, I suggest to get rid of the INSTANCE value, and introduce a static member that will hold the instance:
public static Demo INSTANCE = Demo.WHITE;
You cannot declare two sets of instances within one enum class as you've done.
It isn't clear why you want an enum singleton of an enum, but if you want one INSTANCE to be a singleton, then you can declare a static variable to be one of the instances.
enum Demo {
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
public static Demo INSTANCE = WHITE;
// rest unchanged except for demo->Demo
}
It's possible to use the enum singleton pattern:
enum DemoSingleton
{
INSTANCE(Demo.WHITE);
private Demo myDemo;
private DemoSingleton(Demo demo) { myDemo = demo; }
}
But that would be useless; you could just use Demo.WHITE.
In Java we can do the following to initialize class and call method inside that class:
public class MyClass {
public String myClassMethod() {
return "MyClass";
}
}
.
public class Test {
public static void main(String[] args) {
MyClass myClass = new MyClass(); // initialize MyClass
myClass.myClassMethod();// call a method
}
}
If my class is an enum class, implementation will be the following:
public enum MyEnumClass {
INSTANCE;
public String myEnumClassMethod() {
return "MyEnumClass";
}
}
.
public class Test {
public static void main(String[] args) {
MyEnumClass myEnumClass = MyEnumClass.INSTANCE;
myEnumClass.myEnumClassMethod();
}
}
Both of these cases works in the same way, but it is said to be better in the enum implementation. My question is why and how it is happening?
An enum is essentially a singleton pattern.
The JVM handles the initialization and storage of enum instances. To see this most clearly you can write:
public enum MyEnumClass {
INSTANCE("some value for the string.");
private final String someString;
private MyEnumClass(final String someString) {
this.someString = someString;
}
public String getSomeString(){
return someString;
}
}
And in another class:
public static void main(String[] args) {
final MyEnumClass myEnumClass = MyEnumClass.INSTANCE;
system.out.println(myEnumClass.getSomeString());
}
This would print out "some value for the string.".
This demonstrates that the enum instances are initialised at class load time, i.e. as if by the static initialiser.
Or put another way:
new MyClass() == new MyClass();
Is always false, whereas:
MyEnumClass.INSTANCE == MyEnumClass.INSTANCE;
Is always true. i.e. MyEnumClass.INSTANCE is always the same MyEnumClass.INSTANCE whereas a new MyClass is created every time your call new MyClass().
This brings us nicely to your question of "better".
An enum is a singleton instance with various nifty methods for converting String enum names into a reference to the singleton instance that it represents. It also guarantees that if you de-serialize an enum there won't be two separate instances like there would for a normal class.
So an enum is certainly much better as a robust and threadsafe singleton than a class.
But we cannot have two instances of INSTANCE with the different values for someString so the enum is useless as a class...
In short enums are good for what they're good for and classes are good for what they're good for. They are not substitutes and therefore cannot be compared in any meaningful way expect when one is used as the other.
It's a simple implementation of the Singleton pattern, relying on the mechanisms of how Enum's work.
If you use MyEnumClass.INSTANCE a second time, you'll get the same object instance.
In contrast, new MyClass(); will create a new object.
See also discussion here:
What is the best approach for using an Enum as a singleton in Java?
There would possibly be more to learn by reading Java Language Spec Section 8-9