是否可以在接口类中访问通用类型的方法?

时间:2018-08-03 19:41:15

标签: java

我想通过实现接口类来向类添加新方法,而无需每次都重写它。我知道这听起来很荒谬,但请考虑以下示例:

public class Main {

    public static void main(String... args) {
        Subclass subclass = new Subclass();
        subclass.println("Hello");
        subclass.print("World!");
    }

    static abstract class Abstract {
        abstract void print(String message);
    }

    /**
     * I would like to add methods from this class to
     * whatever class that is a subclass of Abstract.
     */
    interface Interface<T extends Abstract> {
        default void println(String message) {
            System.out.println(message);
        }
    }

    static class Subclass extends Abstract implements Interface<Subclass> {
        @Override
        public void print(String message) {
            System.out.print(message);
        }
    }

}

因此,基本上,我想将println中的方法Interface添加到扩展类Abstract的任何类中。这样,我们就以某种方式知道T是什么类型。但是我真正想在println内部做的是从T调用一个从类Abstract继承的方法。像这样:

interface Interface<T extends Abstract> {
    default void println(String message) {
        // I know that this WON'T work
        ((Abstract) T).print(message + "\n");
    }
}

我这样做的原因是,在不需要重写这些方法的意义上,使这些方法可重用(并节省重复的代码行)。我知道这听起来很荒谬,实际上听起来像是抽象类的 literal 用法,唯一的区别是,我们不能从多个类中扩展。无论如何,这只是我的结论。

那么,这可能吗? OR 是否可以以完全不同的方式而不是使用界面来完成?有想法吗?

2 个答案:

答案 0 :(得分:2)

如果您希望接口Interface中的方法假定它在扩展Abstract的类型上并调用Abstract方法,则此方法应该有效:

interface Interface {
    default void println(String message) {
        ((Abstract) this).print(message + "\n");
    }
}

假设您仅在扩展Abstract的类上实现接口。如果您尝试从未扩展println()的对象中调用Abstract,则会出现强制转换异常。

答案 1 :(得分:1)

您尝试执行的操作不一致。
所有ex.class == NameError 对象都不是Interface实例。
是的,您可以声明实现Abstract的{​​{1}}类,但也可以声明也实现Abstract的{​​{1}}类。

因此,将Interface强制转换为Foo并不是一个好主意,如果Interface不是this实例,它将在运行时触发Abstract

ClassCastException

实际上可以满足您的要求:

  

我想通过实现接口向类添加新方法   类,但不必每次都覆盖它。

您只需要一个东西:一个既定义要实现的方法又定义默认方法的接口:

this

子类将仅定义Abstract方法:

default void println(String message) {
    // I know that this WON'T work
    ((Abstract) this).print(message + "\n");
}

您可以通过以下方式使用它:

interface Interface {
    default void println(String message) {
         this.print(message + "\n");
    }
    void print(String message);
}

抽象类显得无助。