"abstract static" method

Discussions

EJB design: "abstract static" method

  1. "abstract static" method (20 messages)


    Ok, I may have run into what apparently some consider to be a limitation of the java language, based on converstations I read on the sun forum. So, I thought I'd post this question here and see if I get a good response since this seems to be a more knowledgeable forum.

    I really have a need for an abstract static method. Obvously, those aren't allowed. Here's what I need to do.

    I want to create an abstract factory called "DataModelFactory" that lays a blueprint for, for example, "ProductModelFactory" and "InventoryModelFactory" I want to have DataModelFactory call a static descendant method called "buildModel" that is static - can't do it.

    Any ideas?? I really want these factory methods to be static of course, and of course since an abstract class is calling a descendant class, the decending method must be abstract.

    I challenge anyone to come up with a solution to this scenario... come on I dare you to give me a solution that fits the need to this (hopefully this tactic will work! :) Thanks

    Threaded Messages (20)

  2. "abstract static" method[ Go to top ]

    What about using a singleton pattern? This is often used to get around non-overridable static methods. The behavior and application is similar, but instead of calling ClassName.staticMethod() you would call ClassName.getInstance() (which could return a static instance, thus acting in a "static" way), and then call your pseudoStaticMethod on what's returned from getInstance(). You can then add abstract non-static methods to the class, which would be available for other classes to override.
  3. "abstract static" method[ Go to top ]

    Are you sure it's best to organize your class hierarchy this way (i.e. Product and Inventory both extending from Data)? Maybe using composition over inheritance would be a safer approach (even if you do decide to use a Singleton).

    I'm not sure I would call not being able to override statics a "limitation." It's the logical soln. ;)
  4. "abstract static" method[ Go to top ]

    I'm not having product extend from "data" I want to have productfactory extend from datafactory. Each one will be responsible for creating objects of a model type, that model representing a record in a database basically. ANd yes, I see absolutely nothing wrong with doing it that way. The only problem is Java doens't allow you to require decendent classes to implement a static method. Smalltalk doesn't have that limitation.

    I thought about using a singleton, and I could probably do it that way although I haven't actually tried it, but that's more complicated than just simply declaring a static method; that's so much simpler than writing a properly-threaded singleton.

    Thanks
  5. "abstract static" method[ Go to top ]

    I don't think I thoroughly understand your problem but have you considered making static buildModel() in DataModelFactory provide a default implementation that throws an exception. Although, the derived class that fails to provide an implementation for buildModel() will compile, you will get a runtime exception when you try to invoke it.
  6. "abstract static" method[ Go to top ]

    "I don't think I thoroughly understand your problem but have you considered making static buildModel() in DataModelFactory provide a default implementation that throws an exception. Although, the derived class that fails to provide an implementation for buildModel() will compile, you will get a runtime exception when you try to invoke it. "

    Hi David.

    The problem I'm trying to solve is very straight-forward. I want to define a class as a factory, and have decendants of that class. You can't do that, because you can't inherit the "build" method because it's static. Basically I want to create a framework of factories. ProductFactory extending DataFactory etc. all having a common "populate" method that is also static.

    I could use a singleton, but that seems like alot of trouble when all I need is to inherit a static method, which I can't.

    Thanks
  7. "abstract static" method[ Go to top ]

    Derived classes can and do inherit static methods from their base classes. Derived classes can not override inherited static methods but they can hide them. When you hide a static method the decision on which static method to call (base or derived) is made at compile time based on the type of the variable used in the invocation. This means a variable of type DataModelFactory will never be able to invoke the static buildModel() method defined in any of the classes derived from DataModelFactory.
    Why do you want buildModel() to be static?
  8. "abstract static" method[ Go to top ]

    "Derived classes can and do inherit static methods from their base classes."

    No, that isn't true. Abstract static won't even compile.

    "Why do you want buildModel() to be static? "

    Because that's the typical way you code an object factory; there's no need to create multiple instances of a factory because all it does is churn out other objects. The other typical way to do it is with a singleton, but that's more work than simply declaring a static method in a class that has a private constructor and thus can't be instantiated.
  9. "abstract static" method[ Go to top ]

       "Derived classes can and do inherit static methods from their base classes."
    "No, that isn't true. Abstract static won't even compile. "

    Tracy,
        I'm not sure how this behaves in Smalltalk, but I definitely will have to agree with David in this regard. You CAN compile both the abstract parent and the child classes. As David has rightly pointed out, you will not be over-riding the static method, but you will be hiding the static method when you implement it in the child class.
    Thanks,
    Sunil
  10. "abstract static" method[ Go to top ]

    "Tracy,
        I'm not sure how this behaves in Smalltalk, but I definitely will have to agree with David in this regard. You CAN compile both the abstract parent and the child classes. As David has rightly pointed out, you will not be over-riding the static method, but you will be hiding the static method when you implement it in the child class.
    Thanks,
    Sunil "

    This is easy to resolve. Try compiling this:


    public abstract class test {
       public abstract static void m() {
       }
    }

    This is the error you get (per JBuilder):

    "test.java": Error #: 216 : illegal combination of modifiers: abstract and static at line 6, column 32

    You can't have a static method that is abstract; it doesn't work in Java. That's what I'm trying to do; enforce that subclasses define a method with a ceratin signature, but defer the implementation. It can't be done.

  11. "abstract static" method[ Go to top ]

    Hows this??

    ::::::::::::::
    A.java
    ::::::::::::::

    public abstract class A
    {
      public static void fn() { System.out.println("A::fn()") ;}
    }
    ::::::::::::::
    B.java
    ::::::::::::::
    public class B extends A
    {
      public static void fn() { System.out.println("B::fn()") ; }
      
      public static void main(String args[])
      {
        A.fn() ;
        B.fn() ;
      }
    }

    output is
    A::fn()
    B::fn()
  12. "abstract static" method[ Go to top ]

    "Hows this?? "

    I'm not sure what your code snipet has to do with anything. That isn't an abstract static method. You aren't forcing decendants of that class to provide implementation for a method that you then use in the abstract class.
  13. "abstract static" method[ Go to top ]

    maybe u shd consider using interfaces.
  14. "abstract static" method[ Go to top ]

    "maybe u shd consider using interfaces"

    No, you can't have an interface with an abstract static method in an inteface either. In fact you can't even have a static method.

    Also, I need an abstract class because the class actually has alot of implementation in it.
  15. "abstract static" method[ Go to top ]

    Tracy,

    I think the bottom line is that Java is not Smalltalk, and you will need to use a Singleton. I don't think it adds very much complexity:

    You want:

    abstract class DataModelFactory
    {
      private static abstract buildModel(); // illegal
      ...
      public static DataModel create()
      {
      ... buildModel() ...
      }
    }

    class PMF extends DataModelFactory
    {

      private static buildModel()
      {
        ...
      }
    }

    and your client says:

      DataModel = PMF.create();

    Is that about right?

    So with a Singleton we have:

    class DataModelFactory
    {
      private abstract buildModel();
      ...
      public DataModel create()
      {
      ... buildModel() ...
      }
    }

    class PMF extends DataModelFactory
    {
      private PMF{} // private constructor to enforce single instance

      private buildModel()
      {
        ...
      }

      private static PMF s_theInstance = null;
      public static synchronized PMF getInstance()
      {
        if (s_theInstance == null)
        {
           s_theInstance = new PMF();
        }
        return s_theInstance
      }
    }

    and your client says:

      PMF.getInstance().create();

    If you want to add some syntactic sugar you could put a method in PMF:

      public static DataModel create()
      {
         return getInstance().create();
      }

    So this means 10-15 lines of extra code in each concrete factory class.

    Read comp.lang.java.advocacy if you want to hang out with other bitter ex-Smalltalk programmers :-)

    Tom
  16. "abstract static" method[ Go to top ]

    Wah, wah, wah... j/k Yeah I could do it that way. It's counter-intuitive to having to do that, I wish I could just inherit an abstract method just like any other method. THanks for the input.
  17. "abstract static" method[ Go to top ]

    You can do this:

    class SingletonFactory
    {
      private static HashMap s_singletons = new HashMap();
      public static synchronized
        Object getSingleton(Class clazz)
      {
        DataModelFactory f =
         (DataModelFactory)s_singletons.get(clazz);
        if (f == null)
        {
          f = (DataModelFactory)clazz.newInstance();
          s_singletons.put(clazz,f);
        }
        return f;
      }
    }

    class PMF extends DataModelFactory
    {
      ...
      public static PMF getInstance()
      {
        return (PMF)SingletonFactory.getSingleton(PMF.class);
      }
    }

    Which is less typing, but might be slower.

    Tom
  18. "abstract static" method[ Go to top ]

    Another note Mani... in your example, the static method in class b is NOT "inheriting" the method from class a, or even overriding it. In fact, class A and class B BOTH have a totally different "class" method that don't have anything to do with each other. In other words, you can't say this in class B:

      public static void fn() {

         super();
         System.out.println("B::fn()") ;
    }

    That wouldn't work. Again, they each have their own "class" method. You actually still have the same, separate methods in each class.
  19. "abstract static" method[ Go to top ]

    12222
  20. "abstract static" method[ Go to top ]

    The only solution in Java is to use a singleton. I know what you really want, but this is Java after all, not Smalltalk. Java static methods do not participate in inheritance (ie. override) unless invoked from the instance side of things. That's why they don't allow "abstract static", which sort of implies overriding, which isn't supported.

    You can hide the use of the singleton through static methods, of course, so maybe that would make it more palatable to you. But you can't get the classes to behave like inherited class methods in Smalltalk.
  21. "abstract static" method[ Go to top ]

    Johnathon, that's been my findings as well. It's too bad, I'd really like to do it in this situation and seems very clean. cya