Skip to main content
added 789 characters in body
Source Link
DeadMG
  • 36.9k
  • 8
  • 73
  • 141

This is a general OOP question, assuming polymorphism, generics, and mixins are available. The actual language to be used is OOP Javascript (Typescript), but it's the same problem in Java or C++.

That's actually not true at all. Typescript has a substantial advantage over Java- namely, structural typing. You can do something similar in C++ with duck typed templates, but it's a lot more effort.

Basically, define your classes, but do not bother extending or defining any interfaces. Then simply define the interface you need and take it as a parameter. Then, the objects can match that interface- they don't need to know to extend it in advance. Each function can declare exactly and only the bits they give a shit about, and the compiler will give you a pass if the final type meets it, even though the classes don't actually extend those interfaces explicitly.

This frees you from the need to actually define an interface hierarchy and define which classes should extend which interfaces.

Just define each class and forget about the interfaces- structural typing will take care of it.

For example:

class SVGViewee {
    validate() { /* stuff */ }
    addChild(svg: SVG) { /* stuff */ }
}
class CanvasViewee {
    validate() { /* stuff */ }
    paint() { /* stuff */ }
}
interface SVG {
    addChild: { (svg: SVG): void };
}
f(viewee: { validate: { (): boolean }; }) {
    viewee.validate();
}
g(svg: SVG) {
    svg.addChild(svg);
}
h(canvas: { paint: { (): void }; }) {
    canvas.paint();
}
f(SVGViewee());
f(CanvasViewee());
g(SVGViewee());
h(CanvasViewee());

This is totally legitimate Typescript. Notice that the consuming functions don't know or give a single shit about the base classes or interfaces used in the definition of the classes.

It doesn't matter if the classes are related or not by inheritance. It doesn't matter if they extended your interface. Just define the interface as the parameter, and you're done- all classes that meet it are accepted.

This is a general OOP question, assuming polymorphism, generics, and mixins are available. The actual language to be used is OOP Javascript (Typescript), but it's the same problem in Java or C++.

That's actually not true at all. Typescript has a substantial advantage over Java- namely, structural typing. You can do something similar in C++ with duck typed templates, but it's a lot more effort.

Basically, define your classes, but do not bother extending or defining any interfaces. Then simply define the interface you need and take it as a parameter. Then, the objects can match that interface- they don't need to know to extend it in advance. Each function can declare exactly and only the bits they give a shit about, and the compiler will give you a pass if the final type meets it, even though the classes don't actually extend those interfaces explicitly.

This frees you from the need to actually define an interface hierarchy and define which classes should extend which interfaces.

Just define each class and forget about the interfaces- structural typing will take care of it.

This is a general OOP question, assuming polymorphism, generics, and mixins are available. The actual language to be used is OOP Javascript (Typescript), but it's the same problem in Java or C++.

That's actually not true at all. Typescript has a substantial advantage over Java- namely, structural typing. You can do something similar in C++ with duck typed templates, but it's a lot more effort.

Basically, define your classes, but do not bother extending or defining any interfaces. Then simply define the interface you need and take it as a parameter. Then, the objects can match that interface- they don't need to know to extend it in advance. Each function can declare exactly and only the bits they give a shit about, and the compiler will give you a pass if the final type meets it, even though the classes don't actually extend those interfaces explicitly.

This frees you from the need to actually define an interface hierarchy and define which classes should extend which interfaces.

Just define each class and forget about the interfaces- structural typing will take care of it.

For example:

class SVGViewee {
    validate() { /* stuff */ }
    addChild(svg: SVG) { /* stuff */ }
}
class CanvasViewee {
    validate() { /* stuff */ }
    paint() { /* stuff */ }
}
interface SVG {
    addChild: { (svg: SVG): void };
}
f(viewee: { validate: { (): boolean }; }) {
    viewee.validate();
}
g(svg: SVG) {
    svg.addChild(svg);
}
h(canvas: { paint: { (): void }; }) {
    canvas.paint();
}
f(SVGViewee());
f(CanvasViewee());
g(SVGViewee());
h(CanvasViewee());

This is totally legitimate Typescript. Notice that the consuming functions don't know or give a single shit about the base classes or interfaces used in the definition of the classes.

It doesn't matter if the classes are related or not by inheritance. It doesn't matter if they extended your interface. Just define the interface as the parameter, and you're done- all classes that meet it are accepted.

Source Link
DeadMG
  • 36.9k
  • 8
  • 73
  • 141

This is a general OOP question, assuming polymorphism, generics, and mixins are available. The actual language to be used is OOP Javascript (Typescript), but it's the same problem in Java or C++.

That's actually not true at all. Typescript has a substantial advantage over Java- namely, structural typing. You can do something similar in C++ with duck typed templates, but it's a lot more effort.

Basically, define your classes, but do not bother extending or defining any interfaces. Then simply define the interface you need and take it as a parameter. Then, the objects can match that interface- they don't need to know to extend it in advance. Each function can declare exactly and only the bits they give a shit about, and the compiler will give you a pass if the final type meets it, even though the classes don't actually extend those interfaces explicitly.

This frees you from the need to actually define an interface hierarchy and define which classes should extend which interfaces.

Just define each class and forget about the interfaces- structural typing will take care of it.