首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在TypeScript中创建模拟Java函数接口的默认方法?

如何在TypeScript中创建模拟Java函数接口的默认方法?
EN

Stack Overflow用户
提问于 2019-04-21 09:10:10
回答 2查看 1K关注 0票数 3

有一个在类型记录/JavaScript (Script4J)中实现Java(FX) API的项目。现在我要修改比较器的功能接口。这是默认解决方案:

代码语言:javascript
复制
export interface Comparator<T> {
    (o1: T, o2: T): number;
}

这种解决方案允许将比较器添加为箭头函数(如java lambda),例如:

代码语言:javascript
复制
let comparator: Comparator<number> = (n1: number, n2: number): number => {
    return n1 - n2;
};
let treeMap: SortedMap<number, string> = new TreeMap<number, string>(comparator);

正如您所看到的,代码非常干净。现在,我需要添加到TypeScript比较器接口下一个方法(Java代码):

代码语言:javascript
复制
default Comparator<T> reversed() {
    return Collections.reverseOrder(this);
}

考虑到我不能更改API,什么是最好的方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-21 16:38:03

经过一些思考,我决定实现最大Java的唯一方法是使用抽象类而不是接口。这是我的解决办法:

代码语言:javascript
复制
function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
             if (name !== 'constructor') {
                derivedCtor.prototype[name] = baseCtor.prototype[name];
            }
        });
    }); 
}

type ComparatorFunc<T> = (o1: T, o2: T) => any;

abstract class Comparator<T> {

    public static lambda<T>(func: ComparatorFunc<T>): Comparator<T> {
        return new class extends Comparator<T> {
            public compare(o1: T, o2: T): number {
                return func(o1, o2);
            }
        }
    }

    public abstract compare(o1: T, o2: T): number;
}

//VAR 1 - lambda
let lambdaComparator: Comparator<number> = Comparator.lambda((n1: number, n2: number) => { return n1 - n2;});
console.log("Lambda comparator");
console.log(lambdaComparator.compare(100, 50));

//VAR 2 - full implementation
class MyComparator implements Comparator<number> {

    public compare(o1: number, o2: number): number {
        return o1 - o2;
    }
}
applyMixins (MyComparator, [Comparator]);

let classComparator: MyComparator = new MyComparator();
console.log("Class comparator");
console.log(classComparator.compare(100, 50));

优势:

  • 我们非常接近Java。
  • 方法的名称是可见的。
  • 我们可以使用箭头函数快速创建类的实例。
  • 我们可以创建实现多个接口的类。
  • 当实现接口的所有类都通过一个函数(applyMixins)时,我们可以添加对方法的支持,这些方法可以检查某些实例是否实现了某些接口(类通过instanceof很容易检查)。

缺点:

  • 每次程序启动/页面打开时,为每个类调用applyMixins。
  • 在每个实现中显示空的默认方法(反转:()=>比较器)是必要的,因为TypeScript检查它们的实现。
票数 1
EN

Stack Overflow用户

发布于 2019-04-21 10:41:03

在类型记录中没有与默认接口方法实现直接等效的方法。您可以使用ea函数将默认值分配给比较器函数:

代码语言:javascript
复制
export interface Comparator<T> {
    (o1: T, o2: T): number;
    reversed() : any // not sure what return type should be, maybe (o1: T, o2: T) => number ?
}

function comparatorWithDefault<T>(fn: (o1: T, o2: T) => number) {
    function reversed(this: Comparator<T>) {
        return Collections.reverseOrder(this);
    }
    return Object.assign(fn, { reversed });
}

let comparator: Comparator<number> = comparatorWithDefault((n1: number, n2: number): number => {
    return n1 - n2;
})
let treeMap: SortedMap<number, string> = new TreeMap<number, string>(comparator);

与Java不同,将成员添加到Comparator将破坏许多现有代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55781400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档