I'm using ES6 classes and my class (A) extends class B and class B extends class C. How can A extend a method and then call C's version of that method.
class C {
constructor() {
console.log('class c');
}
}
class B extends C {
constructor() {
super()
console.log('no, I don\'t want this constructor.');
}
}
class A extends B {
constructor() {
// What should I be doing here? I want to call C's constructor.
super.super();
}
}
Edit: Thanks all, I'm going to stop trying to do this silly thing. The minor gains in code-re-use aren't worth the acrobatics in my situation.
I'm using ES6 classes and my class (A) extends class B and class B extends class C. How can A extend a method and then call C's version of that method.
class C {
constructor() {
console.log('class c');
}
}
class B extends C {
constructor() {
super()
console.log('no, I don\'t want this constructor.');
}
}
class A extends B {
constructor() {
// What should I be doing here? I want to call C's constructor.
super.super();
}
}
Edit: Thanks all, I'm going to stop trying to do this silly thing. The minor gains in code-re-use aren't worth the acrobatics in my situation.
Share Improve this question edited Nov 25, 2024 at 21:47 Barmar 784k57 gold badges548 silver badges659 bronze badges asked Mar 17, 2017 at 15:48 JulianJulian 2,8551 gold badge23 silver badges31 bronze badges 6- 5 There is no code solution to this problem. You have an architecture problem, not a coding problem. – lonesomeday Commented Mar 17, 2017 at 15:56
- 1 You can't do that with classes. Please, explain your case in details, so the proper solution could be suggested. – Estus Flask Commented Mar 17, 2017 at 15:56
-
2
If
B
is aC
, thenB
should be callingsuper
in its constructor to be set up like C. That wayA
calling super gets bothB
andC
's setups. But it sounds likeB
isn't the class you really want to extend from. If this isn't the case, thenA
should extend fromC
directly. – Joseph Commented Mar 17, 2017 at 15:58 - 3 Alternatively, just skip inheritance altogether in favor of position. – Joseph Commented Mar 17, 2017 at 16:02
- 1 you have just one problem. B has to call his super on his own constructor first, and A has to call his own super on his constructor first. so perhaps it's better working with an interface and not a master class? – mtizziani Commented Mar 17, 2017 at 16:05
5 Answers
Reset to default 5You can’t not call the parent’s constructor in an ES6 class. Judging by your ment, maybe you should try something like this?
class Mixin {
static include(constructor) {
const descriptors = Object.getOwnPropertyDescriptors(Mixin.prototype);
Object.keys(descriptors).forEach(name => {
Object.defineProperty(constructor.prototype, name, descriptors[name]);
});
}
someCommonFunction() {
// Perform operation mon to B and C
}
}
delete Mixin.prototype.constructor;
class B extends A {
}
Mixin.include(B);
class C extends A {
}
Mixin.include(C);
Simple but ugly way is to check for instance A
in B
's constructor:
class B extends C {
constructor() {
super()
if (!(this instanceof A)) {
console.log('no, no no, I don\'t want this!');
}
}
}
class A {
constructor() {
console.log('class c');
}
}
class B extends A {
constructor() {
super()
if (!(this instanceof C)) {
console.log('no, no no, I don\'t want this!');
}
}
}
class C extends B {
constructor() {
super();
}
}
const c = new C()
the best way i can think of, which might not necessarily be the best way, is the to define a function in B that calls A's super()
, that way you will inherit that in C by extension and you will have it there ready to go.
class C {
constructor(){
console.log('C');
}
}
class AB extends C {
constructor(){
super();
}
}
class B extexts AB {
constructor(){
super();
console.log('B');
}
}
class A extends AB {
constructor(){
super();
}
}
i think building a class between both and extend A and B from it is the only way because evere constructor has to call his own super constructor first.
new B(); // output is CB
new A(); // output is C
You need quite some acrobatics, and I don't think I would remend this form a 'clean / transparent code' point of view, however it can be done as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
class C {
constructor() {
this.fooExtension = null;
}
initC(aFoo) {
this.fooExtension = aFoo;
}
foo() {
if (this.fooExtension === null) {
console.log('fooFromC');
} else {
console.log('extend foo called from C');
this.fooExtension();
}
}
}
class B extends C {
constructor() {
super();
}
foo() {
super.foo();
}
}
class A extends B {
constructor() {
super();
let fooExtension = function() {
console.log('fooFromA');
};
this.initC(fooExtension);
}
}
c = new C();
c.foo();
a = new A();
a.foo();
</script>
</head>
<body>
</body>
</html>
This will result in the following output:
fooFromC
extend foo called from C
fooFromA