当前位置: 首页 > 知识库问答 >
问题:

我怎么能覆盖基类方法使用lambda表达式在java 8?

华君浩
2023-03-14

Lambda表达式必须转换为函数接口。据我所知,他们不能扩展一个类,但我想知道是否有办法得到类似的东西。

我有java.nio.file.SimpleFileVisitor

public static void printContent(Path path) throws IOException {
    FileVisitor<Path> visitor = new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
            System.out.println(file);
            return super.visitFile(file, attrs);
        }
    };
    Files.walkFileTree(path, visitor);
}

有没有办法在lambda的帮助下删除这些代码?

我认为lambda应该是(f)-

我想过忘记SimpleFileVisitor,用默认方法创建一个等效的接口,但是,我怎么能选择要重写的方法呢?我需要离开我想要重写的方法而没有默认实现吗?在这种情况下,我需要几个接口来处理不同的情况,并使用不同的未实现方法。

非常感谢。


共有1个答案

韩麒
2023-03-14

使用委托。对于这个任务,您需要一个只实现一次的助手类:

interface IoBiFunction<T, U, R> {
  R apply(T t, U u) throws IOException;
}
class LambdaFileVisitor<T> extends SimpleFileVisitor<T> {
    IoBiFunction<T, BasicFileAttributes, FileVisitResult> preVisitDir=super::preVisitDirectory;
    IoBiFunction<T, BasicFileAttributes, FileVisitResult> visitFile=super::visitFile;
    IoBiFunction<T, IOException, FileVisitResult> visitFailed=super::visitFileFailed;
    IoBiFunction<T, IOException, FileVisitResult> postVisitDir=super::postVisitDirectory;

    public LambdaFileVisitor<T> onVisitFile(IoBiFunction<T, BasicFileAttributes, FileVisitResult> f) {
        this.visitFile = Objects.requireNonNull(f);
        return this;
    }
    public LambdaFileVisitor<T> onVisitFailed(IoBiFunction<T, IOException, FileVisitResult> f) {
        this.visitFailed = Objects.requireNonNull(f);
        return this;
    }
    public LambdaFileVisitor<T> onPreVisitDir(IoBiFunction<T, BasicFileAttributes, FileVisitResult> f) {
        this.preVisitDir = Objects.requireNonNull(f);
        return this;
    }
    public LambdaFileVisitor<T> onPostVisitDir(IoBiFunction<T, IOException, FileVisitResult> f) {
        this.postVisitDir = Objects.requireNonNull(f);
        return this;
    }
    @Override
    public FileVisitResult visitFile(T file, BasicFileAttributes attrs) throws IOException {
        return visitFile.apply(file, attrs);
    }
    @Override
    public FileVisitResult visitFileFailed(T file, IOException exc) throws IOException {
        return visitFailed.apply(file, exc);
    }
    @Override
    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) throws IOException {
        return preVisitDir.apply(dir, attrs);
    }
    @Override
    public FileVisitResult postVisitDirectory(T dir, IOException exc) throws IOException {
        return postVisitDir.apply(dir, exc);
    }
}

一旦你有了你的助手类,你就可以和lambda表达式一起使用它,例如:

FileVisitor<Path> fv=new LambdaFileVisitor<Path>()
  .onVisitFile((f,a)->{System.out.println(f); return CONTINUE; })
  .onVisitFailed((f,e)->{ throw e; });

FileVisitor<Path> fv2=new LambdaFileVisitor<Path>()
  .onPreVisitDir((f,a)->{System.out.println("ENTER "+f); return CONTINUE; })
  .onPostVisitDir((f,e)->{
      System.out.println("LEAVE "+f);
      if(e!=null) throw e; else return CONTINUE;
  });
 类似资料:
  • 问题内容: Lambda表达式必须强制转换为功能接口。就我所知,他们无法扩展课程,但我想知道是否有办法获得类似的东西。 我有一个基类,我想重写它的一个方法,但是我想在另一个方法中重写它。我可以这样用匿名类来做到这一点: 有没有办法在lambda的帮助下消除代码的负担? 我认为lambda将是 我考虑过忘记SimpleFileVisitor并使用默认方法创建等效接口,但是,我如何选择要覆盖的方法?如

  • 问题内容: 我正在阅读有关Java 8的教程,作者在 其中显示了代码: 然后说 无法从lambda表达式内访问默认方法。以下代码无法编译: 但是他没有解释为什么这是不可能的。我运行了代码,但出现了错误, 不兼容的类型:公式不是功能界面` 那么为什么不可能或错误的含义是什么呢? 该接口满足具有一种抽象方法的功能接口的要求。 问题答案: 这或多或少是范围的问题。从JLS 与出现在匿名类声明中的代码不同

  • 问题内容: 为什么上面的代码片段是错误的? 问题答案: 我将尝试结合其他答案中的想法来提出一个答案。 首先,让我们看一下代码中正在发生的事情。 看一下代码 本类有一个包私有方法: 在该子类的类的类,并且所述方法是被覆盖的,但具有访问修饰符。 问题 Java语言不允许子类降低子类中方法,字段或类的可见性,因此,降低该方法可见性的类是不合法的。 为什么降低可见度是一个问题? 考虑我们要使用该类的情况:

  • 如果希望在匿名类中实现多个方法,那么使用将如何处理,例如: …等等?

  • 问题内容: 假设我有一个通用接口: 和方法sort: 我可以调用此方法并将lambda表达式作为参数传递: 那会很好的。 但是现在,如果我将接口设为非泛型,并且将方法设为泛型: 然后像这样调用: 它不会编译。它在lambda表达式中显示错误: “目标方法是通用的” 好的,当我使用编译时,它显示以下错误: 从此错误消息看来,编译器似乎无法推断类型参数。是这样吗 如果是,那为什么会这样呢? 我尝试了各

  • IntelliJ一直建议我用方法引用替换我的lambda表达式。 两者之间有什么客观差异吗?