3

I'm trying to refactor my code by using a BaseComponentType class and inheriting from this in my ElectricalComponentType class (and similar child classes), as follows:

BaseComponentType.java

public abstract class BaseComponentType {

    public static BaseComponentType findByUid ( Class klass, String uid ) {

        return new Select().from( klass ).where( "uid = ?", uid ).executeSingle();

    }

}

ElectricalComponentType.java

public class ElectricalComponentType extends BaseComponentType {

    public static ElectricalComponentType findByUid( String uid ) {

        return (ElectricalComponentType) findByUid( ElectricalComponentType.class, uid );

    }

}

What I need to do is call ElectricalComponentType.findByUid( 'a1234' ) but it would be great if I did not have to define findByUid in the ElectricalComponentType class and instead could inherit this functionality from the BaseComponentType.

You'll notice that two things stand in the way:

  1. I need the ElectricalComponentType class in the findByUid parent method.

  2. I need to return ElectricalComponentType object (or whatever the child class object is) instead of a BaseComponentType class object.

Is there a way to do this?

7
  • 2
    What do you mean by 'remove' the findByUid method? You can't just delete that? And your abstract class does not seem to have any abstract methods, so you don't 'have to' override anything. What is the motive here? Commented May 3, 2014 at 17:08
  • If you don't need the findByUid method in your ElectricalComponentType, then why did you program it there? I daresay the best way to remove it is never have programmed it in the first place. Commented May 3, 2014 at 17:10
  • You may want to take a look here: stackoverflow.com/questions/10291949/… or at any of the other ones on the right that talk about static methods and inheritance. Commented May 3, 2014 at 17:15
  • By "remove", I mean that I would like to not have to define it in the ElectricalComponentType model, but I still need to do ElectricalComponentType.findByUid( 'a433' ). I'll update the question a little bit. Commented May 3, 2014 at 17:17
  • @JoshPinter You're not required to override any methods except the abstract ones (which you didn't define in the sample). Commented May 3, 2014 at 17:20

4 Answers 4

7

Use generics and only have the parent class method:

public abstract class BaseComponentType {
    public static <T extends BaseComponentType> T findByUid(Class<T> klass, String uid) {
        return new Select().from( klass ).where( "uid = ?", uid ).executeSingle();
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

So the formatting of this is pretty special, requiring <T extends BaseComponentType> T. Do you have a link I can read up on this more?
Glad you like it. For more info, start with official docs. If you need more google "java generic methods" or "java typed methods"
Thanks. One last thing, is it possible to determine the child class programmatically so I can remove the Class<T> klass function param?
If the from() method requires a class object of type T (which is highly likely), then "no" there is no way to avoid passing the class object, because due to runtime type erasure you can't create a class object of type T at runtime.
0

There are several points to note:

  • static methods are not being inherited and cannot be overriden;
  • To call static method of your parent class, you have to write class name first: BaseComponentType.findById();

If you want to get rid of method with the same name in child class, you may want to make it non-static or/and reconsider your classes design, because if you have two static methods with the same names in classes bound with inheritance relation, most likely there is something wrong with class design.

Comments

0

i hope you need something like following..

public class TestClass{
    public static void main(String args[]){
        Child c2;
        c2 = (Child) Child.findByUid(Child.class, "123");
        System.out.println(c2.getClass());
    }            
}

class Base{
    public static Base findByUid ( Class klass, String uid ) {
        System.out.println(klass);
        Child c = new Child();
            //execute your query here and expect it to return the type of object as the class by which it was called
        //your parent class method always returns the type of the child by which the method was called
        return c;

    }

}

class Child extends Base{
    /*public static Child findByUid( String uid ) {
        System.out.println(Child.class);
        return (Child) findByUid( Child.class, uid );

    }*/
}

Comments

0

I think you could reengineer this so that you have a ComponentFinder class that finds Components.

public class ElectricalComponent extends Component {

     @Override
     public void method1(){
         //specific stuff
     }

}

public abstract class Component{
     public abstract void method1();
}

public class ComponentFinder{

    public static Component findByUid ( Class klass, String uid ) {

        return new Select().from( klass ).where( "uid = ?", uid ).executeSingle();

    }

}

Then you don't have to worry about the inheritance issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.