【问题标题】:Implementing a class that calls interface methods?实现一个调用接口方法的类?
【发布时间】:2013-04-18 16:21:52
【问题描述】:

我真的在寻找这个问题的答案。我想创建一个只遍历目录树的通用代码。也许它只是一个包含一个方法的静态类。没问题。对于每个不是目录的文件,它会做一些事情。我认为为这个 something 定义一个接口是要做的事情(我现在称之为FileActionInterface.performAction()),但我不确定如何编写目录遍历器代码来调用这个接口方法(尚不存在)。我已经看到并使用过其他 Java 类,它们有一个“添加接口处理程序()”的方法,然后该类将运行您实现的接口。如果你什么都不放进去,什么都不会发生。

很抱歉在这里抓住了正确的词。如何编写此目录遍历器代码以调用抽象代码?

PS 所有这些都是很好的答案,我已经将它们标记为这样。当一个类对类有一个类似“addInterfaceHandler()”的方法时,他们是如何做到的?我猜这个类有它自己的接口实现,但它可能是空的。然后,当您调用 add() 方法时,您要么替换类的实现,要么像接口实现数组一样添加到它。

我将开始尝试您的不同解决方案。

【问题讨论】:

标签: java generics interface abstraction


【解决方案1】:

您将传入一个实现所述接口的对象。

walking 方法将调用该对象上的方法。

类似于Files.walkFileTreeFileVisitor 的工作方式。

非常粗略:

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);
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    作为一个简单的静态方法:

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

    (假设 Visitor 有 performAction 方法。)

    【讨论】:

      【解决方案3】:

      你会写两种类型。第一个是一个接口,它声明了一个方法,如果他们想使用你的walker,他们必须实现。

      public interface FileAction {
      
        void perform(File file) throws IOException;
      
      }
      

      另一个是步行者本身:

      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);
          }
        }
      
      }
      

      您的用户将实现您声明的接口。它可以在 perform() 方法的实现中做任何他们需要的事情,该方法将由您的文件 walker 调用:

      final class SizeCalculator implements FileAction {
      
        private long total = 0;
      
        @Override
        public void perform(File file) {
          total += file.length();
        }
      
        long getTotal() {
          return total;
        }
      
      }
      

      然后他们会一起使用他们的对象和你的对象:

      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());
        }
      
      }
      

      如果您使用的是 Java 7,并且您的应用程序实际上是在遍历文件树,那么您应该使用 NIO.2 API 来遍历文件树。这里要实现的接口是Java核心库声明的FileVisitor接口。

      【讨论】:

      • 我可能会使用类似 'Function' 或 Action 之类的东西而不是 'FileAction',其中接口 'Action' 有 .perform() 没有 args 或 Function 有 public O apply(I输入)
      【解决方案4】:
      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 2014-03-13
        • 2014-11-20
        • 2013-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多