"Demystifying Dart Class Relationships: Implement, Extends, and With Explained"
In our exploration of Dart's inheritance capabilities, we've previously delved into the "extends" and "implements" keywords, uncovering their unique roles in class inheritance and interface implementation. However, the Dart language offers yet another invaluable tool in the form of the "with" keyword. In this article, we will embark on a comprehensive journey into the realm of "with," unlocking its potential to enhance code reusability and composability, further expanding your expertise in Dart's inheritance and mixin mechanisms. Let's dive into the intricacies of the "with" keyword and discover how it empowers your Dart programming endeavors.
With:
To delve into the intricacies of the "with" keyword in Dart, it's imperative to first grasp the concept of Mixins. Are you familiar with Mixins? If not, allow me to introduce them. According to the Dart official website, Mixins are a mechanism for defining reusable code applicable across multiple class hierarchies, designed to provide member implementations en masse. Essentially, Mixins represent ordinary classes devoid of constructors, and their properties and methods can be shared with other classes. Notably, Mixins can't be instantiated, extended by other classes, and they are incorporated into classes using the "with" keyword. So show me the code:
In the above example, we define two Mixins: "Guitarist" and "Drummer". The "Musician" class is then mixed with the "Drummer" mixin. When we invoke the "perform" method, the output reflects the content within our "playDrums" method. So far, so good. Now, let's explore the versatility of Mixins by combining both "Guitarist" and "Drummer" in a single example:
Note that the "Guitarist" mixin includes both abstract and concrete methods. The "Musician" class, now mixed with both "Drummer" and "Guitarist", gains access to all methods from these mixins. It's crucial to implement abstract methods like "playTwoGuitars" using the "@override" annotation. You may be wondering about the "perform" method within the "Drummer" and "Guitarist" mixins and the presence of the "Performer" class. This leads us to the concept of Class Hierarchy, which is pivotal when using mixins. Consider the following example:
领英推荐
In this scenario, the "perform" method is invoked on the "Musician" class. However, which "perform" method will be called? Will it be the drummer's or the guitarist's? Let's run the main function and discuss about it.
So as you can see it printed the guitarist performer, but why? The answer lies in the Class Hierarchy. That's how the hierarchy works, the Dart compiler interprets the "Musician" class hierarchy as follows:
So, the compiler reads as follows: Musician extends Performer with Drummer and Guitarist. Therefore, we should interpret it as Musician extends Performer mixed in with Drummer and Guitarist. Between the Performer and the Musician lies the Performer with Drummer, and the Performer with Drummer and Guitarist. Consequently, the class above the Musician is the Guitarist, elucidating why, upon calling musician.perform(), we observe the message 'Playing the guitar.' Thus, we discern that the order in which we arrange the classes after the 'with' keyword makes a difference. Now, this is a point I'd like to emphasize. Take a look at the code below:
As you can see now we have the "on" keyword on our "Guitarist", so when we use the "on" keyword we can specify witch classes can be actually mixed in with then. In this modification, the "Musician" class no longer extends the "Performer" class, resulting in a compiler error. To resolve this, we extend the "Performer" class in the "Musician" class. Notably, the "Drummer" mixin remains unaffected. The Class Hierarchy concept persists, emphasizing that the order in which classes appear after the "with" keyword remains pivotal.
This exploration highlights the nuances of using mixins in Dart, offering a deeper understanding of their application, Class Hierarchy, and the strategic use of keywords like "with" and "on".
Desenvolvedor Full-Stack | Back-end | Front-end | Javascript | MongoDB | Express | React | NodeJS | Rest API | HTML | CSS | Python | Django | SQL | Postgres
1 年ótima leitura!