接口和类中的函数重载 - 如何?

Posted

技术标签:

【中文标题】接口和类中的函数重载 - 如何?【英文标题】:Functions Overloading in interface and classes - how to? 【发布时间】:2012-10-24 12:46:22 【问题描述】:

我有这个界面:

interface IPoint 
    getDist(): string;
    getDist(x: number): any;

我需要一个类来实现它,但我无法获得正确的语法来实现 getDist() 方法 在课堂上..

class Point implements IPoint 
    // Constructor
    constructor (public x: number, public y: number)  

    pointMethod()  

    getDist() 
        Math.sqrt(this.x * this.x + this.y * this.y);
    
    // Static member
    static origin = new Point(0, 0);

上面写着:

类 'Point' 声明了接口 'IPoint' 但没有实现它: “Point”和“IPoint”类型的属性“getDist”的类型是 不兼容:类型 '() => void' 和 ' (): string; 的调用签名 (x:数字):任何; ' 不兼容

这样做的正确方法是什么?

谢谢

【问题讨论】:

【参考方案1】:

当你在类中声明函数时,你需要用重载来装饰它:

getDist(): string;
getDist(x: number): any;
getDist(x?: number): any 
    // your code
 

【讨论】:

你不需要写第二个声明。即使没有它也可以工作 @S.RaviKiran 您需要两个重载声明,因为您不能在重载函数上调用实现。你可以在 TypeScript Playground 中尝试一下。 typescriptlang.org/Playground @S.RaviKiran 发布您的示例。 它无需添加声明即可工作,但要在 Visual Studio 自动完成中实现重载,您需要添加重载减速。 和静态类型的返回值,是不同的。【参考方案2】:

This answer 描述了如何在 TypeScript 中实现方法重载,并不漂亮:

interface IPoint 
    getDist(): string;
    getDist(x: number): any;


class Point implements IPoint 
    // Constructor
    constructor (public x: number, public y: number)  

    pointMethod()  

    getDist(x?: number) 
         if (x && typeof x == "number") 
             return 'foo';
          else 
             return 'bar';
         
    

注意使用接口中声明的返回类型的特定组合,您只能从getDist 返回字符串。

【讨论】:

你的意思是它不漂亮只是因为它有 if-else 类型保护?【参考方案3】:

你也可以使用默认值

interface Foo
    next()
    next(steps: number)
    prev()
    prev(steps: number)


next(steps: number = 1) 
    // ...


prev(steps: number = 1) 
    // ...

【讨论】:

【参考方案4】:

以下是上述部分内容的变体

class Position 
    x: number;
    y: number;

    constructor(x : number = 0, y : number = 0) 
        this.x = x;
        this.y = y;
        


class Pen 
    colour: string;

    constructor(colour: string) 
        this.colour = colour;
    


class PlottingHead 
    isPenUp: boolean;
    pen: Pen;
    position: Position;

    constructor()      
       this.penUp();
   

   move(p: Position): void;
   move(x: number, y: number): void;
   move(x: number | Position, y?: number): void 
        if (typeof x === "number")
        
            x = new Position(x, y);
        
        this.penUp();
        this.position = x;
    

    draw(x: number | Position, y?: number): void 
        if (typeof x === "number")
        
            x = new Position(x, y);
        
        this.penDown();
        this.position = x;
    

    penDown(): void 
        this.isPenUp = false;
     

    penUp(): void 
        this.isPenUp = true;
    

    onChangePen(newPen: Pen) 
        this.penUp();
        this.pen = newPen;
        

move 函数采用单个位置对象或一对数值。这显然可以根据需要进行扩展。

【讨论】:

以上是关于接口和类中的函数重载 - 如何?的主要内容,如果未能解决你的问题,请参考以下文章

关于友元函数,运算符重载和类的类型转换

如何从基类中的函数调用重载函数?

类中的函数重载

类中的函数重载(二十三)

C++深度剖析学习总结 22 类中的函数重载

C++深度剖析学习总结 22 类中的函数重载