我通过Mixins使用多重继承(使用替代模式)。有没有办法用这个模式得到类似于“超级”的东西?考虑这里的例子
abstract class Activatable{
private activated: boolean = false;
constructor(){}
public activate(): void {
this.activated = true;
console.log('Activatable activated')
}
}
class SomethingElse{};
interface ThingParent extends Activatable{}
class ThingParent extends SomethingElse{
public activate(): void {
(this as Activatable).activate();
let addSomeValueHere = true;
console.log('Thing parent activated')
}
}
applyMixins(ThingParent, [Activatable]);
class Thing extends ThingParent {
constructor(){
super()
}
public activate(): void {
super.activate();
console.log('Thing activated');
}
}
let thing = new Thing();
thing.activate();
function applyMixins(derivedCtor: any, constructors: any[]) {
constructors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
Object.create(null)
);
});
});
}
Thing扩展了ThingP,它通过混合扩展了一个名为Activable的类。当我在Thing上调用激活时,我也想在ThingP的和Activable上调用激活,但它只在Activable上调用。
如果我更改了ThingParent上函数的名称,我可以直接调用该函数,但ThingParents不能通过super访问Activatable(因为它扩展了SomethingElse)。那我就得叫这两个超级。activate()和这个。thing的thingParentActivate()。activate(),所以如果可能的话,我想避免这种模式。
有没有其他选择?
(链接到打字操场上的代码:https://www.typescriptlang.org/play?#code/IYIwzgLgTsDGEAJYBthjAggvAlgN2AlGQFMBvAWACgFaEAHKfQkhOCZiEgEwC4EQAe0GlgAOwQBeBADNgyMCQDc1OkkFjIUAK7xBUABQBKMgF9VdetpDIcsNrgJdj-PIJzcElGmroQAFjhgAHTsnDxSCNDayha6poiJMHIggDmBgDk2BxOxKxhTjyZRhbmVOXUKGgYAMqCALYkAThiaQCiCuSmKlTUrVxQcrCsACqBbQAKuFAkYogkAB5cYtwYOZz5ZtRVqOgI461p07PzCEsrawj1TS1tnYRealY2dg65LC4Ibh5ecb4GFoYNBYRyEFJGUJg5xGXrxWikRDAbjcG4kABq8hiAAkSLNItFYj54rANGAkil0llDm0GDM5kjocVSsSEOVKlRqvsaWlzss5lceScGX9TNNE9IYTP81GBtPQ8cZ-uVntZbPZCp8jK53J4nvD
正如你所知道的,JavaScript类不支持多重继承,所以如果你想得到那样的效果,你需要做一些事情来模拟它。Mixins是实现这一点的一种方式,但是它们并不真正支持有冲突的方法名。如果你有冲突的方法名,那么mixins将会破坏所有的方法名,只留下一个,这不是你想要的。
如果要在子类的实例上调用特定的超类的方法,可以直接使用Function.prototype.call()
,该实例作为this
arg。而不是Activatable::activate()
,您可以调用Activatable.prototype.activate.call(this);
。
让我们试一试:
interface ThingParent extends Activatable { }
class ThingParent extends SomethingElse {
public activate(): void {
Activatable.prototype.activate.call(this);
let addSomeValueHere = true;
console.log('Thing parent activated')
}
}
class Thing extends ThingParent {
constructor() {
super()
}
public activate(): void {
ThingParent.prototype.activate.call(this);
console.log('Thing activated');
}
}
let thing = new Thing();
thing.activate();
// [LOG]: "Activatable activated"
// [LOG]: "Thing parent activated"
// [LOG]: "Thing activated"
这会编译好并产生您期望的输出。
在更复杂的场景中,您可能会决定需要混合使用直接方法调用或其他方法。
代码的游乐场链接
我正在为一个系统建模,该系统有一个创建资源的操作和其他消耗该资源的操作。然而,一个给定的资源只能被消耗一次——有没有一种方法可以保证在编译时这样做? 具体来说,假设第一个操作烘焙蛋糕,还有另外两个操作,一个用于“选择吃”蛋糕,另一个用于“选择吃蛋糕”,我只能做其中一个。 通过在我们使用蛋糕后在蛋糕上设置一个标志,很容易在运行时强制执行不保留已经吃过的蛋糕(反之亦然)的限制。但是有没有办法在编译时强
问题内容: 我正在使用felixge的客户端。我没有使用ORM。 我正在用Vows进行测试,并且希望能够使用Sinon来模拟我的数据库。由于除之外我本身还没有DAL ,因此我不确定如何执行此操作。我的模型大多是带有很多吸气剂的简单CRUD。 关于如何做到这一点的任何想法? 问题答案: 使用sinon,您可以在整个模块上放置一个模拟或存根。例如,假设模块具有一个功能: ,是您期望的输入。是您期望的输
我想现在,如果有可能模仿一个类一样 我们的业务逻辑在代码中的某个地方用< code>new myClass()创建了这个对象,因此我不能访问创建的对象来模拟这些方法。有没有办法替换整个类或者覆盖那些方法。我正在使用mockito,我只找到了这样做的例子 我们不能使用 PowerMock,因为它与我们的测试环境不兼容。 欢迎任何建议。
我有折叠代码: 根据以下链接中描述的原因,我无法使用
我有一个python项目,我使用virtualenv(pipenv)设置它。我使用来创建虚拟环境,并从它们内部使用 主要的派克 我试图显示一个情节,但我得到以下错误: 文件“/home/linuxbrew/.linuxbrew/opt/python@3.8/lib/python3。8/tkinter/init。py“,第36行,在导入_tkinter中#如果这失败,您的Python可能不会为Tk
在虚拟环境之外,它运行良好。但是在虚拟环境中,MySQL Python连接器没有导入。我正在做覆盆子皮。下面是我提到的内容。我该怎么做才能修好它? =========================================================================== ==================================================