Let's dive into a foundational concept in Object-Oriented Programming (OOP): Classes and Objects. If you have already explored OOP concepts in other programming languages or previous units, this might serve as a good reminder. If not, no worries — we'll start from the basics.
Classes and objects are the building blocks of OOP. A class acts as a blueprint for creating objects, which are instances of the class. Understanding these basics is essential before moving on to more advanced OOP topics, such as inheritance, polymorphism, and encapsulation.
In TypeScript, a class is defined using the class keyword, just like in many other languages. However, TypeScript allows you to specify types for class properties and constructor parameters, enabling compile-time type checking and reducing runtime errors.
Here's a simple example:
In this snippet, we define a Person class with two properties: name (of type string) and age (of type number). The constructor parameters are also annotated with their respective types. TypeScript will check at compile time that only the correct types are used when creating instances of this class.
An object is an instance of a class. It represents a specific example of the class and holds the characteristics that define the class.
Objects have three main characteristics:
- State: The data or attributes of the object. In the
Personclass, thenameandageare the object's state. - Behavior: The methods and functions that the object can perform. In the
Personclass, thedisplaymethod is mentioned here as an example of behavior, and it will be implemented later in this lesson. - Identity: A unique identifier distinguishes the object from others, even if they have the same state. This is handled by the memory address in the runtime environment.
An object is thus a concrete instance of a class that includes state, behavior, and identity.
Constructors initialize the newly created object's state. In the Person class, we use a constructor to set the name and age, and we specify the types for both the class fields and the constructor parameters. TypeScript's compile-time type checking ensures that only values of the correct type can be assigned.
Here, both name and age are explicitly typed as string and number, respectively. The constructor parameters are also typed, so if you try to pass a value of the wrong type, TypeScript will show a compile-time error. This helps catch mistakes early in the development process.
TypeScript supports constructor overloading through the use of overload signatures. This allows you to define multiple ways to construct an object, each with different parameter types or counts. The actual implementation is a single constructor that handles all cases.
Here's how you can overload constructors in TypeScript:
In this example, the Car class has three constructor overloads:
- One that takes both
brandandyear - One that takes only
brand - One that takes no parameters
The actual constructor implementation uses optional parameters and the nullish coalescing operator (??) to provide default values. TypeScript will enforce the correct usage of these overloads at compile time.
Member functions define the behavior of the object. In TypeScript, you can specify types for method parameters and return values, which are checked at compile time.
For the Person class, we can define a method to display the object's data:
Here, the display method has a return type of void, indicating that it does not return a value. TypeScript will check that the method does not return anything and will also ensure that any parameters (if present) are of the correct type.
Once you have defined a class, you can create objects (instances of the class). Here’s how we can create and use objects of the Person class in TypeScript:
Here, we create an object, person, with the name "Alice" and age 30 by using the constructor of the Person class. The inputs "Alice" and 30 are passed directly to the constructor to initialize the object's state. The type annotation : Person makes it clear that person is an instance of the Person class.
The object then uses its display method to print its data to the console. This demonstrates how to instantiate a class and call its member functions in a TypeScript program, with the added benefit of compile-time type checking.
You might wonder why this is important.
Understanding classes and objects is critical because they enable you to model real-world entities in your programs. For instance, a Person class helps you create multiple person objects with different names and ages, enabling you to manage and manipulate data efficiently. This principle is the backbone of complex software systems.
With this knowledge, you will be better prepared to approach more advanced OOP techniques and design patterns, allowing you to write clean, modular, and scalable code. Let's get started with the practice section to gain more hands-on experience.
Ready to code? Let's dive in!
