简体   繁体   中英

Implementing a class that calls interface methods?

I'm really searching for the answer to this. I want to create a generic piece of code that just walks a directory tree. Maybe it's just a static class that contains one method. No problem for that. For each file that is not a directory, it does something . I thought that defining an interface for this something was the thing to do (I call it FileActionInterface.performAction() for now), but I'm not sure how to code the directory walker code to call this interface method (which doesn't exist yet). I've seen and used other Java classes that have a method that says "add Interface handler()" then that class will run your implemented interface. If you drop nothing in, nothing happens.

Sorry about grasping for the right words here. How do I code this directory walker code to call the abstract code?

PS All of these are good answers and I've marked them as such. How do they do it when a class has a "addInterfaceHandler()" like method to the class? I'm guessing that the class has it's own implementation of the interface, but it's empty possibly. Then when you call the add() method you either replace the class' implementation or add to it like an array of interface implementations.

I'll start trying out your different solutions.

You would pass in an object implementing said interface.

The walking method would call the method on that object.

Similar to how Files.walkFileTree works with FileVisitor .

Very roughly:

public class Walker {
    private Visitor v;
    public Walker(Visitor v) { this.v = v; }
    public walk(File dir) {
        // pseudo-code
        for (File f : dir.getFiles()) {
            if (f.isDir()) {
                walk(f);
            } else {
                v.performAction(f);
            }
        }
    }
}
class DirIterator

  interface Callable
    method callback(file) // abstract
  end interface 

  method iterate (dir, callable) {
    for each file in dir
      if (file is Folder) then iterate(file, callable)
      else callable.callback(file)
  }

  // example use
  method main() {
    callable = new Callable{callback(file) {print(file.name)}}; // specify cb for this iteration
    dirIterator.iterate("root_dir_to_iterate/", callable); // start iteration
  }
end class

As a simple static method:

static public walkTree(File dir, Visitor vis) {
    for(File fil: dir.getFiles()) {
        if(fil.isDirectory()) { walkTree(f,vis);      }
        else                  { vis.performAction(f); }
        }
    }

(assuming that Visitor has a performAction method.)

You'd write two types. The first is an interface, that declares a method someone has to implement if they want to use your walker.

public interface FileAction {

  void perform(File file) throws IOException;

}

The other is the walker itself:

public final class FileWalker {

  public void scan(File directory, FileAction action) throws IOException {
    if (!directory.isDirectory())
      throw new IllegalArgumentException("Not a directory.");
    File[] sub = directory.listFiles();
    if (sub == null)
      throw new FileNotFoundException("Failed to list directory contents.");
    for (File f : sub) {
      if (f.isDirectory())
        scan(f, action);
      else
        /* This is where you invoke the implementation of the interface. */
        action.perform(f);
    }
  }

}

Your user would implement the interface you declared. It can do whatever they need in it's implementation of the perform() method, which will be called by your file walker:

final class SizeCalculator implements FileAction {

  private long total = 0;

  @Override
  public void perform(File file) {
    total += file.length();
  }

  long getTotal() {
    return total;
  }

}

Then they'd use their object and your object together:

final class Test {

  public static void main(String[] argv) throws IOException {
    SizeCalculator sizer = new SizeCalculator();
    FileWalker walker = new FileWalker();
    File cwd = new File("");
    walker.scan(cwd, sizer);
    System.out.printf("Directory contains %d bytes.%n", sizer.getTotal());
  }

}

If you are using Java 7, and your application is actually walking a file tree, you should use the NIO.2 API to walk the file tree. Here, the interface to be implemented is the FileVisitor interface declared by the core Java libraries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM