Is there any way how to automatically send notification from subclass to superclass after subclass has been fully initialized i. e. after finishing subclass constructor?
MOTIVATION
Base class has to provide some default methods that are working with list of class fields. Since subclass fields are accessible in parent class only after subclass creation, base class can't read these subclass fields in base class constructor. One solution is to read subclass fields at the begining of each base method which need to process these fields. Due of slow reflection, it is better to use lazy-initialization.
I'm curious if there is some not widely known callback mechanism in Java that will allow to define some "subclass-created-callback" so I would be able to initialize these fields without using lazy-initialization to achieve better maintainability.
I know it is possible to track deallocation of an object e. g. via finalize() or ReferenceQueue so I want to know If there is something similar for object creation.
EXAMPLE
Suppose you want to create an database Entity class (I know there are ORM based solution for this, but this is only for illustration of similar problems) which will be able to generate SQL statements like CREATE TABLE, INSERT, UPDATE, DELETE based on entity's class fields. So base class would be responsible for reading of class fields and also for producing these statements. To create an entity one would need just to extend Entity and use some field annotations like #Column, #Id, #AutoIncrement, ...
class Entity {
public String getCreateTableStatement() {
// lazy-initialize list of class fields and produce statement...
}
public String getInsertPreparedStatement() {
// lazy-initialize list of class fields and produce statement...
}
// update, delete, ...
}
Example of subclass
public Person extends Entity {
#Id public int id;
#Column public String name;
}
AIM
To replace lazy initialization be another pattern that will help to reduce amount of repeated code. Ideally, subclass would not have to define anything else, only just "extends Entity".
It is a bit unclear what you're trying to do, but in general, many problems that have to do with object creation can be solved by using a factory method that encapsulates the creational process. This way, you can do more than you can achieve in a single constructor call:
public static MySubClass createSubClass() {
MySubClass subClass = new MySubClass();
subClass.baseClassMethodThatManipulatesFields();
return subClass;
}
Note that (as others have pointed out), inheritance might not be the best solution for your problem. The methods you list in Entity should probably be at the responsibility of the factory that uses reflection for initializing the class.
I am not asking why. If you want to do exactly like in you answer, then parent object has full access to it's children via constructor. Yes, I know that child object is not fully initialized at this time, but annotation informations is available at this step.
This is an example:
import org.apache.commons.lang3.reflect.MethodUtils;
import javax.persistence.Id;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.util.ArrayList;
import java.util.List;
public class Entity {
protected Entity() {
List<AccessibleObject> ids = getAccessibleObjectWithAnnotation(Id.class);
List<AccessibleObject> columns = getAccessibleObjectWithAnnotation(Column.class);
}
private List<AccessibleObject> getAccessibleObjectWithAnnotation(Class<? extends Annotation> cls) {
List<AccessibleObject> res = new ArrayList<>();
res.addAll(FieldUtils.getFieldsListWithAnnotation(getClass(), cls));
res.addAll(MethodUtils.getMethodsListWithAnnotation(getClass(), cls));
return res;
}
}
Related
What is a class without fields called? I'm a beginner in programming Java and I'm trying to understand and learn about classes, so i have the following class "DalUser" that doesn't have fields, only methods, like validateSession in a folder called Dal:
import com.app.Be.BeUser;
public class DalUser{
public BeUser validateSession(String user, String password)
{
...
}
I have a class BeUser that has the fields user and password and is located in another folder or package called Be. is this a particular type of class or is a common class despite not having any fields?
What is a class without fields called?
There is no universally applicable name for this1:
Classes with no fields have no explicit state, but strictly speaking, every Java object has state associated its mutex. Hence calling them "stateless classes" is a bit of a stretch.
Classes with no fields may be "helper classes", but the absence of fields is neither a necessary or sufficient precondition.
An instance that has no state is also immutable, so you could call Classes with no fields an "immutable classes" ... though the locking use-case applies here too.
Another distinction between helper classes and stateless classes is whether the class is designed to be instantiated. A helper class (in normal usage) consists of static methods, and is not instantiated. (An instance serves no purpose). A stateless class is often designed to be instantiated, and passed around to other classes which will actually make method calls on the instance; e.g. as a "policy object".
Then there is a sub-case of the "base class" use-case where there are no fields in the base class. (In that case, calling the class "stateless" is misleading, since there is typically state in the child classes.)
In short, you need to examine the class and how it is actually being used to determine which label (or labels) best apply to it.
In your specific example, the code is best described as a stateless class. That is because it is designed to be instantiated and passed around in different contexts, but the functionality does not depend on any state of the object itself.
Here are some other examples to illustrate why there is no simple answer to this.
1) This is a helper class, but it has a (static) field.
public class Plumbing {
private static nosTapsFixed;
private Plumbing() { }
public class fixTap(Tap t) {
// fix 't'
}
}
2) This is a base class. It has no fields, but it is clearly not intended as a helper class.
public abstract class Tradesman {
// no fields
public abstract Invoice issueInvoice();
}
3) Here is a use of a class with no fields (java.lang.Object) in a way that is clearly not a "helper".
final Object myLock = new Object();
...
synchronized (myLock) {
...
}
4) And here is another example of a class that has no fields but is and not a helper.
public enum Agreement {
YES, NO
}
1 - But if you really want a name, how about a "villein class". Villeins didn't own any fields ....
These are called helper classes or utility classes, although the methods are usually declared static. Examples include java.util.Arrays and java.util.stream.StreamSupport. Often, they might have a pluralized name (for example, a helper class that works with Widget objects might be called Widgets.
Classes without any internal fields are stateless. A class that derives from a class with internal state (fields) would still have fields in the super class. So such a class would not be considered stateless.
Classes will often have more specific names depending on what they are used for. Your example above appears to be a validator class.
This question already has answers here:
What's the difference between importing and extending a class?
(10 answers)
Closed 7 years ago.
I have seen several threads that define extending a class as a way for a personalized class to inherit the methods of the class that it is extended to. When you import a class and create an instance of that class you have access to its methods, can someone please explain to me how extending a class to provide those methods to your own class is effectively different, in other words, the only difference I see is that when you import you create an instance of a standardized class, and when you extend you effectively turn your personalized class into the standardized class only with a different name. I am aware I am wrong, but the answers I have read have failed to help me fundamentally understand the difference.
Importing and extending are two very different things.
Importing
Classes are organized in packages, which provide a namespace facility that avoids name conflicts. Importing allows you to use the class in your code without the namespace information.
Importing is optional. You never have to import anything if you always use the fully qualified name of the class, but that makes your code hard to read.
If you want to make a list of Calendar objects, for example, you either import java.util.List, java.util.ArrayList and java.util.Calendar and use:
List<Calendar> array = new ArrayList<>();
Or import nothing and use:
java.util.List<java.util.Calendar> array = new java.util.ArrayList<>();
Sometimes you have two classes with the same name in different packages. In that case, if you use both of them in your code you can't import both. You will have to refer to one of them by their fully qualified name. For example:
List<java.awt.List> array; // you have to import java.util.List, but can't also import java.awt.List
Extending
When you extend in Java you are saying that the subclass is a type of the original class. That's the most important aspect you have to be aware of when using extends. Is you say Bus extends Vehicle you are saying that Bus is a Vehicle. You not only inherit all the non-private methods and fields of the superclass, but also can use the subclass anywhere you could legally use the superclass. For example, if you have this method:
public park(Vehicle v) {
v.drive();
v.turn(Direction.LEFT);
v.stop();
}
you could pass a Bus as an argument, because Bus is a Vehicle.
parkingLot.park(new Bus());
and the drive(), turn() and stop() methods will be called in the Bus. That is polymorphism.
Although you inherit methods, inheritance is not the best way to reuse code. Most of the time when you need to reuse code you can do it by using composition (making your class have a reference to another class, instead of being one). A Car shouldn't extend Motor because a car is not a motor, but it could have a motor and delegate a call to the motor's turnOn() method when the car's drive() method is called.
You can also have polymorphism without inheritance in Java using interfaces.
To make a simple example (but bad :/ ). Lets say you have a Person class.
public Person
{
int age;
string name;
}
Then you have different type of persons that inherit the Person class, eg.
public SoftwareDeveloper extends Person
{
string codingLanguage;
}
Now you can easily create a SoftwareDeveloper and use its attributes like this:
public static void main ()
{
SoftwareDeveloper developer = new SoftwareDeveloper();
System.print.out(developer.name);
}
If you would "import" instead, you would have to create an instance of Person in SoftwareDevelopers constructor and make it public. So your code would be to access the attribute:
public SoftwareDeveloper
{
public Person person;
string codingLanguage;
public SoftwareDeveloper(){
person = new Person();
}
}
public static void main ()
{
SoftwareDeveloper developer = new SoftwareDeveloper();
System.print.out(developer.person.name);
}
I think in small scale your reasoning works fine but the idea of extending is that your class inherits all the methods of the extended class.
But if you start with a simple idea or program and want to expand it massively the use of instantiating all the classes you need becomes much more consuming. On even a simple idea the increase in imports can explode.
Example:
Animal - warm blooded - biped - human
Animal - warm blooded - quadruped - feline - cougar - panther
Now you want to have your panther have all the methods of the 5 classes its built apoun.
So that 5 imports and objects you have to manipulate to get to all the methods you want to access. But if all these are extending each other you just have direct access to the methods. And this is a simple example now imagine a huge accounting program.
So point I trying to make....I think...Is that its much more prevalent and easier to understand the usefulness in extending classes when you look at it in the large scale.
Hope this helps or makes as much sense as it does to me.
Extending a class means that your class is "inheriting" the methods of the standard class; in other words, you are taking an existing class and building your class on top of it. That is how Java manages all objects (i.e. every class that you create actually extends the default Object class). When you import a class, on the other hand, you have access to all its functionality, but you cannot build on top of it as you could with inheritance.
Let's start with importing a class. You import a class in order to use it in another class, if that class is in another package. It's really just a shortcut that's saying when you see a class called X used, what I really mean if com.somepackage.X.
Extending is taking a class and using it as a base for a new class. There's alsorts of reasons to do this (well beyond the scope of an answer here) but the important thing is that you inherit the behaviour of the class you are extending and have the choice of whether or not to override that behaviour or add additional behaviour.
For good example of classes being extended, look at the Collection API in java.util where you can see java.util.AbstractList is extended to ultimately create two different types of list, each with different characteristics - java.util.ArrayList and java.util.LinkedList.
Lets look on an example.
We have class which provide an update function to database and containing a String variable.
public class DBupdate {
public String StrVar = "Hello";
...
public void doUpdate(String expression) {
try {
connect();
runExp(expression);
disconnect();
} catch ...
}
}
If you import it. You will do something like
log(new DBupdate.StrVar);
String myExp = "UPDATE ..."; // SQL
new DBupdate.doUpdate(myExp);
If you extend.
log(StrVar);
String myExp = "UPDATE ..."; // SQL
doUpdate(myExp);
doUpdate() function and StrVar became part of your new class. So all functions and variables (which are public or protected) are part of your new class (inherited).
Example for usefull import (and not extend/inherit) is log4j. It is doing work like writing to console and into a file. But you want just to use it "log" function and no speacial functions it is using for its work.
Example for usefull inherit is java.lang.Thread. If you class became a thread it can be treated as a Thread and will be splitted to run parallel, if you use java.lang.Thread function "start()". (Override run() method to do so some stuff...)
At the very simplest case it can be said that, Import Statement improves readability and reduces the length of the code.
In java we implement dynamic loading, language import statement no class file is loaded at the time of import statement, when ever we are suing a class, at the time of only the corresponding .calss file will be loaded.
Extends-
In Java, when we wish to extend the usefulness of a class, we can create a new class that inherits the attributes and methods of another. We don't need a copy of the original source code (as is the case with many other languages) to extend the usefulness of a library. We simply need a compiled '.class' file, from which we can create a new enhancement. I could not find a better way to explain so just refer this link..(source -http://www.javacoffeebreak.com/java104/java104.html)
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;
}
}
I have a superclass like this which I expect alot of classes to inherit:
public abstract class Super {
protected Object myField; //Not used anywhere in this class
//a load more code here which does useful stuff
}
All these classes will need to use an instance of myField. However the superclass does not. Have I made a bad design decision somewhere?
Not necessarily. If all the subclasses need the same field for the same reason, then that's no different than providing any other common functionality in a base class. as your classes grow you may find that you add common functionality which uses this field (e.g. referencing it in an equals/hashCode method).
Now, if the field is of type Object and each sub-class shoves something completely different into it, i would consider that a code smell.
Well IMHO, a field should not be present in a class if it's not really used by that class. What it seems to me that you really want here is to have a base class that tells its subclasses "you should ALL have some way of keeping state for X but I (the base class) will not modify that X state, in which case you should make an abstract method in order to convey that message, something like this:
public abstract class Super {
protected abstract Object getMyField();
}
It's hard to say with such a vague description, but it would seem like you could do some generalization and push some common code up into your superclass. If your subclasses are doing something similar with the field then some commonality could be found (using template methods or strategies to handle subclass-specific differences), otherwise if every subclass is doing something different with it then what's the point of using a common field?
No, I don't think so. Abstract class serve that purpose (Have common functionality in base class and let subclass implement only specific required functionality).
So, if you don't use that field in class Super - why do you need it there?
Perhaps your super class would provide an interface to interact with this field in generic way, for example:
public abstract class Super<T> {
protected T myField;
public T getField() {
return myField;
}
}
public class Child extends Super<String> {
public Child( String label ) {
super.myField = label;
}
}
As stated in this tuturial
A protected field or method is accessible to the class itself, its subclasses, and classes in the same package.
This means that the protected fields have been designed precisely to have these characteristics.
Just on a lighter note The only thing common in your hirarchy is one field then you should get rid of abstract class and Create one Marker Interface.
I have some Entities that look like this:
#Entity
public abstract class AbstractEntity{
#Id
private Long id;
String name;
User author;
#Lob
byte[] data;
}
public class EntityOne extends AbstractEntity{
// nothing new
}
public class EntityTwo extends AbstractEntity{
// nothing new
}
public class EntityThree extends AbstractEntity{
// nothing new
}
The byte[] defined in the superclass is the interesting part of each subclass entity. The reason I want to subclass is to enforce typing rules, as some parts of the program require EntityThree, while some parts of the program require EntityTwo. the byte[] will have completely different meaning from subclass to subclass.
It feels a little strange, because I don't expect that any of the subclasses will add any fields or methods... So i use inheritance only as a typing tool.
Is this a reasonable design? A better way to accomplish this? Does it break any best practices?
It is a good OO practice. For the database, use the SINGLE_TABLE Inheritance strategy (the default), and maybe use a custom #DiscriminatorValue per subclass, otherwise you'll get classnames in your table.
From a DBA perspective, there is no difference between this and using a single class with a property TYPE.
For OO, the subclasses can be much more usefull, e.g. you can use it to implement certain methods differently or implement the visitor or strategy pattern instead of tedious if-then-else or instanceof structures.
It's hard to say without knowing the exact use-case, but it looks like you just want to reuse the common fields in all the entities, but that no other entity will have references to AbstractEntity - only to one specific subclass. In this case, you should map the superclass with #MappedSuperclass rather than with #Entity. Each entity will have its own table, and can override the mapping defined in the mapped superclass.
Note that if I'm mistaken, and you really need an entity inheritance, using instanceof, at least with Hibernate, will cause problems, because you might have a proxy to the base class, which doesn't know yet the exact subclass the foreign key is pointing to, and which is thus not an instance of any of the subclasses.