Understanding behavior subtyping

Behavior subtyping is sometimes called interface inheritance. In order to avoid confusion with the overloaded word inheritance, we will avoid using the term interface inheritance here. Behavior subtyping says that a subtype only inherits behaviors from the supertype. 

As we switch the language back to Julia, we will refer to types rather than classes.

Julia supports behavior subtyping. Every data type inherits functions that are defined for its supertype. Let's try a quick and fun exercise in the Julia REPL:

Here, an abstract type, Vehicle, is defined with a subtype of Car. We have also defined a move function for Vehicle. When we pass a Car object to the move function, it still works properly because Car is a subtype of Vehicle. This is consistent with the Liskov substitution principle, which says that a program accepting type T can also accept any subtype of T and continue to work properly without any unintended outcome.

Now, the inheritance of a method can travel quite far over multiple levels. Let's create another level of abstraction:

We just defined a new FlyingVehicle abstract type and a Helicopter struct. The move function is available for a helicopter as inherited from Vehicle, and the liftoff function is also available, as inherited from FlyingVehicle

Additional methods can be defined for more specific types, and the most specific one would be chosen for dispatch. Doing this essentially has the same effect as method overrides in implementation inheritance. Here's an example:

So far, we have defined two liftoff methods—one accepting FlyingVehicle and another for Helicopter. When a Helicopter object is passed to the function, it is dispatched to the one defined for Helicopter, because it is the most specific method that works with helicopters.

The relationship can be summarized in the following diagram:

According to behavior subtyping, a car should behave like a vehicle, a flying vehicle should behave like a vehicle, and a helicopter should behave like a flying vehicle and also like a vehicle. Behavior subtyping allows us to reuse the behavior already defined for a supertype.

In Java, behavior subtyping can be achieved using interfaces.

Now that we know about implementation inheritance and behavior subtyping, we can revisit our earlier question: why does Julia not support implementation inheritance? What are the reasons for not following other mainstream OOP languages? In order to understand this, we can review some of the well-known issues with implementation inheritance. Let's start with the square-rectangle problem.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.93.221