标签: default-method

Kotlin 强制实现类成为另一种类型的超类型

由于 java/kotlin 中不允许多重继承,因此利用接口默认方法很有用。给出的例子:

abstract class Animal { 
    fun beAnimal() { 
        println("I'm animal!") 
    } 
}
abstract class Mammal : Animal()  { 
    fun produceMilk() { 
         beAnimal().apply { println("Freesh milk!") }
    } 
}
abstract class AnimalWithBeak : Animal()  { 
    fun quack() { 
        beAnimal().apply { println("Quack!") }
    } 
}
class Platypus : ??? // I want it to both produce milk and quack!
Run Code Online (Sandbox Code Playgroud)

如上所述,不允许使用多个基类,但我们可以使用接口:

abstract class Animal { fun beAnimal() { println("I'm animal!") } }

interface Mammal { 
    fun produceMilk() { 
        (this as Animal).beAnimal().apply …
Run Code Online (Sandbox Code Playgroud)

inheritance kotlin default-method

6
推荐指数
2
解决办法
3178
查看次数

使用带有默认方法的新Java8接口

我有几个关于Java 8中"新"接口的问题,我有以下代码:

public interface Drawable {
    public void compileProgram();

    public Program getProgram();

    public boolean isTessellated();

    public boolean isInstanced();

    public int getInstancesCount();

    public int getDataSize();

    public FloatBuffer putData(final FloatBuffer dataBuffer);

    public int getDataMode();

    public boolean isShadowReceiver();

    public boolean isShadowCaster();    //TODO use for AABB calculations

    default public void drawDepthPass(final int offset, final Program depthNormalProgram, final Program depthTessellationProgram) {
        Program depthProgram = (isTessellated()) ? depthTessellationProgram : depthNormalProgram;
        if (isInstanced()) {
            depthProgram.drawArraysInstanced(getDataMode(), offset, getDataSize(), getInstancesCount());
        }
        else {
            depthProgram.drawArrays(getDataMode(), offset, getDataSize());
        }
    }

    default …
Run Code Online (Sandbox Code Playgroud)

java oop interface java-8 default-method

5
推荐指数
1
解决办法
308
查看次数

如果两个接口包含相同的默认方法会发生什么?

如果我有两个接口使用相同的默认方法,并且都使用类实现/请参阅此程序.

interface alpha {
  default void reset() {
    System.out.println("This is alpha version of default");
  }
}

interface beta {
  default void reset() {
    System.out.println("This is beta version of default");
  }
}

class MyClass implements alpha, beta {
  void display() {
    System.out.println("This is not default");
  }
}

class main_class {
  public static void main(String args[]) {
    MyClass ob = new MyClass();
    ob.reset();
    ob.display();
  }  
}
Run Code Online (Sandbox Code Playgroud)

然后会发生什么?而且这个程序我也得到了无关的错误.

java interface java-8 default-method

5
推荐指数
1
解决办法
985
查看次数

使用ECJ的Lambda /默认方法/类型擦除怪癖/错误?

今天遇到了这个问题,花了很多年时间试图重现/弄清楚发生了什么.有人可以解释为什么会发生这种情况,或者这是类型擦除/默认方法/ lambda/polymorphism的错误?取消注释默认方法可以使它运行正常,但我希望它能够按原样运行

输出:

Works fine with an object
Calling consume
Hello
Calling accept with context
Hello
Calling accept via consumer...
Exception in thread "main" java.lang.AbstractMethodError: Method test/LambdaTest$$Lambda$1.accept(Ljava/lang/Object;)V is abstract
    at test.LambdaTest$$Lambda$1/834600351.accept(Unknown Source)
    at test.LambdaTest.main(LambdaTest.java:24)
Run Code Online (Sandbox Code Playgroud)

package test;

import java.util.function.Consumer;

public class LambdaTest {

    public static void main(String[] args) {
        Consumer<Context> contextIgnoringObject = new ContextUnawareObject();
        contextIgnoringObject.accept(new Context());

        ContextIgnorer contextIgnoringLambda = () -> {
            System.err.println("Hello");
        };

        System.err.println("Calling consume");
        contextIgnoringLambda.consume();

        System.err.println("Calling accept with context");
        contextIgnoringLambda.accept(new Context());

        Consumer<Context> consumer = contextIgnoringLambda;

        System.err.println("Calling accept via …
Run Code Online (Sandbox Code Playgroud)

java lambda type-erasure java-8 default-method

5
推荐指数
1
解决办法
227
查看次数

Java 8 - 默认方法 - 对遗留代码的关注

一本书的问题:

在过去(Java 8之前版本),您被告知将方法添加到接口是一种糟糕的形式,因为它会破坏现有代码.现在您被告知可以添加新方法,前提是您还提供默认实现.

  1. 这有多安全?描述接口的新stream方法Collection导致遗留代码编译失败的情况.
  2. 二进制兼容性怎么样?来自JAR文件的遗留代码是否仍会运行?"

我的答案如下,但我不太确定.

  1. 仅当遗留代码不提供具有相同名称stream和相同签名的方法时(例如,在实现的遗留类中Collection),它才是安全的.否则,这个旧的遗留代码将无法编译.
  2. 我认为保留了二进制兼容性,旧JAR文件中的遗留代码仍将运行.但我对此没有明确的论据.

任何人都可以确认或拒绝这些答案,或者只是为这些答案添加更多参数,参考或清晰度吗?

java java-8 default-method

5
推荐指数
1
解决办法
352
查看次数

必须实现默认接口方法吗?

这是一个显示我的问题的简化示例:

import java.util.List;

public interface SingleTask extends List<Runnable>, Runnable {
    default Runnable get(final int x) {
        if (x != 0) {
            throw new IndexOutOfBoundsException();
        }
        return this;
    }

    default int size() {
        return 1;
    }
}

import java.util.AbstractList;

public class MyTask extends AbstractList<Runnable> implements SingleTask {
    @Override
    public void run() {
        System.out.println("hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

SingleTask我提供用于方法的实现getsize,它们是从仅抽象方法AbstractList.但是,当我编译时MyTask,我仍然会遇到如下错误:

MyTask类型必须实现继承的抽象方法AbstractCollection.size()

要么

MyTask.java:3:错误:MyTask不是抽象的,并且不会覆盖AbstractList中的抽象方法get(int)

(取决于编译器).我当然是使用java 8.

所以我有两个问题:

  1. 为什么我会收到这些错误?我期待它能够识别默认的实现.
  2. 如果它不应该像那样工作,那么在MyTask不复制整个代码的情况下使用这两种方法的最简单方法是什么?

java java-8 default-method

5
推荐指数
1
解决办法
477
查看次数

如何从TestNG测试和Selenium接口调用默认方法?

我想知道是否可以使用来自TestNG @BeforeMethod注释的接口的默认方法?

这是我试过的样本:

@Listeners(TestListener.class)
public interface ITestBase {
    String baseUrl = Config.getProperty(Config.TEST_HOST);
    String driverName = Config.getProperty(Config.BROWSER);
    DriversEnum driverInstance = DriversEnum.valueOf(driverName.toUpperCase());

    @BeforeMethod(alwaysRun = true)
    default public void start() {
        try {
            driver.init();
            DriverUnit.preconfigureDriver(Driver.driver.get());
            driver.get().manage().deleteAllCookies();
            driver.get().get(baseUrl);
        } catch (TimeoutException e) {
            Logger.logEnvironment("QT application is not available");
        }
    }

    @AfterMethod(alwaysRun = true)
    default public void end() {
        if (driver.get() != null) {
            try {
                driver.get().quit();
            } catch (UnreachableBrowserException e) {
                Logger.logDebug("UnreachableBrowser on close");
            } finally {
                driver.remove();
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

当我运行典型的TestNG测试方法时,如:

public …
Run Code Online (Sandbox Code Playgroud)

java testng java-8 selenium-webdriver default-method

5
推荐指数
1
解决办法
556
查看次数

具有默认行为且具有Seri​​alizable的功能接口

当没有默认方法的接口扩展可序列化时,一切正常。但是,当该接口的默认方法出现时,我们将显示警告:

MyInterface.java:可序列化的类MyInterface没有serialVersionUID的定义

当我将该接口更改为抽象类时,它变得很有趣。错误消失。

总结警告发生的表格如下:

|----------------------------|------------------|
|            Type            |      WARNING     |
|----------------------------|------------------|
| interface with no defaults |         NO       |
|----------------------------|------------------|
| interface with defaults    |        YES       |
|----------------------------|------------------|
| abstract class             |         NO       |
|----------------------------|------------------|
Run Code Online (Sandbox Code Playgroud)

有什么原因还是只是一个错误?

java interface serializable compiler-warnings default-method

5
推荐指数
0
解决办法
160
查看次数

Java 8 - 两个接口包含具有相同方法签名但返回类型不同的默认方法,如何覆盖?

我理解如果一个类实现包含同名默认方法的多个接口,那么我们需要在子类中重写该方法,以便明确定义我的方法将执行的操作.
问题是,见下面的代码:

interface A {
    default void print() {
        System.out.println(" In interface A ");
    }
}

interface B {
    default String print() {
        return "In interface B";
    }
}

public class C implements A, B {

    @Override
    public String print() {
        return "In class C";
    }

    public static void main(String arg[]) {
        // Other funny things
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,接口A和B都有一个名为'print'的默认方法,但我想覆盖接口B的print方法 - 返回字符串并按原样保留A的打印方式.但是这段代码不能编译给出:

Overrides A.print
The return type is incompatible with A.print()
Run Code Online (Sandbox Code Playgroud)

很明显,编译器试图覆盖A的打印方法,我不明白为什么!

java overriding interface java-8 default-method

5
推荐指数
1
解决办法
588
查看次数

从匿名内部类调用重写的默认方法

考虑以下代码:

interface A {
    default void doA() {
        System.out.println("a");
    } 
}

interface B {
    void doB(); 
}

class Test implements A {

    @Override
    public void doA() {        
        // Works
        B b = () -> A.super.doA();
        b.doB();

        // Does not compile
        /*
        new B() {      
            public void doB() {  
                A.super.doA();
            }       
        }.doB();
        */
    }

    public static void main(String[] args) {
        new Test().doA();
    }

}
Run Code Online (Sandbox Code Playgroud)

这是做作,但基本上Test::doA()试图来包装thisB,并且具有B::doB()调用它的超强功能A.super.doA().

我可以打电话给A.super.doA()一个类型的lambda B就好了.但我无法弄清楚A.super.doA() …

java super anonymous-class java-8 default-method

5
推荐指数
1
解决办法
260
查看次数