Overcome duplicated methods static reference on super - java

We all know that in Java, if you declare a static method in a Abstract class, that method will belong to the Abstract class, and not to its child. (There is no abstract static)
I have a simple database system that has a Abstract Model class:
public abstract class Model<T> {
// WON'T WORK (unfortunately I can't use abstract static)
public static T find(int id) {
...
}
}
As you can see, I can't create a static method on that class that returns a generic, since that method is not inherited, so it belongs to the abstract class.
A workaround is to make a protected method on the abstract class and then a static method on each of its children:
public abstract class Model<T> {
protected T find(int id) {
...
}
}
public class User extends Model {
public static User find(int id) {
User dummy = new User();
return (User) dummy.find(id);
}
}
I feel that there are better ways of doing that.
Any ideas?

I can think of two possible options, although one is a bit of a hack. The first one would be to make Model<T> a normal class and adding a static method to get the model like this:
//I do not know how you want to do the user class, I just made it take the models class
private static final Model<User> MODEL = new Model<User>(User.class);
public static Model<User> model() {
return MODEL;
}
You would use it like this: User.model().find(id)
Another option would be to add a public static variable to the class and static importing that variable to invoke methods on it as if it were the class and not the Model instance. For example:
public class User {
public static Model<User> User = new Model<User>(User.class);
}
Importing it using static import my.package.User.User; would allow you to use User user = User.find(id); where the first User is the class name and the second User is the static variable.
Otherwise, you will have to put the static methods in each class, because unfortunately you cannot inherit or override them.

You could use a static generic method with a type that extends the parent class. You will, however, need an instance of the type in order to do the return of type T. The easiest way is to pass in the caller, but it could just be an empty instance.
For example, you can do the following:
//No more generic Model
public abstract class Model
{
//Our generic static method; we need caller to get something of type T to return.
public static <T extends Model> T find(int id, T caller)
{
...
return caller.getMyReturnObject(id);
}
}
To invoke this you would just do
Model model = find(someId, new Model{...})
where new Model{...} can be replaced by this if you invoke it within a class that is a child of Model.
If you need to create a new instance of T in the method, then you will still need to pass in something as T (the caller still works) and use reflection to create the new instance (using something like (T) type.getClass().newInstance(); instead of new T()).

Related

Is there a way to return current class type in a final method?

I have the following situation in java; There is a class that implements a method that is meant to be final but I need the returning type of such method to be exactly that of the class that it calling it. Since I want the method to be final I can't modify the return data type in the subclasses since that would be illegal.
Is there a way to archive this without sacrificing finality and having to override such method for all subclasses that implement it?. Even if the method was not final it would still be faster to implement it this way.
The code would be something like this:
class Parent
{
public currentClass finalMethod() {...}
}
class Children extends Parent {}
public static void main(String args[])
{
Children c = new Children();
System.out.print(c.finalMethod().getClass().getName()); // Would print Children
}
Tried to use reflection and generics to no avail. Examples:
class Parent
{
public this.getClass() finalMethod() {...} //Many Errors
public <extends Parent> finalMethod() {...} // Returns Parent even if called by Child
public Class<? extends Parent>[] getVecinos() // Returns Class<? extends Parent> thus can't use polymorphism which is the use case
}
I know I could use casting but still not the best solution.
The default behavior is that you'll get what you're looking for, as long as finalMethod does not generate new instances using other types.
To use your code:
class Parent {
public final Parent finalMethod() {
return this;
}
}
With that, c.finalMethod().getClass().getName() returns Children. That's because this inside finalMethod() is the same object that was created using new Children() and getClass() returns the runtime class of the object.
That uses inheritance and as long as you can work with Parent as the return type, you should be fine. If, however, your objective is to call methods specific to Children on the return value of finalMethod(), you may need to make Parent generic. Something like this:
class Parent<C extends Parent<C>> {
public final Parent<C> finalMethod() {
//whatever
return this;
}
}
class Children extends Parent<Children> {
}
And that would make the following code valid, still producing the same output:
Parent<Children> c = new Children(); //or Children c = new Children();
System.out.print(c.finalMethod().getClass().getName());
This has the advantage of allowing you to make static reference to Child-specific methods without prior casting. But it's not the right solution unless it's okay to make Parent generic. It's also not fail-safe.

What is the best practice in Java to set a constant required in subclasses?

I have the following situation:
A parent class has a function that depends on a constant. But the only valid place to define that constant is in subclasses (parent class cannot define the constant's value, but it can be used with the constant undefined in 99% of use cases - the constant is a default to use if a specific configuration element is missing).
However, I would like to enforce that any child class inheriting from that parent class must define the value for the constant, since any child classes have to be able to use the other 1% of functionality.
What is the best practice to implement this enforcement in Java, ideally at compile time? (clearly, at runtime, I can simply check if the constant is null/empty in the method using it).
My own solution was to implement a value-getter for the constant as an abstract method in the parent class, and call that in combination with the real setter in the constructor; something like this:
public class HelperClass1 {
private String myConstant;
public void setMyConstant() {} // implemented obviousy
public void myMethod() { // Called from ParentClass's methods
// Do something useful with myConstant
}
}
import HelperClass1;
public abstract class ParentClass {
ParentClass() {
HelperClass1.setMyConstant( getMyConstantValue() );
}
public abstract void getMyConstantValue();
}
public class ChildClass1 extends ParentClass {
public void getMyConstantValue() { return "BUZZ"; }
}
public class ChildClass2 extends ParentClass {
} // Fails to compile without getMyConstantValue()
However, (a) This implementation has a problem (I can't use ParentClass itself, since it's now abstract) without subclassing; and (b) since I'm not a Java developer, I'm afraid that this isn't the best or the most elegant solution. So I'd like to know if there's a best practices approach that improves on what I implemented.
Provide two constructors for the parent class:
One is a protected constructor which takes the constant as an argument.
The other is private constructor which can construct instances of the parent class without setting the constant.
Provide a factory method for the parent class which can call the private no-constant constructor.
Classes that want to get an instance of the parent class can call the factory method. But child classes that want to inherit from the parent class have to call the protected constructer, which can validate that a valid constant was passed.
public class ParentClass {
private final SomeClass myConstant;
protected ParentClass(SomeClass aConstant) {
if (null == aConstant) {
throw new IllegalArgumentException("...");
}
myConstant = aConstant;
}
private ParentClass() {
myConstant = null;
}
public static ParentClass getInstance() {
return new ParentClass();
}
}
public class ChildClass {
public ChildClass() {
super(new SomeClass(42));
}
}
This isn't perfect. Someone could write a child class that passes a bad constant to the superclass constructor, and it wouldn't actually fail until some code tried to construct an instance of the child class.

How to design a common static method in all classes implementing an interface

I have an interface called Relation, implemented by a class BasicRelation, and extended by subclasses (e.g. ParentChild, Sibling, Spouse). While developing my code, I realized that I often need a method which takes a String representation of a relation to create it. For example:
public class ParentChild implements Relation extends BasicRelation {
// e.g. "Jack is Emily's father. Jill is her mother." will return the list
// <ParentChild(Jack, Emily), ParentChild(Jill, Emily)>
static List<ParentChild> fromSentence(String s) {
...
}
}
Now, since I find myself needing this method (fromSentence(String)) in every class, except perhaps in BasicRelation, I would like to move it up the hierarchy. The problem is that the internal details of the method is subclass-dependent, so I can't have it as a static method in the interface Relation or the superclass BasicRelation.
Unfortunately, in Java, it is also not possible to have a static abstract method.
Is there any way to ensure that every subclass of BasicRelation (or every class implementing Relation) implements fromSentence(String)? If no, should I be designing this in a completely different way? I guess this last question is more of a request for design-advice than a question.
Why does the static method need to be in the interface? What's stopping you from having a 'Utility' class and having the method in there?
public class RelationUtility {
public static BasicRelation relationFactory(String asString) {
....
}
}
As a static method, there is no reason other than access to private members, which can also be accomplished by by 'default' permissions on those members....
You can try making the BasicRelation class an abstract class and use an abstract fromSentence(..) method. This would require the ParentChild class to override and implement the fromSentence method because you can't create an object for ParentChild without implementing fromSentence()
public abstract class BasicRelation extends Relation(){
public abstract List<..> fromSentence(String s);
}
public class ParentChild implements Relation extends BasicRelation {
fromSentence(){
//parentChild class's implementation
}
}
If I understood right... you can try an approach like this
public class BasicRelation {
public abstract List<ParentChild> fromSentenceInSubclass(s);
public List<ParentChild> fromSentence(String s){
fromSentenceInSubclass(s);
}
}
And then you could have:
public class SubclassRelation extends BasicRelation {
public List<ParentChild> fromSentenceInSubclass(s){
// do subclass relation stuff
}
}
You will probably need to change the code a bit and add some Generics around to make it happen the way you want.
Sotirios Delimanolis Factory suggestion might also be an option.
You can have the abstract class BasicRelation include the static method which throws an Exception. That way you will be forced to override (shadow) the static method in the subclasses when you use it.
Something like:
public abstract class BasicRelation {
public static List<..> fromSentence(String s) {
throw new RuntimeException();
}
}

protected static member for inherited class

I have a few classes that all inherit the same base class and need to have a static property that is initialized in a function at startup. I implemented it this way:
public abstract class Base {
protected static Model model;
}
public class Inherited extends Base {
static {
model = initializationFunction();
}
}
public class OtherInherited extends Base {
static {
model = otherInitializationFunction();
}
}
// Example of use
Base[] inheriteds = new Base[] { new Inherited(), new OtherInherited() };
for (int i = 0; i < inheriteds.length; i++) {
doStuff(inheriteds[i]).model; // This will always use the same model (last defined)
}
So the class initializes the static member at start. But it appears that it sets the value of model for the whole base class, and so all classes actually have the same model.
I need model to be static because the it needs to exist only once per subclass. My problem is how to have one static model per subclass, while still ensuring it is defined in the parent class (so if a class doesn't define it, it is defined in the parent class).
What is the expected behaviour of a protected static member in an inherited class? And how should I go about having my version of this member for each class, still static (I don't want it to duplicate for each instance)?
My problem is how to have one static model per subclass, while still
ensuring it is defined in the parent class (so if a class doesn't
define it, it is defined in the parent class).
No way, Because, static members and polymorphism, inheritance don't go together
Inheritance does not work for static fields (i.e. class fields). So there is only one single field Base.model. Inherited.model refers to the same field.
If you really need the resolution of the model to be automatic instead of having the devoloper ensure consistency, then you need to implement the whole mechanism yourself because no language feature of Java will take care of that directly.
One of the options is going down the Singleton route, where the singleton would be the Model factory. Instead of accessing the static field directly to get the model, you would ask the respective class's factory singleton to get it. The factory itself would subclass the base factory, so then you can get the "automatic default" behavior by polymorphism.
As other answers have suggested, static members are scoped at the class level and not at the object level, and in short are not part of inheritance hierarchies whatsoever. The class name for a static member is just an extra namespace qualifier. Here is a pretty good synopsis on the static keyword: http://mindprod.com/jgloss/static.html
As for solving your problem, I took a crack at this while still using static members. If you really must have each instance of a subclass share the same model instance while maintaining some kind of interface compatibility with the base class then consider doing something like the following:
public abstract class Base {
public abstract Model getModel();
}
public class Inherited extends Base {
static private Model model = initializationFunction();
public Model getModel() {
return model;
}
}
public class OtherInherited extends Base {
static private Model model = otherInitializationFunction();
public Model getModel() {
return model;
}
}
The fact there are static members involved here is hidden from the interface, which is a big win all around. If you reach the point where you can solve this problem without using static members, the clients of your class hierarchy here will not be affected since accessing a model does not expose the implementation detail of the use static members at all.
Maybe managing the model objects somehow:
public abstract class TestBase {
private static Map<Class, Object> modelObjects = new HashMap<>();
public static void setModel(Class _class, Object model) {
modelObjects.put(_class, model);
}
public static Object getModel(Class _class) {
return modelObjects.get(_class);
}
public static class Inherited extends TestBase {
static {
setModel(Inherited.class, new Object());
}
}
public static class OtherInherited extends TestBase {
static {
setModel(OtherInherited.class, new Object());
}
}
}

Instantiate an object from a dynamically generated class

I am currently trying to achieve something like this:
Based on this class, I try to create a new instance of the class Class<? extends AbstractValidator> returned by the method getValidator().
public abstract class AbstractEnumDefinition
extends AbstractRequestFieldDefinition {
private Vector<String> values = new Vector<String>();
public abstract void define(String lang);
protected void addEnumDefinition(String value){
values.add(value);
}
public Vector<String> getValues(){
return values;
}
#Override
public Class<? extends AbstractValidator> getValidator() {
return new AbstractValidator() {
#Override
public boolean isValid(String value) {
return values.contains(value);
}
#Override
public String getDefaultValue() {
return "";
}
}.getClass();
}
}
Say I create this class:
public class LanguageDefinition extends AbstractEnumDefinition {
public LanguageDefinition() {
super();
}
#Override
public void define(String language) {
addEnumDefinition("BEL-fr");
addEnumDefinition("BEL-nl");
addEnumDefinition("BEL-en");
}
}
Later in my code, I call
new LanguageDefinition().getValidator().getConstructor().newInstance()
The class I am trying to instantiate here is not declared anywhere, but "generated dynamically"/"dynamically created" within the AbstractEnumDefinition class.
When trying to do this, I get an java.lang.InstantiationException for
be....servlets.model.extraction.filter.editor.AbstractEnumDefinition$1
I guess this is due to the fact that this Class has to be explicitly created before hand, and not referenced dynamically?
Is there some kind of solution that would allow me to not have to write one class per validator?
Thanks for the help,
Eric
I can only make assumptions since i don't see the code where you are actually using the class, but you should check: http://docs.oracle.com/javase/6/docs/api/java/lang/InstantiationException.html
One thing it mentions is the instantiation can fail is the class is an abstract class (perfectly logical since you can't instantiate abstract classes).
Also, i don't see why you need to return the class and then create and object. Why not just define a Validator Interface and have your method return a Validator object.
That does not work for anonymous classes as far as I know, you have to convert your class to a named inner class:
But even that will not work, properly because you might not have a default constructor. Inner classes get implicit constructor arguments to keep the reference to the enclosing class. Unfortunately Closures do not work so well in static languages.
In summary inner classes that are non-static can not be instantiate outside of an instance of the enclosing class.

Categories

Resources