I have a superclass that I would like to forward a static method called getInstance() to all subclasses.
When creating an instance of a subclass, I then register the instance in the superclass (perhaps using a hashtable, where the key is based on getClass()). Then, I wish to use the aforementioned static method ( getInstance ) where the superclass method will return the instance of the correct type.
For example, I have a superclass A, and a subclass B extends A.
I want to write a static method A.getInstance(); when called from B (B.getInstance()), I would like it to return the instance of B that I stored earlier.
Its kinda hard to explain, but I am going to be using this superclass a lot, and I would rather not code a getInstance method into every single subclass.
How would I go about doing something like this?
edit: I just realized that my question may be misconstrued as creating a NEW instance of the object. I have already created the instance, and i wish to get the existing instance of the class
As many others have noted in the comments, what you are trying to do is not possible with static methods. Also, you should try to avoid static methods whenever possible because they can result in a testing and maintanance nightmare (*).
You named your method "getInstance", so I guess what you want to do is a mix of Factory- and Singleton patterns. Here is some information to get you started about these patterns:
Singleton: http://en.wikipedia.org/wiki/Singleton_pattern
Factory Method: http://en.wikipedia.org/wiki/Factory_method_pattern
Abstract Factory: http://en.wikipedia.org/wiki/Abstract_factory
Both should not be coded by hand in these days (*) - Have a look at a good "Dependency Injection" (DI) container like Google Guice or Spring. I am not 100% sure what exactly you want to achieve, but it looks like a DI container will do it for you.
Edit: This is a response to an edit of the question. You want to receive a cached instance of the sub classes. In this case, I would still advise against static methods. You could create a singleton instance of a "BCache" class (using a DI container or programming it by hand), and then use this cache object to look up your registered objects. Using Guice as a DI container, it could look like this (warning, untested):
#Singleton
public class BCache {
private Map<Class<? extends B>, B> cache = ...;
public <T> T getInstance(Class<? extends T> type) {
return (T) cache.get(type);
}
}
I still think it would be possible to get rid of the cache class completely using a DI container, though. Again, this is untested code, using Guice, but it could look like this:
#Singleton
public class A extends B {
public A() {
//I am not sure if you need to register in this case, because your
//DI container keeps track of the singleton instances.
super.register(this);
}
}
public class SomeClassUsingA {
#Inject private A a;
}
(*) Note that "all generalizations are wrong", that is, in some projects it might make sense, but in most it will not.
You can't do exactly what you want with the static methods, in good OOP way. You can can do something with the reflection or bunch of if .. else if.
You however, should use some well defined design patterns like Abstract fectory or Factory method. This is the way you should go, like someone said "Don't invent warm water".
You can always assign a subClass instance to a superClass reference. Therefore your superClass's static methods can set or get a subClass instance. But make sure to cast the returned instance before using.
public class A {
private static A a;
/**
* #param a the a to set
*/
public static void setA(A a) {
A.a = a;
}
/**
* #return the a
*/
public static A getA() {
return a;
}
public class B extends A {
private int index = 0;
/**
* #param index the index to set
*/
public void setIndex(int index) {
this.index = index;
}
/**
* #return the index
*/
public int getIndex() {
return index;
}
Usage:
public static void main(String[] args) throws Exception {
B b = new B();
A.setA(b);
B c = (B) A.getA();
System.out.println(c.getIndex());
}
Change form getInstance() to getInstance(String class)
in the superclass:
public static A getInstance(String class){
if(class.equals("A")){
RegisterObject(...);//User defined method
return new A(...);
}
else if(class.equals("B")){
RegisterObject(...);//User defined method
return new B(...);
}
else if(class.equals("C")){
RegisterObject(...);//User defined method
return new C(...);
}
//... and so on
}
Static methods are cannot know which class is used to invoke them. If for example you have class A and B that extends A and static getInstance() implemented in A there is no difference whether you invoke getInstance() using A or B. Moreover attempt to call B.getIntance() will produce compilation warning (at least in Eclipse).
However you can pass the class as a parameter of getInstance():
public class A {
public static <T extends A> T getInstance(Class<T> clazz) {
return clazz.newInstance(); // I do not catch exceptions here: do it yourself
}
}
public class B extends A {
}
...............
B b = A.getInstance(B.class);
You can do like this way,
class A{
public static A getInstance(){
return new A();
}
#Override
public String toString() {
return "inside A";
}
}
class B extends A{
public static A getInstance(){
return new B();
}
#Override
public String toString() {
return "inside B";
}
}
inside main :
public static void main(String[] args) {
A a1 = A.getInstance();
A a2 = B.getInstance();
System.out.println(a1.toString());
System.out.println(a2.toString());
}
Related
I am working on an API which interface with a proprietary piece of hardware. In this API, I have constructed a utility class (for the sake of this post let's call it B), consisting of only static methods. Most of these methods depend on another class for communicating with the hardware, let's call this A. I am currently a little unsure how to design the dependency of B on A as I cannot instantiate B and inject the dependency using constructor injection. From a design perspective, what is the best way to model this behavior?
For a little more hands-on description, here is what I am trying to achieve. Let's say A has declarations of certain other classes like so
class A
{
private HardwareCommunicator communicator;
private ModelLoader modelLoader;
public HardwareCommunicator getCommunicator()
{
return communicator;
}
public ModelLoader getModelLoader()
{
return modelLoader;
}
}
And B then has static methods like so, which seek to use some of the members declared in A
class B
{
public static PerformOperation()
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, hardwareCommunicator.getCommunicator()); // Needs reference
}
}
Obviously, B needs a reference to A, so I am currently fiddling with passing the dependency as an argument to the method, like this:
class B
{
public static PerformOperation(HardwareCommunicator communicator) // Passed as argument
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, communicator.doSomething()); // OK, so far so good
}
}
Now I run into the problem that I sometimes need more dependecies than just the communicator in B, e.g. in another static method in B I might need both the HardwareCommunicator and the ModelLoader
class B
{
public static SomeOtherOperation(HardwareCommunicator communicator)
{
AnotherClass c = new AnotherClass();
c.SomeMethod(someValue, communicator.doSomething(),
ModelLoader.getModelLoader()); // Missing reference
}
}
OK, so I could just pass this as a parameter as well, but now I am thinking I have an architectural problem. I should (shouldn't I?) be able to just go
class B
{
public static SomeOtherOperation()
{
AnotherClass c = new AnotherClass();
c.someMethod(someValue, instanceOfA.getCommunicator(),
instanceOfA.getModelLoader());
}
}
Without being able to call a constructor on B and pass in an instance of A I obviously can't achieve this behavior.
What am I missing? Thank you.
Since Java 8, we are able to define static and default methods in interface. But I need to ensure a public static method say foo() to be implemented in all the classes that implements a particular interface say interface A. How do I do that , or is it at all possible ?
The interface A:
package com.practice.misc.interfacetest;
public interface A {
public static Object foo(); //Eclipse shows error : 'This method requires a body instead of a semicolon'
String normalFunc();
}
Class B :
package com.practice.misc.interfacetest;
public class B implements A{
#Override
public String normalFunc() {
return "B.normalFunc";
}
//I need to ensure that I have to define function foo() too
}
Class C :
package com.practice.misc.interfacetest;
public class C implements A{
#Override
public String normalFunc() {
return "C.normalFunc";
}
//I need to ensure that I have to define function foo() too
}
Edit 1:
Actual case :
I have one public static method getInstance() (returning Singleton instance of that class) in all the implementing classes, and I want to ensure all the future classes other developers write must have that static method implemented in their classes. I can simply use reflection to return that instance by calling the getInstance() method from a static method of the interface, but I wanted to make sure that everyone implements the getInstance() in all the implementing classes.
static methods from interface are not inherited (1). They are inherited in case of a class, but you can not override them (2); thus what you are trying to do is literally impossible.
If you want all classes to implement your method, why not simply make it abstract (and implicitly public) to begin with, so that everyone is forced to implement it.
Eugene already pointed out that static methods can not be overridden. I suggest that you extract the singleton behavior to a separate interface. For example:
public interface A {
String normalFunc();
}
public class B implements A {
#Override
public String normalFunc() {
return "B.normalFunc";
}
// TODO add getInstance for singleton
}
public interface Singleton {
// TODO extensive javadoc to describe expected singleton behavior
A getInstance();
}
public class BSingleton implements Singleton {
#Override
public A getInstance() {
return B.getInstance();
}
}
Finally you can use any object of type BSingleton to get the singleton object of B.
I'm a begginer programmer for Android and I found some code over the internet and I couldn't get what this "Class not meant to be instantiated" means?! Also what's the use of it. I would be very happy if somebody could help here.
public class Settings
{
//some code
private Settings() {} // Class not meant to be instantiated
//some code
}
The constructor is private so only the class itself can create instances. There are several reasons for doing this. A couple off the top of my head...
The class is a "utility" class that only contains static methods and so instantiating it would make no sense. As the class is commented "Class not meant to be instantiated" I guess this is the most likely reason.
The class itself controls its own lifecycle and provides methods for creating instances. For example if the class is a lazy singleton it might provide a method that creates an instance when first called and return this instance on subsequent calls.
It is a private constructor. This means that outside classes cannot create new instances using the default constructor.
A little more info
All Objects in Java have a default constructor:
public MyObject() {}
That is how you can have this class:
public class MyObject{}
and still be able to call:
MyObject mObj = new MyObject();
Private Constructors
Sometimes a developer may not want this default constructor to be visible. Adding any other constructor will nullify this constructor. This can either be a declared constructor with empty parameters (with any of the visibility modifiers) or it can be a different constructor all together.
In the case above, it is likely that one of the following models is followed:
The Settings object is instantiated within the Settings class, and is where all the code is run (a common model for Java - where such a class would also contain a static main(String[] args) method).
The Settings object has other, public constructors.
The Settings object is a Singleton, whereby one static instance of the Settings Object is provided to Objects through an accessor method. For example:
public class MyObject {
private static MyObject instance;
private MyObject(){}//overrides the default constructor
public static MyObject sharedMyObject() {
if (instance == null)
instance = new MyObject();//calls the private constructor
return instance;
}
}
This inner construct
private Settings() {}
is a constructor for Settings instances. Since it is private, nobody can access it (outside of the class itself) and therefore no instances can be created.
The constructor is private so its not meant to be called by anything outside of the class
It's not a nested class, it's a constructor. A private constructor means that you can't construct instances of this class from outside, like this:
Settings s = new Settings(); //Compilation error! :(
Now, if a class can't be instantiated, what could it be for? The most likely reason for this is that the class would return instances of itself from a static method, probably as a singleton. The settings are normally global to the program, so a singleton pattern really fits here. So there would be a static method that goes kind of like this
static private TheOnlySettings = null;
static public getSettings()
{
if(TheOnlySettings == null)
TheOnlySettings = new Settings(); //Legal, since it's inside the Settings class
return TheOnlySettings;
}
See if that's indeed the case.
As other have mentioned, a class having private constructors cannot be instantiated from outside the class. A static method can be used in this case.
class Demo
{
private Demo()
{
}
static void createObjects()
{
Demo o = new Demo();
}
}
class Test
{
public static void main (String ...ar)
{
Demo.createObjects();
}
}
We can have private constructor . Below program depicts the use of private constructor with a static function
class PrivateConstructor {
private:
PrivateConstructor(){
cout << "constructor called" << endl;
}
public:
static void display() {
PrivateConstructor();
}
};
int main() {
PrivateConstructor::display();
}
Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO
So here's the scenario.
I have a class A, and I want some of its methods to behave differently depending on how the class is called.
What I've done now is something like this:
interface Interface{
public void someMethod();
}
class A{
int variable;
Interface getA1(){
return new A1();
}
Interface getA2(){
return new A2();
}
class A1 extends A implements Interface{
public void someMethod(){
variable++;
}
}
class A2 extends A implements Interface{
public void someMethod(){
variable--;
}
}
}
Now the problem with this is that when getA1() or getA2() is called, it will actually return a completely new instance of A1, or A2, where the int variable is totally separate to the parent class A (duh, silly me of course thats how it works).
So the question is. Is it possible in java to return some kind of inner class that allows you to modify the data within the outer class through it's methods?
The key thing is having a single class that can return interfaces that modify that single class in different ways, depending on which method was used to create that interface.
I might be overlooking something simple here, sorry but it's got me stumped! :(
Edit: I think the better way of explaining it is - I want to give direct access to local variables, to a subclass (or another class), and have a method in the original class that can create the other class.
EDIT2: The reason why it created a separate instance when getA1()/getA2(), is likely because class A1 and A2 were declared to extend A. It seems like if the extends clause is removed, then it works as expected.
Yes an anonymous class would do e.g.
interface Interface{
public void someMethod();
}
public class A {
int variable;
Interface getA1() {
return new Interface() {
#Override
public void someMethod() {
variable++;
}
};
}
}
It should be pointed out though that this is equivalent to declaring non-static inner classes albeit more concise.
First of all, I find it very strange that your inner classes are extending the outer class. I can't think of a good reason to do that and I'm not exactly sure what that even does.
Besides that, I don't understand your issue. All inner classes have access to their parent class's fields. For example, the following:
public class Tester {
private int myInt;
public InnerTester getInnerTester() {
return new MyInnerTester();
}
public InnerTester getOtherInnerTester() {
return new OtherInnerTester();
}
public interface InnerTester {
public void doStuff();
}
public class MyInnerTester implements InnerTester{
#Override
public void doStuff() {
myInt++;
}
}
public class MyOtherInnerTester implements InnerTester {
#Override
public void doStuff() {
myInt++;
}
}
public static void main(String[] args) {
Tester tester = new Tester();
System.out.println("Before: " + tester.myInt);
tester.getInnerTester().doStuff();
tester.getOtherInnerTester().doStuff();
System.out.println("After: " + tester.myInt);
}
}
outputs:
Before: 0
After: 2
However, this all seems pretty shady. I'm not exactly sure why you would want to take advantage of this behavior. I've done similar things with action listeners before, but I wouldn't exactly call their parent object an "ActionListenerFactory". Why don't you just have a method to increment the field on the object itself?