In Java, Is there a way to enforce the implementations of my interface are singletons? I have interfaces that I want to ensure are implemented by classes with a single instance - is this something I can do with abstract classes?
Edit: more context
I am implementing a framework that defines a platform interface that I need only instance of, per implementation since it is going to be used a lot.
I can show you a dirty trick there:
static public abstract class SingletonAbc {
static private final HashSet<Class<?>> mInstancedClasses = new HashSet<>();
public SingletonAbc() { // CTOR should be thread-safe imo, check that to be sure
final Class<?> c = getClass();
System.out.println("Checking Class: " + c.getName());
if (mInstancedClasses.contains(c)) throw new IllegalStateException("Damn, cannot instantiate the class " + c.getName() + " twice!");
else mInstancedClasses.add(c);
}
}
static public class Ext1 extends SingletonAbc {}
static public class Ext2 extends SingletonAbc {}
static public class Ext1Ext1 extends Ext1 {}
static public class Ext1Ext2 extends Ext1 {}
public static void main(final String[] args) {
new Ext1();
new Ext2();
new Ext1Ext1();
new Ext1Ext2();
new Ext2(); // <= bam! exception!
}
But keep in mind that might not be the best solution. Factors like multithreading and reflection might kill this approach.
Related
I'm reading a book "Thinking in Java" that states the following about inner classes:
Each inner class can independently inherit from an implementation. So one way to look at the inner class is as the rest of the solution of the multiple-inheritance problem. Interfaces solve part of the problem, but inner classes effectively allow "multiple implementation inheritance". That is, inner classes effectively allow you to inherit from more than one non-interface.
I've never used inner classes like that. So I started to thinking about how this could look and where this can be useful. I came up with this:
public class ReadWriteCollection {
public static void main(String[] args) {
var rw = new ReadWriteCollection();
var ro = rw.new ReadPart();
var ao = rw.new AddPart();
ao.add("foo");
System.out.println(ro.read(0));
}
private List<String> list = new ArrayList<>();
class AddPart extends AddOnlyCollection {
void add(String s) { list.add(s); }
}
class ReadPart extends ReadOnlyCollection {
String read(int index) { return list.get(index); }
}
public abstract static class ReadOnlyCollection {
final void someExistingImplementation(){ System.out.println("Foo"); }
abstract String read(int index);
}
public abstract static class AddOnlyCollection {
final void someExistingImplementation(){ System.out.println("Bar"); }
abstract void add(String s);
}
}
ReadOnlyCollection and AddOnlyCollection represent some existing implementations that I can't control. I've put them inside ReadWriteCollection just for convenience in my example.
So is it how inner classes should be used for "multiple implementation inheritance"? Can somebody give more examples and possible usages for this technique? Or is it the way inner classes were used in the past and no longer used like this (the book is quite old)?
I guess the idea of the author is the following to by-pass the multi inheritance restriction in Java:
public class A {}
public class B {}
public class C {}
public class MainTest {
private AA aa;
private BB bb;
private CC cc;
public static void main(String[] args) {
AA aa = new AA();
BB bb = new BB();
CC cc = new CC();
}
private static class AA extends A {
}
private static class BB extends B {
}
private static class CC extends C {
}
}
With that you have extended three different classes inside your MainTest.
For a project, I have written the following interface:
public interface IManipulation {
void applyManipulation (double value);
}
Since I would like to force all implementing classes to use a certain constructor signature, I have been considering to change the interface into something like the following abstract class:
(edit: I forgot that it's not possible to have an abstract constructor, so I changed the "solution" below a bit)
public abstract class Manipulation {
private Signal signal;
public Manipulation (Signal signal) {
this.signal = signal;
}
public abstract void applyManipulation (double value);
protected Signal getSignal () {
return signal;
}
}
The reason for wanting to force this constructor is because every implentation should have an instance of Signal available. (and it should not be possible to reassign this signal)
Is this a valid reason to replace the interface with an abstract class (and live with the limitations that come with it), or are there any other potential solutions?
instead of an abstract class you should use an init method for that purpose.
public interface MyInterface{
public void init(YourParam p);
//... other methods
}
in the init you check, if the class is allready initialised if yes, just return.
So you have still an interface and can extend from other classes.
Instead of the constructor you will call the init method for your initialization
EDIT:
public interface IManipulation {
void init(Signal s);
void applyManipulation (double value);
}
You should use abstract classes only, if you have implementation details in it, which are shared by all subclasses. For Method signatures use interfaces
You can make empty constructor private in the abstract class:
abstract class AbstractManipulation {
private final Integer signal;
private AbstractManipulation() {
signal = null;
}
public AbstractManipulation (Integer signal) {
this.signal = signal;
}
}
class Manipulation extends AbstractManipulation {
public Manipulation(Integer signal) {
super(signal);
}
// Cannot redeclare
//public Manipulation() {
//}
}
Then:
public static void main(String[] args) {
// Will not work
//Manipulation m = new Manipulation();
// This one will
Manipulation m = new Manipulation(1);
}
You should not choose for technical reasons but rather logical, ie an abstract class is used when you have a realtion with the sub-classes like for example person: student, teacher. An interface is used when you want to impose a service contract for classes that may not have a relationship between them.
I have following classes (note that methods are static):
class Base
{
public static void whosYourDaddy()
{
Class callerClass = // what should I write here to get caller class?
System.out.print(callerClass.getName());
}
}
Class A extends Base
{
public static void foo()
{
A.whosYourDaddy();
}
}
Class B extends Base
{
public static void bar()
{
B.whosYourDaddy();
}
}
And when I call:
A.foo();
B.bar();
I'd like to get output:
AB instead of BaseBase. Is it even possible with static methods (in Java 7)?
What you can do, but shouldn't :) is use the Throwable getStackTrace method. Aside from the smell, this is pretty slow, because getting the stack trace isn't that fast. But you will get an array of StackTraceElement, and each one will contain the class of teh class that is calling it (and you can also get the file and line, and if you separate the two with a : you can get a clickable link in eclipse, not that I'd ever do such a thing...).
Something like
String className = new Throwable().getStackTrace()[1].getClassName();
Hope that helps :)
private static class Reflection {
private static final SecurityManager INSTANCE = new SecurityManager();
static Class getCallClass() {
return INSTANCE.getCallClass(2);
}
private Reflection() {
}
private static class SecurityManager extends java.lang.SecurityManager {
public Class getCallClass(int i) {
Class[] classContext = getClassContext();
if (i >= 0 && i + 1 < classContext.length) {
return classContext[i + 1];
}
return null;
}
};
}
Is it even possible with static methods (in Java 7)?
No, Static methods aren't inherited. Only non-static methods are inherited.
In your case change Base (and subclasses) as follows:
class Base
{
public void whosYourDaddy()
{
Class<?> callerClass = getClass();
System.out.print(callerClass.getName());
}
}
I was trying to develop an interface and that interface will contain static class
class C1 {
static interface I // A static interface or class can contain static members.Static members can be
//accessed without instantiating the particular class
{
static class C2 {
}
}
public static void main(String a[]) {
C1.I.C2 ob1 = new C1.I.C2();
System.out.println("object created");
}
}
But my query is that can interface contain classes which are not static and if yes , then how their object would be created , please advise. Thanks
Can an interface contain classes?
Yes. For example, in
interface Widget {
static class Factory {
static Widget create() { return new Widget() {}; }
}
}
the inner class can be accessed as
Widget w = Widget.Factory.create();
so to refer to the inner class you can just use the interface name then a dot then the inner class name
import my.pkg.MyInterface;
...
MyInterface.InnerClass ic = new MyInterface.InnerClass();
I want to define a base class that defines a main method that instantiates the class, and runs a method. There are a couple of problems though. Here is the base class:
public abstract class Strategy
{
abstract void execute(SoccerRobot robot);
public static void main(String args)
{
Strategy s = new /*Not sure what to put here*/();
s.execute(new SoccerRobot())
}
}
And here is an example derived class:
public class UselessStrategy
{
void execute(SoccerRobot robot)
{
System.out.println("I'm useless")
}
}
It defines a simple execute method, which should be called in a main method upon usage as a the main application. However, in order to do so, I need to instantiate the derived class from within the base class's main method. Which doesn't seem to be possible.
I'd rather not have to repeat the main method for every derived class, as it feels somewhat unnessary.
Is there a right way of doing this?
Move the main method out into a separate class. Separate concerns
Strategy (the name says it all)
Launcher (assembling components together and triggering execution)
public class Launcher
{
public static void main(String args)
{
Strategy s = new UselessStrategy();
//OR Strategy s = CreateInstance(args[0]) ;
//OR equiv mechanism for Dependency Injection if you don't want to hardcode the derived strategy to use.
s.execute(new SoccerRobot())
}
}
Static methods, such as "main", are not inherited but can be called directly. As a workaround, you could parameterize the class name as an argument to the main method:
public static void main(String args) throws Exception
{
String className = (args.length > 0) ? args[0] : 'UselessStrategy';
Strategy s = (Strategy) Class.forName(className).newInstance();
s.execute(new SoccerRobot())
}
If Class.forName is not possible, then maintaining a mapping of class names can provide a lookup table, per Andreas_D's comment:
private static Map<String, Class<? extends Strategy>> STRATEGY_NAME =
new HashMap<String, Class<? extends Strategy>>();
static {
STRATEGY_NAME.put("Useless", UselessStrategy.class);
STRATEGY_NAME.put("Better", BetterStrategy.class);
}
public static void main(String args[]) throws Exception {
String className = (args.length > 0) ? args[0] : null;
Class<? extends Strategy> klass = STRATEGY_NAME.get(className);
if (klass == null) klass = UselessStrategy.class;
Strategy s = klass.newInstance();
s.execute();
}
Automated methods for maintaining the mapping could be devised, such as using reflection, if the need arises.
You can define the class in a static block in the subclass.
public abstract class Strategy
{
protected static Class<? extends Strategy> instanceClass;
abstract void execute(SoccerRobot robot);
public static void main(String args)
{
Strategy s = instanceClass.newInstance()
s.execute(new SoccerRobot())
}
}
and then
public class UselessStrategy extends Strategy
{
static {
instanceClass = UselessStrategy.class;
}
void execute(SoccerRobot robot)
{
System.out.println("I'm useless")
}
}
You cannot instantiate an abstract class, but you definitely can instantiate a derived class from the base class. So just remove abstract from class definition
public class UselessStrategy
and do
Strategy s = new UselessStrategy();
I'd rethink this.
Put the code that you'd like executed somewhere else, preferably a non-static method, and call that. main() shouldn't be used this way.
I'd recommend creating a separate Strategy class in lieu of main.
Where is the main method called from? If it takes arguments then you can decide a concrete strategy based on those arguments, instantiate that strategy class and call the execute method on it.