4

I defined an interface IPersistent that has two methods load and save. Using these methods I can load or save the implementing class using whatever method they want.

public interface IPersistent {
    void save();
    void load(int id);
}

What I want now, is to implement a deleteAll method, but it would have to be a static method, as it acts on class level, rather than object level. I tried using a static method in the interface, but that is not possible, as I would need to implement it in the interface, instead of any implementing class.

Typical usage would be something like this:

class Foo implements IPersistent {
   void load(int id) { ... }
   void save() { ... }
   static void deleteAll() { ... }
}

List<foo> fooList = ...;
Foo.deleteAll();
for (Foo f: fooList) {
  f.save();
}

How would I implement this?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195

3 Answers3

2

You should have an abstract class instead of an interface, and make all of the classes utilizing deleteAll() extend that class.

Lawrence Aiello
  • 4,560
  • 5
  • 21
  • 35
2

As static method can't be overridden, your idea is quite complex to implement in Java.
I think about an other way, using generic static method and annotations.

public final class PersitenceTools {
  public static <T extends IPersistent> void deleteAll(Class<T> clazz) {
    // stuff
  }
}

You could use it like this: PersistenceTools.deleteAll(Foo.class).
Note: Since Java 8, you can put this method in the IPersistent interface, if you want to avoid creating a tools class.

You will probably need some information about Foo (or other IPersistent object) in deleteAll. And you can use the power of annotations for this purpose !

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PersitenceInfo {
  String info1();
}

Finally, you will be able to decorate Foo

@PeristenceInfo(info1="Foo")
public class Foo implements IPersistent {
  // stuff
}

And get this information in deleteAll through clazz.getAnnotation(PersistenceInfo.class).info1().

NiziL
  • 5,068
  • 23
  • 33
  • I am trying to implement this, but I get a `null` on `clazz.getAnnotation(PersistenceInfo.class)` – Bart Friederichs Apr 10 '15 at 09:03
  • @BartFriederichs Oh sorry ! I forget the `@Retention(RententionPolicy.RUNTIME)` on the annotation, to make it available at runtime ! I also added `@Target` to ensure this annotation is only available for class, interface or enum. – NiziL Apr 10 '15 at 09:13
  • Well this would work, but its not that OOP like, Avoid Util/Tools classes. @Lawrenace Aiello s answer – Zarathustra Apr 10 '15 at 09:42
  • @Zarathustra which was my first incling as well, but `abstract static` is not allowed. – Bart Friederichs Apr 10 '15 at 09:44
  • @Zarathustra Actually, OP want a static function (because `instance.deleteAll()` has no sense), so using an abstract class isn't a good solution for this pupose (moreover, I always promote interfaces over abstract classes). I also think about a solution using a template method pattern, but still hard to implements with static function... – NiziL Apr 10 '15 at 09:51
-1

Follow the java SE convention as seen in:

Path path = Paths.get("...");
File file; ... Files.copy(...);
Collection colxn = ...; Collections.sort(colxn);

In your case that would be a utility class with static methods:

public class Persistents {
    private Persistens() {}
    public static void deleteAll() { ... }
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138