Полиморфизм и наследование в ООП: чем отличаются и примеры
Полиморфизм и наследование являются двумя основными концепциями объектно-ориентированного программирования (ООП). Хотя эти концепции связаны между собой, они имеют свои собственные уникальные особенности.
Наследование - это процесс создания нового класса на основе уже существующего класса, известного как базовый класс или суперкласс. При наследовании производный класс наследует свойства и методы базового класса. Это позволяет создавать иерархию классов, где производные классы расширяют функциональность базовых классов. Таким образом, наследование позволяет повторно использовать код и создавать более чистый и организованный код.
Полиморфизм - это концепция, в которой один и тот же метод может работать с разными типами объектов. Полиморфизм позволяет использовать один и тот же метод для объектов разных классов, что упрощает кодирование и повышает гибкость. Полиморфизм может быть реализован через перегрузку методов или через виртуальные методы и интерфейсы.
Пример полиморфизма
Для демонстрации полиморфизма на языке TypeScript можно рассмотреть пример работы с классами и методами.
Предположим, у нас есть базовый класс "Фигура
", который имеет метод для вычисления ее площади, а также два производных класса: "Прямоугольник
" и "Круг
". Каждый из этих классов имеет свои специфические свойства и методы, но все они реализуют метод для вычисления площади.
Вот пример кода на TypeScript:
class Shape {
calculateArea(): number {
return 0;
}
}
class Rectangle extends Shape {
private width: number;
private height: number;
constructor(width: number, height: number) {
super();
this.width = width;
this.height = height;
}
calculateArea(): number {
return this.width * this.height;
}
}
class Circle extends Shape {
private radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
calculateArea(): number {
return Math.PI * this.radius * this.radius;
}
}
В этом примере мы определяем базовый класс "Фигура
" с методом "calculateArea()
", который возвращает значение 0
. Затем мы определяем производный класс "Прямоугольник
" и "Круг
" с их собственными свойствами и методами. Обратите внимание, что каждый из этих классов переопределяет метод "calculateArea()
" собственной реализацией вычисления площади.
Теперь мы можем создать массив объектов этих классов и вызвать метод "calculateArea()
" на каждом из них, не заботясь о типе каждого элемента массива:
const shapes: Shape[] = [new Rectangle(10, 20), new Circle(5)];
for (const shape of shapes) {
console.log(shape.calculateArea());
}
Это и есть пример полиморфизма. Метод "calculateArea()
" в базовом классе "Фигура
" может быть использован для объектов разных типов (прямоугольника и круга), и при этом будет вызываться соответствующая реализация для каждого типа. Таким образом, код становится более гибким и расширяемым, поскольку мы можем легко добавлять новые типы фигур, не меняя существующий код.
Пример наследования
Концепция наследования в объектно-ориентированном программировании означает, что производный класс наследует свойства и методы базового класса. Давайте рассмотрим пример на TypeScript, чтобы продемонстрировать наследование классов:
class Animal {
private name: string;
constructor(name: string) {
this.name = name;
}
move(distanceInMeters: number = 0) {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
bark() {
console.log('Woof! Woof!');
}
}
// Создание экземпляров классов
const animal = new Animal('Animal');
const dog = new Dog('Buddy');
// Вызов методов на экземплярах классов
animal.move(); // Output: Animal moved 0m.
dog.move(10); // Output: Buddy moved 10m.
dog.bark(); // Output: Woof! Woof!
В этом примере у нас есть базовый класс Animal
с конструктором и методом move()
, а также производный класс Dog
, который наследует от Animal
. Dog
также имеет собственный метод bark()
.
Мы создаем экземпляры Animal
и Dog
и вызываем методы move()
и bark()
на каждом из них. Обратите внимание, что Dog
наследует метод move()
от Animal
, и поэтому мы можем вызвать его на экземпляре Dog
.
Таким образом, наследование в TypeScript позволяет создавать новые классы на основе уже существующих, повторно используя код и добавляя новые свойства и методы.
Заключение
Таким образом, наследование и полиморфизм - это два ключевых понятия ООП, которые позволяют создавать более гибкий и организованный код. Наследование позволяет расширять функциональность классов, а полиморфизм позволяет использовать один и тот же метод для разных объектов.