Note: None of this has been implemented.
Inheritance makes it easy to declare a new type that reuses (inherits) the fields or methods defined by some other type.
Cone's version of inheritance looks and behaves somewhat differently than in other languages, which is why it is called delegated inheritance. At its heart, Cone's inheritance is a composition-based approach that offers convenient namespace "sugar" for automatically forwarding certain method (or field) access requests. This makes method reuse (forwarding) easy to accomplish, where needed, while side-stepping the tightly-coupled complexity and fragility sometimes experienced when using traditional inheritance.
Selective Inheritance
Imagine we have this Engine type:
struct Engine fuel f32 torque f32 fn thrust(amt f32) { ... } fn power(on Bool) { ... }
Now, let's create a new Car type that includes, and inherits from, an Engine:
struct Car: engine Engine use fuel, thrust body SportyLook wheels RimWheels
The use of the use keyword on the engine field ensures that every Car object inherits the fuel field and thrust method from Engine by way of engine. Effectively, we are requesting automatic namespace-forwarding magic, such that:
- any access to car.fuel is treated as equivalent to car.engine.fuel.
- car.thrust(23.2) is treated as equivalent to car.engine.thrust(23.2) It is important to note that the thrust will be called with self being the engine, and not the car. If one needs a thrust method that operates on car, then don't have Car inherit it from engine. Implement it in Car and then explicitly call engine's thrust as part of its logic, if desired.
A type may inherit names from more than one field.
Name Aliasing
Inherited names must be unique. It is an error to inherit names that are otherwise defined by the type. Similarly, it is an error to inherit the same name from two different fields.
To avoid such name conflicts, a name may be inherited using an alias. For example use fuel as fuelamt, thrust would support the use of car.fuelamt as an alias for car.engine.fuel.
Total Inheritance
If a field specifies use *, all fields are inherited. Additionally, this inherits every method not explicitly implemented by the new type. For example:
struct SuperEngine: engine Engine use * fn power(on Bool) { ... }
SuperEngine inherits the fields fuel and torque, as well as the thrust method from engine. It does not inherit the power method, since it has its own implementation of it.
When a type inherits all the fields of another type, its constructor may name those fields individually or collectively. Thus, SuperEngine[engine: Engine[fuel: 1.0, torgue: 2.0]] and SuperEngine[fuel: 1.0, torgue: 2.0] are equivalent and equally acceptable.