Programming in Dart: Classes

Jun 28 2022 · Dart 2.17, Flutter 3.0, DartPad

Part 2: Learn Inheritance

12. Understand Inheritance

Episode complete

Play next episode

Next
About this episode

Leave a rating/review

See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 11. Introduction Next episode: 13. Override Methods

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 12. Understand Inheritance

Often times, you’ll define a class but you may need to make a slight alteration to a class for a specific situation. This is would result in you either copying and pasting the class to make your edits or you’d jury rig some solution that would increase the overall complexity of the class.

Thankfully we have inheritance to help us out. Inheritance allows us to a make specialized version of our class otherwise known as a child class or subclass. We use inheritance to keep the majority of our code the same while we make our selective changes in child classes. Typically, inheritance goes from general to specific. For instance say you were creating a drawing app.

You may decide to draw various shape so you create a shape class that contains an array of 2D points and a method to draw the points.

Then you might define subclasses for specific ways to draw each shape such as a polygon class and a circle class. The circle may allow an image to be drawn in it, so you’d create a textured circle class. Now you have a family of classes all related to each other. Let’s define a couple of classes now.

We are going to start by defining a person class. This person class will have a first name and a last name as well as a method to print out the full name. Open up DartPad and add the following:

class Person {

}

Now let’s add our first name and last name.

String firstName;
String lastName;

Then we lets add a constructor.

Person(this.firstName, this.lastName);

Finally, we’ll add a method to print out the name.

String getFullName() => '$firstName $lastName';

Okay, this looks really good but we’d like to extend this to create a student class. The student will have a first name and last name so it makes sense to extend the Person class. We do this by defining a new class followed by the extends keyword.

class Student extends Person {

}

We are getting an error because we need a constructor. We have two instance variables that we are inheriting so we have to populate them. Add the following constructor.

Student(this.firstName, this.lastName);

Here we are creating a constructor like any other class except we’re getting some errors. That’s because Student doesn’t contain first name or last name. The Person class does. So we have to set the variables on the parent class otherwise known as the super class.

To do this, we can Person constructor. We do this by using the super keyword. Let’s update the Person class to the following:

Student(String firstName, String lastName) : super(firstName, lastName);

This was the standard way of passing in values to the super constructor. With the latest version of Dart, we can now do the following:

Student(super.firstName, super.lastName) 

This makes the code easier to read. Now let’s create a new student. Add the following in main.

var student = Student('Ray', 'Wenderlich');

Now we can print out the name.

print(student.getFullName());

Now run the program. You’ll see the name printed out. Yet, when you look at the Student class, there is only a constructor in it. We used the inherited instance variables and methods. Now in main, let’s add the student and press the period after the name.

student.

You’ll see all the properties and methods. We have a first name and a last name, but also, we have a hash code and a runtime type. Yet you didn’t define those. What’s going on?

Earlier in this course, I stated that in Dart, almost everything is an object.

This is true but also, every object is a child object. That’s right, you’ve been using inheritance all along. You see, Dart defines a root object. Every object extends from this root object.

It gives us a few properties and some methods.

The hashCode property is how we perform equality checks with other objects.

The runtime type is a read only property that lets us know the current runtime of the object. Every object contains these methods.

The toString is what we use to print out our object. Yet, our subclass doesn’t do much. Often times, we want to specialize our subclasses and we can do that by overriding methods which you’ll learn about in the next episode.