无论何时在JavaScript或Python中扩展类,派生类都必须使用关键字super,以便在基类中设置属性和/或调用方法和构造函数.例如:

class Rectangle {
    constructor(length, width) {
        this.name = "Rectangle";
        this.length = length;
        this.width = width;
    }

    shoutArea() {
        console.log(
            `I AM A ${this.name.toUpperCase()} AND MY AREA IS ${this.length * this.width}`
        );
    }
    
    rectHello() {
        return "Rectanglish: hello";
    }
}

class Square extends Rectangle {
    constructor(length) {
        super(length, length);
        this.name = "Square"
    }
    
    squaHello() {
        const h = super.rectHello();
        return "Squarish:" + h.split(':')[1];
    }
}

const rect = new Rectangle(6, 4);
rect.shoutArea(); //=> I AM A RECTANGLE AND MY AREA IS 24

const squa = new Square(5);
squa.shoutArea(); //=> I AM A SQUARE AND MY AREA IS 25

console.log(squa.squaHello()); //=> Squarish: hello

推荐答案

在JavaScript和Python中使用的关键字super的Raku对应值是什么?

拉库re-dispatching functions人中的一人.

Basics of redispatch

首先,Do not的一些代码包括重新调度功能:

class Rectangle {
  has ($.length, $.width)
}

Rectangle.new: length => 6, width => 4;

Rectangle声明甚至不包括构造代码,只有两个属性的声明,仅此而已.

那么,Rectangle.new呼叫在做什么呢?它继承了Raku的Mu类提供的默认new方法,该方法初始化名称与任何命名参数匹配的任何类属性.


如果您想要一个接受positional个参数的自定义构造函数,则通常编写一个new方法,其中列出您希望在其签名中包含哪些参数,然后让该方法调用需要命名参数的默认new,方法是调用一个适当的重调度函数,将参数转换为命名参数:

class Rectangle {
  has ($.length, $.width);
  method new ($length, $width) { callwith length => $length, width => $width }
}

Rectangle.new: 6, 4;

callwith是重调度功能,它执行以下操作:

  • 基于原始呼叫的下一个匹配候选者的call%

  • with一组新的论点.

在这个简单的例子中,最初的调用是Rectangle.new: 6, 4,下一个候选方法是从Mu继承的new方法.

A Rectangle class based on yours

我不会模仿您的代码,而是编写一个惯用的Raku翻译并对其进行注释.

class Rectangle {
  has ($!length, $!width) is required is built;
  method new ($length, $width) { callwith :$length, :$width }
  method shoutArea { put uc "I am a {self.^name} and my area is {$!length * $!width}" }
  method rectHello { 'Rectanglish: hello' }
}

constant rect = Rectangle.new: 6, 4;
rect.shoutArea; #=> I AM A RECTANGLE AND MY AREA IS 24

comments :

  • 默认编写代码来限制代码演变过程中可能出现的问题是一个好习惯.出于这个原因,我使用了$!length作为长度属性,而不是$.length.

  • 我已经为属性添加了is required注释.这意味着在实例构造结束时未能初始化属性将意味着抛出异常.

  • 我已经为属性添加了is built注释.这意味着,即使没有公共访问器的属性--就像$!length$!width的情况一样,因为我使用的是!而不是"twigil"中的.--如果构造调用中有匹配的命名参数,它仍然可以/仍然会被自动初始化.

  • :$lengthlength => $length的缩写.

  • self.^name可避免不必要的开销.阅读这篇文章并不重要,而且很可能会让人分心,所以你可以忽略我的脚注来解释它.⁴

A Square class based on yours

我会用newSquare重新调度:

class Square is Rectangle {
  method new ($side-length) { callwith $side-length, $side-length }
  method squaHello { "Squarish: {self.rectHello.split(':')[1].trim}" }
}

constant squa = Square.new: 5;
squa.shoutArea; #=> I AM A SQUARE AND MY AREA IS 25
put squa.squaHello; #=> Squarish: hello

comments :

  • 我为Square‘S .new参数 Select 了名称$side-length,但名称并不重要,因为它是位置参数/实参.

  • 抽象地说,重新调度是给下一位候选人的,就像以前一样.具体地说,这一次的下一个候选方法是我刚才在Rectangle中定义的方法(它又重新调度到Munew).

  • self.rectHello就足够了,因为被调用的方法与最初调用的方法(squaHello)具有不同的名称.如果将RectangleSquare中的两个方法重命名为具有相同的名称Hello,那么重新分派也是合适的,尽管这一次我只编写了callsame而不是callwith ...,因为callsame只是使用原始调用中提供的相同参数重新分派给下一个候选项,这将省go 再次写出参数的麻烦.

Footnotes

?重新调度是对super等功能的概括.重调度函数用于一系列目的,包括与面向对象无关的目的.

?在RAKU中,函数或方法调用可能会导致编译器生成一个可能匹配的候选对象列表,考虑的因素包括方法调用的调用以及函数和方法的多个分派和函数包装.在构建了候选人列表之后,它然后将其分派给领先的候选人(或者在重新分派给下一个候选人的情况下是下一个).

³如果你真的想为一个给定的属性自动生成一个getter/setter,那么用一个.来声明它,例如$.length而不是$!length,Raku会同时生成一个$!length属性和一个.length getter.(如果您在$.length声明中添加is rw,也是一个setter.)我在第一个代码示例中这样做是为了让事情更简单一些.

在像foo.^bar这样的方法调用中⁴^意味着bar方法调用被"向上"(因此是^)重定向到知道foo如何作为一种特定类型工作的H更高的OrderW排序对象.在本例中,Rectangleclass,而HOW对象是Perl6::Metamodel::ClassHOW的实例,它知道类是如何工作的,包括每个类具有不同的name,并且具有检索该名称的.name方法.当然,Rectangle类的名称是‘Rectangle’,因此self.^name省go 了用类的名称创建其他东西的麻烦.

Javascript相关问答推荐

如何在dataTables PDF输出中正确渲染字形?

如何在加载的元数据上使用juserc和await中获得同步负载?

ReactJS中的material UI自动完成类别

通过使用100%间隔时间来代表我们还剩多少时间来倒计时

如何修复我的js构建表每当我添加一个额外的列作为它的第一列?

无法从NextJS组件传递函数作为参数'

XSLT处理器未运行

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

如何在JAVASCRIPT中合并两组对象并返回一些键

Vaadin定制组件-保持对javascrip变量的访问

我想将Sitecore搜索面过滤器从多个转换为单个

为什么云存储中的文件不能公开使用?

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

使用线性插值法旋转直线以查看鼠标会导致 skip

重新呈现-react -筛选数据过多

如果对象中的字段等于某个值,则从数组列表中删除对象

按特定顺序将4个数组组合在一起,按ID分组

我为什么要使用回调而不是等待?

未捕获的不变违规:即使在使用DndProvider之后也应使用拖放上下文

使用Library chart.js在一个带有两个y轴的图表中绘制两个数据集