JavaScript · Синтаксис · Начальный уровень
ООП: наследование и переопределение методов
Задачи по ООП в JavaScript на наследование, super(), constructor, переопределение методов, toString(), собственные методы классов и работу с объектами.
Краткое введение в тему и пояснения перед упражнениями (упражнения ниже):
toString() и пользовательские методы
#Паттерны наследования и методов
#Упражнения:
Animal и Dog через наследование.
#Создайте класс Animal , у создаваемых им объектов должен быть свойство name . Значение в свойство передается при создании объекта через constructor. То есть - объект описывает животное (любое) и хранит его кличку. Потом создайте класс Dog , который наследуется от Animal . В классе Dog добавьте метод toString , который возвращает строку в которой содержится тип животного (ахахах, извиняюсь, "тип животного" смешно звучит) и его кличка: "Dog: Rex" # пример возвращаемой строки Смысл такой: Базовый класс Animal хранит основное "поведение" объектов животных, а класс Dog детализирует под конкретный тип животного.
class Animal {
// ваш код здесь
}
class Dog extends Animal {
// ваш код здесь
}
Решение
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
toString() {
return `Dog: ${this.name}`;
}
}
Book со строковым представлением.
#Создайте класс Book с свойствами объектов title и pages . Добавьте метод toString(), который возвращает: "Book: JavaScript Basics (120 pages)" Можно добавить метод length() который будет возвращать количество страниц книги.
class Book {
// ваш код здесь
}
Решение
class Book {
constructor(title, pages) {
this.title = title;
this.pages = pages;
}
length() {
return this.pages;
}
toString() {
return `Book: ${this.title} (${this.pages} pages)`;
}
}
User и Admin.
#Давайте похожее на 1е прогоним еще раз: Условие: Создайте класс User со свойством name . Создайте класс Admin , который наследуется от User . Переопределите метод toString , чтобы вывод был: "Admin: Alex" А у просто User выводилось через toString просто: "Alex"
class User {
// ваш код здесь
}
class Admin extends User {
// ваш код здесь
}
Решение
class User {
constructor(name) {
this.name = name;
}
toString() {
return this.name;
}
}
class Admin extends User {
toString() {
return `Admin: ${this.name}`;
}
}
Коробка с предметами.
#Создайте класс Box со свойством items_count . Добавьте метод length(), который возвращает количество предметов. И добавьте метод add и remove которые могут класть и забирать объект из коробки. Это можно сделать просто по счетчику items_count (просто считать без сложностей), или сделать массив предметов в коробке (строк) и подогнать класс для работы со массивом (массив свойство объекта).
class Box {
// ваш код здесь
}
Решение
class Box {
constructor(itemsCount) {
this.itemsCount = itemsCount;
}
add(count) {
if (count > 0) {
this.itemsCount += count;
}
}
remove(count) {
if (count > 0) {
this.itemsCount -= count;
if (this.itemsCount < 0) {
this.itemsCount = 0;
}
}
}
getCount() {
return this.itemsCount;
}
}
Message со спам-флагом.
#Создайте класс Message со свойствами text и spam. Значение text передаётся при создании объекта через constructor, а spam изначально равно null. Добавьте методы: isSpam() — проверяет, есть ли в тексте слова, похожие на спам, возвращает true/false и записывает результат в this.spam; length() — возвращает длину текста.
class Message {
// ваш код здесь
}
Решение
class Message {
constructor(text) {
this.text = text;
this.spam = null;
this.spamTriggers = ["куплю", "дорого"];
}
isSpam() {
if (this.spam !== null) {
return this.spam;
}
for (let trigger of this.spamTriggers) {
if (this.text.toLowerCase().includes(trigger)) {
this.spam = true;
return true;
}
}
this.spam = false;
return false;
}
length() {
return this.text.length;
}
}
let m = new Message("Куплю старые телевизоры дорого!!!");
console.log(m.isSpam());
console.log(m.length());
Employee и Manager.
#Создайте класс Employee (работник) с свойствами name и salary . Сделайте метод у Employee который может менять зарплату. Создайте класс Manager , который наследуется от Employee . Переопределите метод toString так, чтобы вывод был: Manager John earns 5000 Убедитесь что метод изменения зарплаты работает и для Manager
class Employee {
// ваш код здесь
}
class Manager extends Employee {
// ваш код здесь
}
Решение
class Employee {
constructor(name, salary) {
this.name = name;
this.salary = salary;
}
changeSalary(coef) {
this.salary = Math.round(this.salary * coef);
}
}
class Manager extends Employee {
toString() {
return `Manager ${this.name} earns ${this.salary}`;
}
}
let manager = new Manager("Bob", 1000);
manager.changeSalary(1.1);
console.log(manager.toString());
Playlist и CustomPlaylist.
#Создайте класс Playlist со свойством songs (массив). Добавьте методы add и remove для добавления и удаления песен. Добавьте метод reverse(), который переворачивает массив треков. Добавьте метод length(), который возвращает количество песен. Добавьте метод isEmpty(), который проверяет, пустой плейлист или нет. Потом создайте класс-наследник CustomPlaylist, в котором метод add() будет позволять добавлять дубли песен в плейлист. В базовом Playlist дубли добавлять нельзя.
class Playlist {
// ваш код здесь
}
Решение
class Playlist {
constructor(songs) {
this.songs = songs;
}
add(song) {
if (!this.songs.includes(song)) {
this.songs.push(song);
}
}
remove(song) {
if (this.songs.includes(song)) {
this.songs.splice(this.songs.indexOf(song), 1);
}
}
reverse() {
this.songs.reverse();
}
length() {
return this.songs.length;
}
isEmpty() {
return this.songs.length === 0;
}
}
class CustomPlaylist extends Playlist {
add(song) {
this.songs.push(song);
}
}
Именованный CustomPlaylist.
#Доработайте прошлый класс CustomPlaylist, добавив ему собственный constructor. Он должен вызвать constructor родительского класса через super(songs), а затем сохранить имя плейлиста в свойство name.
class CustomPlaylist extends Playlist {
constructor(songs, name) {
super(songs);
// ваш код здесь
}
add(song) {
this.songs.push(song);
}
}
Решение
class Playlist {
constructor(songs) {
this.songs = songs;
}
add(song) {
if (!this.songs.includes(song)) {
this.songs.push(song);
}
}
}
class CustomPlaylist extends Playlist {
constructor(songs, name) {
super(songs);
this.name = name;
}
add(song) {
this.songs.push(song);
}
toString() {
return `Playlist: ${this.name}`;
}
}
MagicBox со случайным предметом.
#Давайте вернемся к классу Box (код ниже есть), Давайте от него наследуемся и сделаем класс MagicBox , единственное добавленное поведение - - это при создании объекта коробки в ней будет появляться случайный предмет из массива. Массив возможных случайных предметов определите где удобно это не важно, хоть в глобальной области. Заготовка:
class Box {
constructor() {
this.items = [];
this.itemsCount = this.items.length;
}
add(item) {
this.items.push(item);
this.itemsCount = this.items.length;
}
remove(item) {
if (this.items.includes ? this.items.includes(item) : (item in this.items)) {
this.items.splice(this.items.indexOf(item), 1);
this.itemsCount = this.items.length;
} else {
console.log("Кот из коробки говорит: Такого тут нет, до свидания!");
}
}
length() {
return this.itemsCount;
}
}
let things = ["Шапка", "Зонтик", "Кружка"];
class MagicBox extends Box {
constructor() {
// вызовите super() и добавьте случайный предмет
}
}
Решение
function choice(items) {
return items[Math.floor(Math.random() * items.length)];
}
class Box {
constructor() {
this.items = [];
this.itemsCount = this.items.length;
}
add(item) {
this.items.push(item);
this.itemsCount = this.items.length;
}
remove(item) {
if (this.items.includes(item)) {
this.items.splice(this.items.indexOf(item), 1);
this.itemsCount = this.items.length;
} else {
console.log("Кот из коробки говорит: Такого тут нет, до свидания!");
}
}
length() {
return this.itemsCount;
}
}
const things = ["Шапка", "Зонтик", "Кружка"];
class MagicBox extends Box {
constructor() {
super();
this.items.push(choice(things));
this.itemsCount = this.items.length;
}
}