当前位置: 首页 > 面试题库 >

如何在Java 8中使用Lambda表达式覆盖基类方法?

程承恩
2023-03-14
问题内容

Lambda表达式必须强制转换为功能接口。就我所知,他们无法扩展课程,但我想知道是否有办法获得类似的东西。

我有一个java.nio.file.SimpleFileVisitor<Path>基类,我想重写它的一个方法,但是我想在另一个方法中重写它。我可以这样用匿名类来做到这一点:

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) -> System.out.println(f);

我考虑过忘记SimpleFileVisitor并使用默认方法创建等效接口,但是,我如何选择要覆盖的方法?如果没有默认实现,是否需要保留要覆盖的方法?在那种情况下,我将需要使用不同的未实现方法的不同情况的多个接口。

谢谢。


问题答案:

使用 委托 。对于此任务,您需要一个只能执行一次的帮助程序类:

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

  • 如果我更改了方法的名称,它会进行编译,但它不会重写toString,因此print方法不会打印预期的内容。 这是试图定义一个日志子系统,该子系统仅在需要时(当它真的要打印时)对lambda求值,但与非lambda参数兼容。我知道其他的方法来实现它,但我想知道为什么我不能这样做,如果有一个变通办法或我做错了什么,

  • 1 Java8 Lambda表达式的介绍 Lambda表达式是Java8中包含的一项新的重要功能。它提供了一种简洁明了的方式来使用表达式表示一个方法接口。在Collection集合中非常有用。它有助于集合元素的迭代,过滤和从集合中提取数据。 Lambda表达式用于提供具有功能接口的接口的实现。它节省了大量代码。在使用Lambda表达式的情况下,我们无需再次定义用于提供实现的方法。我们只编写实现代码

  • 本文向大家介绍Java8之lambda表达式基本语法,包括了Java8之lambda表达式基本语法的使用技巧和注意事项,需要的朋友参考一下 lambda表达式,即带有参数的表达式,为更清晰地理解lambda表达式,先看如下例子: (1) (1)中代码调用Collections.sort方法对集合进行排序,其中第二个参数是一个类,准确地说是一个匿名内部类,sort方法调用内部类中的compare方法

  • 本文向大家介绍Java8使用lambda表达式调用静态方法,包括了Java8使用lambda表达式调用静态方法的使用技巧和注意事项,需要的朋友参考一下 Java中的Lambda表达式允许您将功能作为参数传递给方法。您还可以使用lambda表达式调用现有的方法。 方法引用是简单的、易于阅读的lambda表达式,可以通过lambda表达式中的名称调用/引用现有的方法。可以使用方法引用引用类中定义的静态

  • 我在尝试使用lambda表达式时遇到了这个错误。