Typescript对象转换错误

时间:2014-12-02 11:41:41

标签: typescript

我有两个类都实现了IFruit接口。简化的问题是我想在某些困惑中用芒果取代Apple。但是,以下示例会导致编译器错误。

无法转换'芒果'对于Apple':类型'芒果'和' Apple'定义属性' _element'作为私人。

为什么这是一个问题? _element未在界面中浮出水面。它不应该被迫公开。

interface IFruit {
    getElement(): HTMLElement;
}

class Apple implements IFruit {

    private _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }
}

class Mango implements IFruit {

    private _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }

}

var e: HTMLElement;
var a = new Apple(e);
var m = new Mango(e);
a = m;

1 个答案:

答案 0 :(得分:2)

您可以使用三种解决方案,根据上下文选择您的。

接口

由于私人会员实际上无法使任何其他类型在结构上匹配,因此您永远不能使Mango看起来像Apple。它们都完全满足IFruit界面,因此如果您将它们键入IFruit,它们就完全可以取代 - 下面的例子IFruitnew Apple(e) new Mango(e)类型注释 - 虽然这只适用于Apple,例如:

interface IFruit {
    getElement(): HTMLElement;
}

class Apple implements IFruit {

    private _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }
}

class Mango implements IFruit {

    private _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }

}

var e: HTMLElement;
var a: IFruit = new Apple(e);
var m: IFruit = new Mango(e);
a = m;

继承

你也可以使用继承来解决这个问题。 AppleMango可以访问基础_element类上受保护的Fruit

class Fruit {
    protected _element : HTMLElement;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }
}

class Apple extends Fruit {
    constructor(element: HTMLElement) {
        super(element);
    }
}

class Mango extends Fruit {
    constructor(element: HTMLElement) {
        super(element);
    }
}

var e: HTMLElement;
var a = new Apple(e);
var m = new Mango(e);
a = m;

公共

如果要在不使用接口或继承的情况下使它们兼容,则需要将属性设为公共:

interface IFruit {
    getElement(): HTMLElement;
}

class Apple implements IFruit {

    public _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }
}

class Mango implements IFruit {

    public _element;

    constructor(element: HTMLElement) {
        this._element = element;
    }

    getElement(): HTMLElement {
        return this._element;
    }

}

var e: HTMLElement;
var a = new Apple(e);
var m = new Mango(e);
a = m;