加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – Typescript:使用类作为接口

发布时间:2020-12-17 17:03:42 所属栏目:安全 来源:网络整理
导读:我试图将Class作为接口用于另一个类.有了这个,我试图完成一个最新的mockClass测试. 这应该是可能的,并且是一种有利的方法,如https://angular.io/guide/styleguide#interfaces中的状态 并在此处展示:Export class as interface in Angular2 但奇怪的是我在VS
我试图将Class作为接口用于另一个类.有了这个,我试图完成一个最新的mockClass测试.

这应该是可能的,并且是一种有利的方法,如https://angular.io/guide/styleguide#interfaces中的状态

并在此处展示:Export class as interface in Angular2

但奇怪的是我在VSCode 1.17.2中使用Typescript 2.5.3时遇到错误

类SpecialTest中的错误

[ts]
Class 'SpecialTest' incorrectly implements interface 'Test'.
  Types have separate declarations of a private property 'name'.

Samplecode:

class Test {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    getName() {
        return this.name;
    }
    setName(name: string): void {
        this.name = name;
    }
}

class SpecialTest implements Test {
    private name: string;

    getName(): string {
        return '';
    }
    setName(name: string): void {
    }
}

我错过了什么?

编辑:
使用字符串而不是字符串,如@fenton建议的那样

解决方法

在开始之前,当您扩展类时,使用extends关键字.您扩展了一个类,并实现了一个接口.在帖子上还有其他注释.

class SpecialTest extends Test {

另外,请注意字符串与字符串,因为这会让你感到震惊.你的类型注释几乎肯定是字符串(小写).

最后,您不需要手动分配构造函数参数,因此原始:

class Test {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    // ...
}

更好地表达为:

class Test {
    constructor(private name: string) {
    }

    // ...
}

现在,您可以从众多问题的解决方案中进行选择.

受保护的会员

使名称成员受保护,然后您可以在子类中使用它:

class Test {
    protected name: string;

    constructor(name: string) {
        this.name = name;
    }

    getName() {
        return this.name;
    }
    setName(name: string): void {
        this.name = name;
    }
}

class SpecialTest extends Test {
    getName(): string {
        return '';
    }
    setName(name: string): void {
    }
}

接口

这是我认为最符合您需求的解决方案.

如果将公共成员拉入接口??,则应该能够将这两个类视为该接口(无论是否显式使用implements关键字 – TypeScript是结构化类型).

interface SomeTest {
  getName(): string;
  setName(name: string): void;
}

如果您愿意,可以明确地实现它:

class SpecialTest implements SomeTest {
    private name: string;

    getName(): string {
        return '';
    }
    setName(name: string): void {
    }
}

您的代码现在可以依赖于接口而不是具体的类.

使用类作为接口

技术上可以将类作为接口引用,但是在使用implements MyClass执行此操作之前存在问题.

首先,您为以后需要阅读代码的任何人(包括未来的代码)添加了不必要的复杂性.您还使用了一种模式,这意味着您需要注意关键字.当继承的类被更改时,意外使用extends可能会在将来导致棘手的错误.维护人员需要成为使用关键字的傻瓜.一切都是为了什么?用结构语言保留名义习惯.

接口是抽象的,不太可能改变.类更具体,更容易改变.使用类作为接口破坏了依赖于稳定抽象的整个概念……而是使您依赖于不稳定的具体类.

考虑整个程序中“类作为接口”的扩散.对类的更改(假设我们添加了一个方法)可能会无意中导致更改波动到很远的距离…程序的多少部分现在拒绝输入,因为输入不包含甚至不使用的方法?

更好的选择(当没有访问修饰符兼容性问题时)……

在类外创建一个接口:

interface MyInterface extends MyClass {
}

或者,在第二堂课中根本不要引用原始课程.允许结构类型系统检查兼容性.

旁注……根据您的TSLint配置,弱类型(例如只有可选类型的接口)将触发no-empty-interface-Rule.

私人会员的具体案例

这些(使用类作为接口,从类生成接口或结构类型)都不能解决私有成员的问题.这就是为什么解决真正问题的解决方案是创建与公共成员的接口.

在私人成员的特定情况下,例如在问题中,让我们考虑如果我们继续使用原始模式会发生什么?自然结果是保留使用类作为接口的模式,成员的可见性将被更改,如下所示:

class Test {
    public name: string;

    constructor(name: string) {
        this.name = name;
    }

    getName() {
        return this.name;
    }
    setName(name: string): void {
        this.name = name;
    }
}

而现在我们正在打破更为既定的面向对象原则.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读