I have an abstract class:
public abstract class AbstractCommand {
private static State state;
}
Intention
An object of class State is provided by some "controlling classes", providing data that is needed by each AbstractCommand subclass
Each subclass needs read access to it
The subclasses are not allowd to change the field
Current approach
The field state should be initialized by the "controlling classes" of the program so that subclasses (that define commands) can use it (read-only). The subclasses are defined internally and should be used as an interface for the user. This user should not have write access to state.
The problem
Adding a public setState() method in AbstractCommand would make it accessible to all subclasses and with that to the user
Making the field final would force the creating of the object to take place in the abstract class and the "controlling classes" would have to use this object, furthermore it would not be replacable
How do you handle something like this?
Another try
Because some answers suggested solutions using package visibility I wonder if this would do a good job:
Have a class in the same package that provides the required information by delegating a call from the "controlling classes" (from outside the package) to the abstract class.
Sounds a little fuzzy, too but what do you think?
If I understand you correctly, you are looking for the protected keyword.
In java this keyword allows for subclass and package field access, but does not make the field public. This allows for the public read-only behavior you're looking for without sacrificing the public protection of the field. The only classes that can access a protected field directly will be anything in the same package or a direct subclass (which may be in a different package).
Source: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
You could put the AbstractCommand into the same package with the "controlling classes" and specific implementations to another package. Then you could provide a package-private setter and protected getter. This would allow the controlling classes set the value and implementations would only have access to the getter.
Howevery, this would mess your package structure. If you do not want this to happen - try to use a Factory. You culd build the following package structure:
command
impl
CommandImpl1 //extends AbstractCommand
CommandImpl2 //extends AbstractCommand
AbstractCommand
CommandFactory
The idea is that a Factory is used to create instances of an AbstractCommand. So you will pass the parameter to the Factory in any other package and it would select an implementation you need and return you a new object. In this case you could use the previous idea to grant proper access to the getters and setters. However here you would be able to set the field once and forever.
If you need to modify it many times, you could create an assessor. This is the CommandAccessor class in the same package as your AbstractCommand and it should provide the static methos like:
public static void setState(State newState, AbstractCommand command);
Nothing would prevent you from using it in the implementation classes, however you could just set an informal rule that it should no be used.
I can only offer fuzzy solutions.
Some solutions first:
Either do
private static final State state = Controller.initState();
Or use inversion of controll, dependency injection, #Inject. That would allow unit tests too. There certainly are open source DI containers out there in the web (Spring, or is Pico container still around?). Or requesting beans from some DI container.
If both are too early, go for lazy evaluation (partly the initialisation of statics is already lazy). Sometimes one will see an inner class:
private static class Singleton {
private static final State state = Controller.initState();
}
Possibly with a getInstance.
My choice:
Somehow no statics, but getters to singletons. A bean frame work with controllers.
Singletons instead of statics.
Statics (static functions) where abundantly used in the prior eclipse 3 rich client, like
IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
boolean autoPrint = store.getBoolean(AUTO_PRINT);
Now alternatively with dependency injection by the OSGi container and annotations:
#Inject #Preference(AUTO_PRINT)
boolean autoPrint;
From: Eclipse 4, Rich Clients by M. Teufel and J. Helming
Besides being shorter, there is less coupling between classes, and unit tests can more easily be written, as we can fill in autoPrint like we like, and do not need to meddle with the filling class.
If one hesitates adding the overhead of such a container, the easiest way is to have alternatives to several statics is having one global application context, where you can lookup java objects, POJO beans. Maybe backed by an XML file:
State state = ApplicationContext.lookup(State.class, "state");
<bean name="state" class="org.anic.State" value="sleepy" depends="firstThis"/>
<bean name="firstThis .../>
Mind, there no longer is a need to have a static state.
The Spring framework has such an XML approach.
The advantage being a centralized initialisation, where sequence and different factory / creation methods are thinkable.
(Sorry for the messy answer.)
Pass it in as the constructor of your abstract class
public abstract class AbstractCommand {
private static State state;
protected AbstractCommand(State state){
this.state = state;
}
public State getState(){
return state;
}
}
In your extending classes...
public class Command1 extends AbstractCommand{
public Command1(){
super([some state]);
}
}
The extending class can set the state once during initialization, but has read-only access thereafter.
So I see you want the behavior as mentioned by Magus as "So you want that subclasses of AbstractCommand can't set the state value, but an other class can do it ?"
Here is my suggestion:
Create an Interface with some rules. That you want to apply in all your subclasses
Now Let AbstractCommand implement that Interface and it should also contain state variable, by doing this you can maintain a set of rule at lower level
In second leg of Interface define in step 1 have your other class that you want not to have access to AbstractCommand class variable
By doing this you can maintain your package structure. Hope this helps.
Here is what I was trying:
Create Interface as:
public interface RuleInterface {
//Define rules here
void method1();
}
Now implement this in your AbstractCommand class
public abstract class AbstractCommand implements RuleInterface{
private static String state;
}
Have other class, this class can modify state varibale
public class SubClassAbstractCommand extends AbstractCommand{
#Override
public void method1() {
}
}
Create one more leg for Interface as:
public class AnotherLeg implements RuleInterface{
#Override
public void method1() {
}
}
Now AnotherLeg class can't access state variable but still you can enforce the rules via interface RuleInterface
public abstract class AbstractCommand {
private static State state;
static {
state = Controller.getState();
}
protected AbstractCommand(){
}
public State getState(){
return state;
}
}
Related
I'm looking for best practices for the following design: I have an abstract class and every concrete class extending that abstract class should be a singleton.
Background: The concrete classes are collectors that compile and log statistics about the operation of a complex legacy system. Collectors are accessible via a static registry, so there's no need to pass dependencies. The abstract class provides the interface to the registry.
I'm aware that there's no perfect solution that gives guarantees, properties have to be maintained by conventions. Nevertheless, there might be best practices for this case.
Technically you cannot prevent the concrete class to allow the creation of more than one instance of it.
But you have ways to try to conceptually enforce it :
document clearly the interface
set a constraint that require that these subclasses be beans managed by a dependency injection container
There is a solution to implement this, it is based on the following:
The constructors of the abstract class must have private visibility, so that it could be instantiated from inside only and to prevent it from being extended elsewhere.
The implementing singleton classes must be nested within the abstract class and must not be extendable.
The instances of the implementing nested classes are static members of the abstract class.
The drawback of this approach is that it can quickly become messy, due to nesting, especially if there are many implementations for singletons.
This might look as follows:
public abstract class AbstractEntity {
public static final AbstractEntity SINGLETON1 = new EntityImpl1(); // might be also instantiated lazily
/**
* Private accessor will not allow this class to be extended from outside.
*/
private AbstractEntity() {
}
static final class EntityImpl1 extends AbstractEntity {
private EntityImpl1() {
}
}
// other implementations...
}
Here is my current solution
singleton property is managed by the registry. JavaDoc clearly states the correct and intended use
a concrete instance is registered by a static register(Instance.class, Instance::new) method that has the class object and a supplier of instances of that class as arguments
the registry maintains a map of String to instance objects, with the toString() result of the class object as key
Advantages
instances can be private and can be placed close to the classes that using them (i.e., in the same package)
instances are created once at first registry
Disadvantages
instances are created by a constructor with empty parameter list
the registry method needs two arguments
When I'm trying to compile the following code
public interface SomeInterface{
private static Logger logger = Logger.getLogger();
public default void someMethod(){
logger.info("someMethod: default implementation");
}
}
I get an error
Illegal modifier for the interface field SomeInterface.logger; only public, static & final are permitted
When I delete private modifier, code compiles, but I don't want other classes from the package to see this field.
Why Java doesn't allow me to do such thing when it actually does make sense?
In the pre-Java-8 view of the world, interfaces were purely for interface contracts, and private members exist purely for implementation, so this restriction was completely sensible.
In the post-Java-8 world, where interfaces can carry behavior (but not state), it starts to be reasonable to ask whether other features of classes should be applied to interfaces as well. (However, just because something might be "reasonable" doesn't mean it must be supported; there is often more than one reasonable way to construct the world.)
In Java 9, private methods in interfaces will be supported.
Interfaces are not classes. They have no private state. Even a public logger in the interface is a design smell and an abuse of interfaces.
The use case for static fields in interfaces is mainly for compile-time constants, not for stateful objects.
The goal of interface is to define something implemented by other classes. A private field does not define anything as it is not visible outside the interface. Hence it does not make any sense in this construct. It may be some hacks how to use it (maybe from interface inner classes) but would not look like a good design anyway.
If you actually implement part of the functionality, use abstract class instead.
Interface is like a blueprint of any class, where you declare your members. Any class that implement that interface is responsible for its definition.
Private members can only be accessed by same class member, which does not make sense in terms of interface.
Protected members can be accessed by same class member and inherited class members, but in case of interface we never extend an interface, we implement it. So any interface can only contain public methods generally,
public interface SomeInterface {
public default void someMethod() {
SomeInterfaceInternal.logger.info("someMethod: default implementation");
}
}
final class SomeInterfaceInternal {
protected static final Logger logger = LoggerFactory.getLogger(SomeInterface.class);
}
Java does not allow private or protected methods, so how do we ensure implementors of a bidirectional interface call the necessary methods?
Let's say we have an IModelListener interface as follows:
public interface IModelListener
{
public void handleChannelUpdate(int channel);
}
Then we have a ViewControl client as follows:
public class ViewControl implements IModelListener
ViewControl objects are going to work as long as we remember to have ViewControl call this:
model.registerChannelListener(this);
If Java allowed protected or private methods in an Interface, we could simply modify IModelListener to:
public interface IModelListener
{
public void handleChannelUpdate(int channel);
private void registerChannelListener( );
}
How can this be achieved?
Are there annotations that would do this?
Java does not support multiple inheritance so if Clients/Implementors are already a derived class (typical), then using an abstract class is not an option.
Thanks for helping,
Jeff
You probably miss the concept of interfaces. It can not contain private or protected methods, because the role of an interface is to provide accessible set of methods. You probably might, on the other hand, take look at abstract classes.
What you need is probably this:
public abstract class AbstractViewControler implements IModelListener {
protected abstract void registerChannelListener();
protected AbstractViewControler() {
this.registerChannelListener();
}
}
and then:
public class MyViewControler extends AbstractViewControler {
protected void registerChanelListener() {
//- Do what you need here.
}
}
and after that just:
IModelListener listner = new MyViewControler();
An interface is a way of providing a public contract to users of the class implementing the interface. How the class is implemented doesn't matter, as long as they are adhering to the contract. Therefore, it doesn't make sense to have private methods in an interface.
What you want is to enforce a default behavior on your class - in Java, abstract classes are the place to formulate default behavior inherited by all extending classes (see the template method design pattern for an application of this). Interfaces only describe, how your objects externally behave and how they can be used by others.
Interface in java intended to provide the signature of interface functionality in mean of signature that you implement in your classs so it should not to be private.
your need: you can have abstract method with some default statements that you want.
where you can have all type of access specifire.
In Java, you can't do it using an interface only.
If you want to achieve some sort of "autobinding" (i.e. call model.registerChannelListener(this); automatically on all pertinent objects), then you should have those objects implement an empty interface, retrieve the list of all the instances of classes implementing it via introspection and iterate on them.
You could do this periodically or at some specific point in the program. You could also use an #interface annotation to add a little syntactical sugar.
You might also want to invert the flow and create objects using dependency injection and/or a factory, so that you have that method called "automagically" just after creation (like with #PostConstruct).
Interfaces are the wrong place to look.
The usual solution in Java for problems like this one is to have a method in either object which returns the other:
public class ViewControl {
public IModel getModel() {...}
}
The method can then make sure that the model and the view are correctly hooked up. Now I guess that you don't really want to couple the view and the model. The solution is then to define a new ViewModel type which just delegates to the real model (most IDEs allow to create delegate types with 3-5 mouse clicks):
public class ViewControl {
public ViewModel getViewModel( IModel model ) {...}
}
You should be able to move this code to a base (abstract) view class which all views inherit from.
I have 2 classes A and B.
class A implements Constants{
private int state;
}
class B implements Constants{
foo(){
//want to set state variable of class A like this
state = state1
}
}
interface Constants{
public final int state1;
public final int state2;
}
I don't want to have an instance of class A in class B. How should I do this?
If I have a function to set the variable in the interface, then both the classes must implement this function. That would be wrong right? Because then 2 definitions for the same function would conflict?
There is nothing called functions in java. They are methods.
You can have getters and setters in your classes for the properties to set and get them from external classes.
Your question is unclear.
If your B class extends the A class, then through the constructor of the B class, you can set the properties of the A class that is the super class.
Hope it helps!
Having an interface does not mean that the variable will be shared between the classes, it is more of a way to define classes that MUST override the functions in the interface. You can read the very basics on them here. To share a variable between two classes, you can either make the variable static and put it in another class that both your classes extend (in effect a global variable, which is bad practice and not thread safe), or have one of the classes have an instance of the other and call getters/setters.
EDIT: there is a similar question here that shows you what I mean about the static variable.
You generally want to avoid writing any method in a class that attempts to alter the internal state of another class. Whatever trick you come up with to accomplish such a thing, you are breaking the principle of encapsulation which is the whole reason for using classes in the first place.
If there is some state that you wish to have accessible from multiple classes, I would recommend breaking that state out into it's own class and have each of the two classes interact with it through getter/setter or utility methods.
Why are interface variables static and final by default in Java?
From the Java interface design FAQ by Philip Shaw:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
source
public: for the accessibility across all the classes, just like the methods present in the interface
static: as interface cannot have an object, the interfaceName.variableName can be used to reference it or directly the variableName in the class implementing it.
final: to make them constants. If 2 classes implement the same interface and you give both of them the right to change the value, conflict will occur in the current value of the var, which is why only one time initialization is permitted.
Also all these modifiers are implicit for an interface, you dont really need to specify any of them.
Since interface doesn't have a direct object, the only way to access them is by using a class/interface and hence that is why if interface variable exists, it should be static otherwise it wont be accessible at all to outside world. Now since it is static, it can hold only one value and any classes that implements it can change it and hence it will be all mess.
Hence if at all there is an interface variable, it will be implicitly static, final and obviously public!!!
(This is not a philosophical answer but more of a practical one). The requirement for static modifier is obvious which has been answered by others. Basically, since the interfaces cannot be instantiated, the only way to access its fields are to make them a class field -- static.
The reason behind the interface fields automatically becoming final (constant) is to prevent different implementations accidentally changing the value of interface variable which can inadvertently affect the behavior of the other implementations. Imagine the scenario below where an interface property did not explicitly become final by Java:
public interface Actionable {
public static boolean isActionable = false;
public void performAction();
}
public NuclearAction implements Actionable {
public void performAction() {
// Code that depends on isActionable variable
if (isActionable) {
// Launch nuclear weapon!!!
}
}
}
Now, just think what would happen if another class that implements Actionable alters the state of the interface variable:
public CleanAction implements Actionable {
public void performAction() {
// Code that can alter isActionable state since it is not constant
isActionable = true;
}
}
If these classes are loaded within a single JVM by a classloader, then the behavior of NuclearAction can be affected by another class, CleanAction, when its performAction() is invoke after CleanAction's is executed (in the same thread or otherwise), which in this case can be disastrous (semantically that is).
Since we do not know how each implementation of an interface is going to use these variables, they must implicitly be final.
Because anything else is part of the implementation, and interfaces cannot contain any implementation.
public interface A{
int x=65;
}
public interface B{
int x=66;
}
public class D implements A,B {
public static void main(String[] a){
System.out.println(x); // which x?
}
}
Here is the solution.
System.out.println(A.x); // done
I think it is the one reason why interface variable are static.
Don't declare variables inside Interface.
because:
Static : as we can't have objects of interfaces so we should avoid using Object level member variables and should use class level variables i.e. static.
Final : so that we should not have ambiguous values for the variables(Diamond problem - Multiple Inheritance).
And as per the documentation interface is a contract and not an implementation.
reference: Abhishek Jain's answer on quora
static - because Interface cannot have any instance. and final - because we do not need to change it.
Interface : System requirement service.
In interface, variable are by default assign by public,static,final access modifier.
Because :
public : It happen some-times that interface might placed in some other package. So it need to access the variable from anywhere in project.
static : As such incomplete class can not create object. So in project we need to access the variable without object so we can access with the help of interface_filename.variable_name
final : Suppose one interface implements by many class and all classes try to access and update the interface variable. So it leads to inconsistent of changing data and affect every other class. So it need to declare access modifier with final.
Java does not allow abstract variables and/or constructor definitions in interfaces. Solution: Simply hang an abstract class between your interface and your implementation which only extends the abstract class like so:
public interface IMyClass {
void methodA();
String methodB();
Integer methodC();
}
public abstract class myAbstractClass implements IMyClass {
protected String varA, varB;
//Constructor
myAbstractClass(String varA, String varB) {
this.varA = varA;
this.varB = VarB;
}
//Implement (some) interface methods here or leave them for the concrete class
protected void methodA() {
//Do something
}
//Add additional methods here which must be implemented in the concrete class
protected abstract Long methodD();
//Write some completely new methods which can be used by all subclasses
protected Float methodE() {
return 42.0;
}
}
public class myConcreteClass extends myAbstractClass {
//Constructor must now be implemented!
myClass(String varA, String varB) {
super(varA, varB);
}
//All non-private variables from the abstract class are available here
//All methods not implemented in the abstract class must be implemented here
}
You can also use an abstract class without any interface if you are SURE that you don't want to implement it along with other interfaces later. Please note that you can't create an instance of an abstract class you MUST extend it first.
(The "protected" keyword means that only extended classes can access these methods and variables.)
spyro
An Interface is contract between two parties that is invariant, carved in the stone, hence final. See Design by Contract.
In Java, interface doesn't allow you to declare any instance variables. Using a variable declared in an interface as an instance variable will return a compile time error.
You can declare a constant variable, using static final which is different from an instance variable.
Interface can be implemented by any classes and what if that value got changed by one of there implementing class then there will be mislead for other implementing classes. Interface is basically a reference to combine two corelated but different entity.so for that reason the declaring variable inside the interface will implicitly be final and also static because interface can not be instantiate.
Think of a web application where you have interface defined and other classes implement it. As you cannot create an instance of interface to access the variables you need to have a static keyword. Since its static any change in the value will reflect to other instances which has implemented it. So in order to prevent it we define them as final.
Just tried in Eclipse, the variable in interface is default to be final, so you can't change it. Compared with parent class, the variables are definitely changeable. Why? From my point, variable in class is an attribute which will be inherited by children, and children can change it according to their actual need. On the contrary, interface only define behavior, not attribute. The only reason to put in variables in interface is to use them as consts which related to that interface. Though, this is not a good practice according to following excerpt:
"Placing constants in an interface was a popular technique in the early days of Java, but now many consider it a distasteful use of interfaces, since interfaces should deal with the services provided by an object, not its data. As well, the constants used by a class are typically an implementation detail, but placing them in an interface promotes them to the public API of the class."
I also tried either put static or not makes no difference at all. The code is as below:
public interface Addable {
static int count = 6;
public int add(int i);
}
public class Impl implements Addable {
#Override
public int add(int i) {
return i+count;
}
}
public class Test {
public static void main(String... args) {
Impl impl = new Impl();
System.out.println(impl.add(4));
}
}
I feel like all these answers missed the point of the OP's question.
The OP did not ask for confirmation of their statement, they wanted to know WHY their statement is the standard.
Answering the question requires a little bit of information.
First, lets talk about inheretence.
Lets assume there is a class called A with an instance variable named x.
When you create a class A, it inhereits all the properties of the Object class. Without your knowledge when you instantiate A, you are instantiating an Object object as well, and A points to it as it's parent.
Now lets say you make a class B that inherits from A.
When you create a class B, you are also creating a class A and a Object.
B has access to the variable x. that means that B.x is really just the same thing as B.A.x and Java just hides the magic of grabbing A for you.
Not lets talk about interfaces...
An interface is NOT inheretence. If B were to implmement the interface Comparable, B is not making a Comparable instance and calling it a parent. Instead, B is promising to have the things that Comparable has.
Not lets talk a little bit of theory here... An interface is a set of functions you can use to interact with something. It is not the thing itself. For example, you interface with your friends by talking to them, sharing food with them, dancing with them, being near them. You don't inheret from them though - you do not have a copy of them.
Interfaces are similar. There is only one interface and all the objects associate with it. Since the interface exists only one time as a Class (as opposed to an instance of itself) it is not possible for each object that implements the interface to have their own copy of the interface. That means there is only one instance of each variable. That means the variables are shared by all the classes that use the interface (a.k.a. static).
As for why we make them public...
Private would be useless. The functions are abstract and cannot have any code inside them to use teh private variable. It will always be unused. If the variable is marked as protected, then only an inheritor of the class will be able to use the variables. I don't think you can inhereit from interfaces. Public is the only viable option then.
The only design decision left is the 'final'. It is possible that you intend to change the shared variable between multiple instances of a class. (E.G. Maybe you have 5 players playing Monopoly and you want one board to exist so you have all the players meet the interface and a single shared Board - it might be that you want to actually make the board change based on the player functions...) [I recommend against this design]
For multithreaded applicatiosn though, if you don't make the variable static you will have a difficult time later, but I won't stop you. Do it and learn why that hurts <3
So there you go. final public static variables