-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1f0ca2f
Showing
54 changed files
with
4,447 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
45 changes: 45 additions & 0 deletions
45
Classes & Interfaces/Constructor Functions & The this Keyword.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Constructor Functions & The "this" Keyword | ||
|
||
## Introduction | ||
|
||
Constructor functions in TypeScript are used to create and initialize objects based on a class. These functions are called when an instance of the class is created using the `new` keyword. The `this` keyword refers to the instance being created, allowing you to set and access properties specific to that instance. | ||
|
||
## Example | ||
```tsx | ||
class Person { | ||
// Properties | ||
name: string; | ||
age: number; | ||
|
||
// Constructor function | ||
constructor(name: string, age: number) { | ||
// Using the "this" keyword to refer to instance properties | ||
this.name = name; | ||
this.age = age; | ||
} | ||
|
||
// Method | ||
introduce(): string { | ||
return `Hello, my name is ${this.name} and I am ${this.age} years old.`; | ||
} | ||
} | ||
|
||
// Creating an instance of the class using the constructor | ||
const person1 = new Person("Alice", 25); | ||
|
||
// Accessing properties and calling methods | ||
console.log(person1.name); // Output: Alice | ||
console.log(person1.age); // Output: 25 | ||
console.log(person1.introduce()); // Output: Hello, my name is Alice and I am 25 years old. | ||
``` | ||
|
||
In this example: | ||
|
||
1. The `Person` class has two properties, `name` and `age`, and a constructor function that initializes these properties when an instance is created. | ||
2. Inside the constructor, `this` refers to the instance being created (e.g., `person1`). The properties `name` and `age` are assigned values specific to that instance. | ||
3. The `introduce` method uses `this` to access the properties of the instance it is called on. | ||
4. When `person1.introduce()` is called, the `this` keyword inside the `introduce` method refers to `person1`, and the method returns a string using the properties of that instance. | ||
|
||
It's important to note that the use of classes and constructor functions is a feature of ES6 (ECMAScript 2015) and later versions of JavaScript. TypeScript enhances this by providing static typing and additional features. | ||
|
||
In summary, constructor functions in TypeScript play a crucial role in initializing object instances by setting their properties using the `this` keyword. They contribute to creating organized and reusable code with class-based structures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Getters & Setters | ||
|
||
## Introduction | ||
|
||
Getters and setters are special methods that allow you to control the access and modification of class properties. Getters are used to retrieve the value of a property, while setters are used to modify the value of a property. They provide a way to encapsulate the internal representation of an object and add behavior when getting or setting its properties. | ||
|
||
Here's an example demonstrating the use of getters and setters: | ||
|
||
```tsx | ||
class Circle { | ||
private _radius: number; | ||
|
||
constructor(radius: number) { | ||
this._radius = radius; | ||
} | ||
|
||
// Getter for the radius property | ||
get radius(): number { | ||
console.log("Getting radius"); | ||
return this._radius; | ||
} | ||
|
||
// Setter for the radius property | ||
set radius(newRadius: number) { | ||
if (newRadius >= 0) { | ||
console.log("Setting radius"); | ||
this._radius = newRadius; | ||
} else { | ||
console.error("Radius must be a non-negative value"); | ||
} | ||
} | ||
|
||
// Getter for calculating the area | ||
get area(): number { | ||
console.log("Calculating area"); | ||
return Math.PI * this._radius ** 2; | ||
} | ||
} | ||
|
||
// Creating an instance of the class | ||
const myCircle = new Circle(5); | ||
|
||
// Using the getter to retrieve the radius | ||
console.log(myCircle.radius); // Output: Getting radius, 5 | ||
|
||
// Using the setter to update the radius | ||
myCircle.radius = 8; // Output: Setting radius | ||
|
||
// Using the getter for calculating the area | ||
console.log(myCircle.area); // Output: Calculating area, 201.06192982974676 | ||
|
||
// Attempting to set a negative radius (error message from the setter) | ||
myCircle.radius = -3; // Output: Radius must be a non-negative value | ||
``` | ||
|
||
In this example: | ||
|
||
- The `Circle` class has a private property `_radius` and exposes it using a getter and setter. | ||
- The getter for `radius` allows retrieving the value of the `_radius` property with additional behavior (in this case, logging). | ||
- The setter for `radius` allows updating the value of `_radius` with validation logic to ensure the radius is non-negative. | ||
- A getter for `area` is included, demonstrating that getters can be used for computed properties. | ||
- The instance of `Circle` (`myCircle`) is created and accessed using the getter and setter. | ||
|
||
### Use Cases: | ||
|
||
1. **Encapsulation:** | ||
- Getters and setters provide a way to encapsulate the internal representation of an object, allowing controlled access to properties. | ||
2. **Validation:** | ||
- Setters can include validation logic to ensure that property values meet certain criteria. | ||
3. **Computed Properties:** | ||
- Getters can be used to calculate and return derived or computed properties based on other properties. | ||
4. **Logging and Side Effects:** | ||
- Getters and setters can be used to log property access or modification and perform additional side effects. | ||
5. **Property Access Control:** | ||
- Getters and setters allow you to control read and write access to properties, enabling fine-grained access control. | ||
|
||
By using getters and setters in TypeScript, you can design classes that provide a clean and controlled interface for accessing and modifying their properties, promoting encapsulation and maintaining the integrity of the object's state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# Inheritance | ||
|
||
## Introduction | ||
|
||
Inheritance is a mechanism that allows a class (called the derived or child class) to inherit properties and methods from another class (called the base or parent class). This promotes code reuse and the creation of hierarchies of related classes. The `extends` keyword is used to establish inheritance. | ||
|
||
```tsx | ||
// Base class | ||
class Animal { | ||
// Properties | ||
name: string; | ||
|
||
// Constructor | ||
constructor(name: string) { | ||
this.name = name; | ||
} | ||
|
||
// Method | ||
makeSound(): string { | ||
return "Some generic sound"; | ||
} | ||
} | ||
|
||
// Derived class inheriting from Animal | ||
class Dog extends Animal { | ||
// Additional property | ||
breed: string; | ||
|
||
// Constructor | ||
constructor(name: string, breed: string) { | ||
// Calling the constructor of the base class using super() | ||
super(name); | ||
this.breed = breed; | ||
} | ||
|
||
// Overriding the makeSound method | ||
makeSound(): string { | ||
return "Woof!"; | ||
} | ||
|
||
// Additional method | ||
fetch(): string { | ||
return "Fetching the ball!"; | ||
} | ||
} | ||
|
||
// Creating an instance of the derived class | ||
const myDog = new Dog("Buddy", "Golden Retriever"); | ||
|
||
// Accessing inherited properties and methods | ||
console.log(myDog.name); // Output: Buddy | ||
console.log(myDog.makeSound()); // Output: Woof! | ||
console.log(myDog.fetch()); // Output: Fetching the ball! | ||
``` | ||
|
||
In this example: | ||
|
||
- The `Animal` class is the base class, and the `Dog` class is the derived class. | ||
- The `Dog` class uses the `extends` keyword to inherit from the `Animal` class. | ||
- The `super` keyword is used in the constructor of the derived class to call the constructor of the base class and initialize inherited properties. | ||
- The `makeSound` method is overridden in the derived class, providing a specific implementation for dogs. | ||
- The `Dog` class introduces an additional property (`breed`) and an additional method (`fetch`). | ||
|
||
### Access Modifiers in Inheritance: | ||
|
||
In TypeScript, access modifiers (`public`, `protected`, and `private`) can be used to control the visibility of members within a class and its subclasses: | ||
|
||
- `public`: Visible to everyone (default if not specified). | ||
- `protected`: Visible to the class and its subclasses. | ||
- `private`: Visible only within the class. | ||
|
||
```tsx | ||
class Animal { | ||
private age: number; | ||
|
||
constructor(age: number) { | ||
this.age = age; | ||
} | ||
|
||
protected getAge(): number { | ||
return this.age; | ||
} | ||
} | ||
|
||
class Dog extends Animal { | ||
// The age property is not directly accessible here | ||
|
||
getDogAge(): number { | ||
// Accessing the protected method from the base class | ||
return this.getAge(); | ||
} | ||
} | ||
|
||
const myDog = new Dog(3); | ||
// Error: Property 'age' is private and only accessible within class 'Animal'. | ||
// console.log(myDog.age); | ||
|
||
// Accessing the protected method from the derived class | ||
console.log(myDog.getDogAge()); // Output: 3 | ||
``` | ||
|
||
### Use Cases: | ||
|
||
- **Code Reusability:** | ||
- Inheritance allows the reuse of code from existing classes, reducing redundancy. | ||
- **Polymorphism:** | ||
- Derived classes can provide specific implementations for methods defined in the base class, allowing polymorphic behavior. | ||
- **Extending Functionality:** | ||
- Derived classes can extend the functionality of the base class by introducing new properties and methods. | ||
- **Creating Hierarchies:** | ||
- Inheritance is useful for creating class hierarchies, representing relationships between different types of objects. | ||
|
||
Inheritance is a powerful feature in TypeScript that enables the creation of more organized and reusable code by allowing classes to build upon the functionality of other classes. |
73 changes: 73 additions & 0 deletions
73
Classes & Interfaces/Overriding Properties & The protected Modifier.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Overriding Properties & The "protected" Modifier | ||
|
||
## Introduction | ||
|
||
When you extend a class and override its methods or properties, you can use the `protected` modifier to control access to those members. The `protected` modifier allows the member to be accessed within the class and its subclasses but not from external code. | ||
|
||
Here's an example demonstrating property overriding and the use of the `protected` modifier: | ||
|
||
```tsx | ||
// Base class | ||
class Animal { | ||
// Protected property | ||
protected sound: string; | ||
|
||
// Constructor | ||
constructor(sound: string) { | ||
this.sound = sound; | ||
} | ||
|
||
// Method | ||
makeSound(): string { | ||
return this.sound; | ||
} | ||
} | ||
|
||
// Derived class inheriting from Animal | ||
class Dog extends Animal { | ||
// Constructor with additional parameter | ||
constructor(sound: string, private breed: string) { | ||
// Calling the constructor of the base class using super() | ||
super(sound); | ||
} | ||
|
||
// Overriding the makeSound method | ||
makeSound(): string { | ||
// Accessing the protected property from the base class | ||
const baseSound = super.makeSound(); | ||
|
||
// Adding breed information | ||
return `${baseSound} (Breed: ${this.breed})`; | ||
} | ||
} | ||
|
||
// Creating an instance of the derived class | ||
const myDog = new Dog("Woof", "Golden Retriever"); | ||
|
||
// Accessing overridden method | ||
console.log(myDog.makeSound()); // Output: Woof (Breed: Golden Retriever) | ||
|
||
// Accessing the protected property from the base class is not allowed externally | ||
// Error: Property 'sound' is protected and only accessible within class 'Animal' and its subclasses. | ||
// console.log(myDog.sound); | ||
``` | ||
|
||
In this example: | ||
|
||
- The `Animal` class has a `protected` property `sound`. This property is accessible within the class and its subclasses but not externally. | ||
- The `Dog` class extends `Animal` and overrides the `makeSound` method. It uses the `super` keyword to call the overridden method from the base class. | ||
- The `Dog` class has an additional private property (`breed`), and the `makeSound` method combines the base sound with the breed information. | ||
- The `sound` property from the base class is not directly accessible from external code. | ||
|
||
### Use Cases: | ||
|
||
1. **Overriding Methods:** | ||
- The `protected` modifier is often used when overriding methods to allow subclasses to access and modify certain aspects of the behavior. | ||
2. **Extending Functionality:** | ||
- Subclasses can add additional properties or methods while building upon the functionality of the base class. | ||
3. **Encapsulation:** | ||
- Using `protected` helps encapsulate the internal details of a class and provides controlled access to its members. | ||
4. **Polymorphism:** | ||
- Overriding methods and properties enables polymorphic behavior, allowing different classes to be used interchangeably. | ||
|
||
In summary, the `protected` modifier in TypeScript is useful when designing class hierarchies and allows for controlled access to properties and methods within a class and its subclasses. This promotes encapsulation and supports the principles of object-oriented programming. |
79 changes: 79 additions & 0 deletions
79
Classes & Interfaces/Private and Public Access Modifiers.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# "Private" and "Public" Access Modifiers | ||
|
||
## Introduction | ||
|
||
Access modifiers in TypeScript, such as `private` and `public`, are used to control the visibility of class members (properties and methods) within a class and its subclasses. They help enforce encapsulation and define how properties and methods can be accessed from outside the class. | ||
|
||
### `Private` Access Modifier: | ||
|
||
When a class member is marked as `private`, it can only be accessed within the class where it is defined. It is not accessible from outside the class, including from instances of the class or its subclasses. | ||
|
||
```tsx | ||
class Car { | ||
private speed: number; | ||
|
||
constructor(speed: number) { | ||
this.speed = speed; | ||
} | ||
|
||
accelerate(increment: number): void { | ||
this.speed += increment; | ||
} | ||
|
||
displaySpeed(): void { | ||
console.log(`Current speed: ${this.speed} km/h`); | ||
} | ||
} | ||
|
||
// Creating an instance of the class | ||
const myCar = new Car(50); | ||
|
||
// Accessing a private member will result in a TypeScript compilation error | ||
// Uncommenting the line below will result in an error: | ||
// myCar.speed = 60; | ||
|
||
// Calling public methods is allowed | ||
myCar.accelerate(10); | ||
myCar.displaySpeed(); // Output: Current speed: 60 km/h | ||
``` | ||
|
||
In this example, the `speed` property is marked as `private`, making it inaccessible from outside the `Car` class. | ||
|
||
### `public` Access Modifier: | ||
|
||
By default, class members are considered `public` if no access modifier is specified. `public` members are accessible from outside the class. | ||
|
||
```tsx | ||
class Animal { | ||
// By default, "legs" is public | ||
legs: number; | ||
|
||
constructor(legs: number) { | ||
this.legs = legs; | ||
} | ||
|
||
displayLegs(): void { | ||
console.log(`Number of legs: ${this.legs}`); | ||
} | ||
} | ||
|
||
// Creating an instance of the class | ||
const dog = new Animal(4); | ||
|
||
// Accessing public members is allowed | ||
dog.legs = 3; // Allowed | ||
dog.displayLegs(); // Output: Number of legs: 3 | ||
``` | ||
|
||
In this example, the `legs` property is implicitly `public`, and it can be accessed and modified from outside the `Animal` class. | ||
|
||
### Use Cases: | ||
|
||
- **`private` Access Modifier:** | ||
- Use `private` for class members that should not be accessible from outside the class. This helps encapsulate internal details and prevents external interference. | ||
- **`public` Access Modifier:** | ||
- By default, members are `public`, and this is suitable for properties and methods that need to be accessed externally. | ||
- **Encapsulation:** | ||
- Access modifiers contribute to encapsulation by controlling the visibility of class members, improving code organization and maintainability. | ||
|
||
By using `private` and `public` access modifiers appropriately, you can design classes with a clear and controlled interface, enhancing the maintainability and robustness of your TypeScript code. |
Oops, something went wrong.