/*
classes are functions:
typeof Rectangle
'function'
//----------------------------------------------------------
Javascript is a bit inconsistant when it comes to classes.
We can get the superclass like this:
Object.getPrototypeOf(Rectangle) === Shape
The superclass of Shape is "Object"
But the root class (Object) behaves differently
We might expect this:
Object.getPrototypeOf(Shape) === Object
//but this is false//These are both true:
Object.getPrototypeOf(Shape) === Object.__proto__
Object.getPrototypeOf(Shape) === Object.getPrototypeOf(Object)
This seems to be how we determine we have the Object class
Object.__proto__.__proto__.__proto__
or
aSuper = Object.getPrototypeOf(Shape)
aSuper.__proto__.__proto__
//null//----------------------------------------------------------
*/
class Shape {
helloFromShape() { return "I am a shape"; }
}
class Rectangle extends Shape {
holaFromRec() { return "I am a rectangle"; }
toString() { return "Me Rectangle"; }
}
class CrazyRectangle extends Rectangle {
holaFromRec() { return "I am a crazy rectangle"; }
toString() { return "Me CrazyRectangle"; }
}
class AbstractInterfaceZz {
constructor(anObject) {
this.object = anObject;
}
o() { return this.object; }
}
class ObjectInterfaceZz extends AbstractInterfaceZz {
getClass() {
return this.o().constructor;
}
getClassName() {
return this.getClass().name;
}
getSuperclass() {
return Object.getPrototypeOf(this.getClass());
}
getProto() {
return Object.getPrototypeOf(this.o());
}
getInstanceMethods() {
return Object.getOwnPropertyNames(this.getProto());
}
}
class ClassInterfaceZz extends AbstractInterfaceZz {
getSuperclass() {
return Object.getPrototypeOf(this.o());
}
getSuperclassName() {
let sc = this.getSuperclass();
let nm = sc.name;
if (!nm && sc.__proto__.__proto__ == null)
return 'Object';
return nm;
}
isRootChild() {
//e.g. is our superclass 'Object'//seems we need to be a bit kludy herelet aSuper = this.getSuperclass();
return aSuper.__proto__.__proto__ == null;
}
}
//----------------------------------------------------------------
Object.prototype.zzo = function() {
return new ObjectInterfaceZz(this.valueOf());
}
Object.prototype.zzc = function() {
return new ClassInterfaceZz(this.valueOf());
}
//----------------------------------------------------------------var rec;
let prn = console.log;
rec = new Rectangle();
prn("rec class: " + rec.zzo().getClassName());
prn("rec superclass: " + rec.zzo().getSuperclass().name);
prn(`rec methods: [${rec.zzo().getInstanceMethods()}]`);
prn("rec superclass of superclass (grandparent class): " + rec.zzo().getSuperclass().zzc().getSuperclassName());
let crazy = new CrazyRectangle();
prn("crazy superclass of superclass (grandparent class): " + crazy.zzo().getSuperclass().zzc().getSuperclassName());
let recSuper = rec.zzo().getSuperclass();
prn(`${recSuper.name} is root child: ${recSuper.zzc().isRootChild()}`);
prn(`${Rectangle.name} is root child: ${Rectangle.zzc().isRootChild()}`);
prn(`${AbstractInterfaceZz.name} is root child: ${AbstractInterfaceZz.zzc().isRootChild()}`);
prn(`${ClassInterfaceZz.name} is root child: ${ClassInterfaceZz.zzc().isRootChild()}`);