Activity 11: Object-Oriented Programming OOP in TypeScript

Research and Study OOP Concepts in TypeScript
Understand how TypeScript implements Object-Oriented Programming principles.
Focus on TypeScript’s features, such as strong typing, access modifiers, and how these enhance OOP practices.
Explain the Core OOP Concepts in TypeScript
For each OOP concept, provide the following details:
Definition: A brief explanation of the concept.
Key Features: The important characteristics of the concept.
How it’s Implemented in TypeScript: Explain how to implement this concept in TypeScript.
Example Code in TypeScript: Provide a code snippet demonstrating how the concept works in TypeScript.
The key OOP concepts to cover are:
Class and Object:
Define what classes and objects are in TypeScript.
Explain how classes act as blueprints and how objects are instances of classes.
Show how to define a class and create an object in TypeScript.
Definition:
Class: A blueprint for creating objects. It defines properties and methods that the created objects will have.
Object: An instance of a class. It contains the actual values for the properties defined in the class.
Key Features:
Encapsulation: Bundling the data (properties) and methods (functions) that operate on the data into a single unit or class.
Inheritance: Creating new classes from existing ones, inheriting properties and methods.
Polymorphism: Allowing objects to be treated as instances of their parent class rather than their actual class.
Abstraction: Hiding the complex implementation details and showing only the necessary features of an object.
Implementation in TypeScript:
TypeScript enhances JavaScript by adding static types and other OOP features. Here’s how you can implement OOP concepts in TypeScript:
Example Code:


This example shows TypeScript's core OOP principles, such as class construction, object generation, inheritance, and method overriding.
Encapsulation:
Define encapsulation and explain how it helps hide the internal details of a class.
Demonstrate how TypeScript uses access modifiers like public, private, and protected to control access to class properties and methods.
Definition:
Encapsulation is a fundamental principle of object-oriented programming (OOP) that involves bundling the data (properties) and methods (functions) that operate on the data into a single unit, typically a class. This concept helps in hiding the internal details of how an object works, exposing only what is necessary through a public interface. This promotes better organization, security, and maintainability in your code.
How Encapsulation Helps:
Hides Internal Details: By restricting access to certain parts of an object, encapsulation prevents external code from directly modifying the internal state of the object. This ensures that the object’s internal state can only be changed in controlled ways.
Improves Security: Encapsulation protects the integrity of the data by preventing unauthorized access and modification.
Enhances Maintainability: By exposing only the necessary parts of an object, encapsulation makes it easier to understand and maintain the code.
Promotes Reusability: Encapsulated code can be reused without exposing its internal workings, making it easier to integrate with other parts of the application.
Access Modifiers in TypeScript:
TypeScript uses access modifiers to control the visibility of class properties and methods. The three main access modifiers are:
public: The default modifier. Properties and methods are accessible from anywhere.
private: Properties and methods are accessible only within the class they are defined.
protected: Properties and methods are accessible within the class and its subclasses.
Example Code:


In this example, the Person class contains public, private, and protected properties and methods. The Employee class extends Person and has access to protected members but not private ones. This illustrates how TypeScript uses encapsulation and access modifiers to regulate access to class properties and methods.
Inheritance:
Define inheritance and explain how one class can inherit the properties and methods of another class in TypeScript.
Demonstrate how to use the extends keyword and how to override methods from the parent class.
Definition:
Inheritance is a core concept in object-oriented programming (OOP) that allows a class (known as a child or subclass) to inherit properties and methods from another class (known as a parent or superclass). This promotes code reusability and establishes a natural hierarchy between classes.
How Inheritance Works in TypeScript:
In TypeScript, inheritance is implemented using the extends keyword. When a class extends another class, it inherits all the properties and methods of the parent class. The child class can also override methods from the parent class to provide specific implementations.
Example Code:


In this example:
The
Animalclass is the parent class with a propertynameand a methodmove.The
Dogclass extendsAnimal, inheriting its properties and methods.The
Dogclass overrides themovemethod to provide a specific implementation. It also calls the parent class’smovemethod usingsuper.move(distanceInMeters).
This demonstrates how inheritance allows a child class to reuse and extend the functionality of a parent class in TypeScript.
Polymorphism:
Define polymorphism and explain how it allows for different classes to be treated as instances of the same parent class.
Show examples of both method overriding (runtime polymorphism) and method overloading (compile-time polymorphism) in TypeScript.
Definition:
Polymorphism is a key concept in object-oriented programming (OOP) that allows objects of different classes to be treated as instances of the same parent class. This enables a single interface to represent different underlying forms (data types). Polymorphism provides flexibility and reusability in code by allowing the same operation to behave differently on different classes.
How Polymorphism Works:
Runtime Polymorphism (Method Overriding): This occurs when a subclass provides a specific implementation of a method that is already defined in its superclass. The method in the subclass overrides the method in the superclass.
Compile-time Polymorphism (Method Overloading): This occurs when multiple methods in the same class have the same name but different parameters (different type or number of arguments). TypeScript supports method overloading through function declarations.
Example Code:
Method Overriding (Runtime Polymorphism):


this example, the makeSound method is overridden in the Dog and Cat classes. The makeAnimalSound function can accept any object of type Animal, demonstrating polymorphism by calling the appropriate makeSound method based on the actual object type.
Method Overloading (Compile-time Polymorphism):

this example, the add method is overloaded to handle both numbers and strings. The actual implementation uses a single method that can handle both types, demonstrating compile-time polymorphism.
Polymorphism allows for more flexible and reusable code by enabling objects to be treated as instances of their parent class and by allowing methods to operate on different types of data.
Abstraction:
Define abstraction and explain its purpose in OOP.
Demonstrate how to use abstract classes and interfaces in TypeScript to implement abstraction.
Definition:
Abstraction is a fundamental concept in object-oriented programming (OOP) that involves hiding the complex implementation details of a system and exposing only the essential features. This allows developers to work with higher-level concepts without needing to understand the underlying complexity.
Purpose of Abstraction in OOP:
Simplifies Code: By hiding the implementation details, abstraction makes the code easier to understand and maintain.
Enhances Reusability: Abstract components can be reused across different parts of an application or even in different projects.
Improves Flexibility: Changes to the implementation details do not affect the code that uses the abstracted components.
Promotes Encapsulation: Abstraction naturally leads to better encapsulation by separating the interface from the implementation.
Implementing Abstraction in TypeScript:
Abstract Classes:
Abstract classes in TypeScript are used as a blueprint for other classes. They cannot be instantiated directly and can contain both abstract methods (methods without implementation) and concrete methods (methods with implementation).

this example, Animal is an abstract class with an abstract method makeSound and a concrete method move. The dog class extends animals and provides an implementation for makeSound method.
Interfaces:
Interfaces in TypeScript define the structure that a class must adhere to. They can include properties and method signatures but do not provide implementations.

this example, the Shape interface defines the structure for shapes with area and perimeter methods. The rectangle class implementation
Additional OOP Concepts to Include:
Interfaces:
Explain what an interface is in TypeScript and how it defines the structure of an object without providing implementation details.
Show how interfaces help in achieving abstraction.
An interface in TypeScript defines the structure of an object by specifying the properties and methods that the object should have, without providing implementation details. Interfaces are used to enforce a certain structure on objects, ensuring that they adhere to a specific contract.
How Interfaces Help in Achieving Abstraction:
Interfaces help in achieving abstraction by allowing you to define the shape of an object without specifying how the object should be implemented. This means you can define what an object should do, but not how it should do it. This separation of concerns makes your code more modular and easier to maintain.
Example Code:


this example, the Vehicle interface defines the structure that any vehicle should have. The Car class implements this interface, providing the actual implementation for the start and stop methods.
Constructor Overloading:
Explain how TypeScript allows multiple constructor definitions using optional parameters.
Show an example of implementing constructor overloading.
How TypeScript Allows Multiple Constructor Definitions:
TypeScript does not support traditional constructor overloading like some other languages (e.g., Java or C#). However, you can achieve similar functionality using optional parameters or union types.
Example Code:

this example, the Box class constructor uses optional parameters to allow for different ways of creating a Box object. If only one parameter is provided, it creates a cube; if three parameters are provided, it creates a rectangular box.
Getters and Setters:
Explain how TypeScript provides get and set methods for encapsulating access to properties.
Provide an example showing how to define and use getters and setters in TypeScript.
How TypeScript Provides Get and Set Methods:
TypeScript allows you to define getter and setter methods to encapsulate access to class properties. Getters are used to retrieve the value of a property, while setters are used to modify the value, often with additional validation or logic.
Example Code:


this example, the Person class uses getter and setter methods to control access to the _age property. The setter method includes validation to ensure the age is within a valid range.



