Программа курса← Объектно ориентированное программирование
1История ООП
2Объект и Класс
3Базовые концепции ООП
4Принцип проектирования GRASP
5Принцип проектирования SOLID
6Паттерны GOF

Класс как описание типа

Сверху – чертёж машины с размерами, снизу – три одинаковые по форме машины разного цвета, собранные по этому чертежу

Объектно-ориентированное программирование (ООП) – это популярный стиль написания кода, который позволяет структурировать программу как набор взаимодействующих объектов. Два ключевых понятия в ООП – это класс и объект. Часто их путают, но между ними есть фундаментальная разница.

Что такое класс?

Представьте себе чертеж машины. На этом чертеже указано:

  • Какой у машины кузов и сколько в нём дверей
  • Какой двигатель под капотом
  • Из каких деталей её собирают на заводе

Класс – это и есть такой “чертеж” или “шаблон” для создания объектов. Он описывает:

  • Атрибуты (данные, поля): Это характеристики, которые будут у будущего объекта (например, для класса Car атрибутами могут быть color, model, max_speed).
  • Методы (функции): Это действия, которые объект сможет выполнять (например, для класса Car методами могут быть start_engine(), drive(), brake()).

Сам по себе класс не занимает места в памяти компьютера. Это просто описание.

По сути описание типа в памяти всё же лежит – но одно на всю программу, сколько бы объектов ни создали. Как лист чертежа рядом с автомобилем.

Пример класса

namespace Lecture1;

public class Car
{
    // Конструктор – специальный метод для инициализации нового объекта
    public Car(string color, string model)
    {
        Color = color;
        Model = model;
        IsEngineOn = false;
    }

    public string Color { get; set; }
    public string Model { get; set; }
    public bool IsEngineOn { get; set; }

    // Определяем методы (поведение класса)
    public void StartEngine()
    {
        IsEngineOn = true;
        Console.WriteLine("Двигатель запущен!");
    }

    public void Drive()
    {
        if (IsEngineOn)
        {
            Console.WriteLine($"{Model} поехал!");
        }
        else
        {
            Console.WriteLine("Сначала заведи двигатель!");
        }
    }
}
#include <iostream>
#include <string>

class Car {
public:
    // Конструктор – специальный метод для инициализации нового объекта
    Car(std::string color, std::string model)
        : color_(std::move(color)), model_(std::move(model)) {}

    // Определяем методы (поведение класса)
    void StartEngine() {
        is_engine_on_ = true;
        std::cout << "Двигатель запущен!" << std::endl;
    }

    void Drive() const {
        if (is_engine_on_) {
            std::cout << model_ << " поехал!" << std::endl;
        } else {
            std::cout << "Сначала заведи двигатель!" << std::endl;
        }
    }

    const std::string& color() const { return color_; }
    const std::string& model() const { return model_; }

private:
    // Поля класса: по умолчанию в class всё закрыто
    std::string color_;
    std::string model_;
    bool is_engine_on_ = false;
};
// В Go нет классов: описание типа – это структура и методы на ней.
type Car struct {
	Color      string
	Model      string
	IsEngineOn bool
}

// Конструктора как отдельной конструкции тоже нет.
// По соглашению пишут функцию New… – она и играет его роль.
func NewCar(color, model string) *Car {
	return &Car{Color: color, Model: model}
}

func (c *Car) StartEngine() {
	c.IsEngineOn = true
	fmt.Println("Двигатель запущен!")
}

func (c *Car) Drive() {
	if c.IsEngineOn {
		fmt.Printf("%s поехал!\n", c.Model)
	} else {
		fmt.Println("Сначала заведи двигатель!")
	}
}
class Car:
    # Конструктор – специальный метод для инициализации нового объекта
    def __init__(self, color, model):
        # Определяем атрибуты (данные класса)
        self.color = color
        self.model = model
        self.is_engine_on = False

    # Определяем методы (поведение класса)
    def start_engine(self):
        self.is_engine_on = True
        print("Двигатель запущен!")

    def drive(self):
        if self.is_engine_on:
            print(f"{self.model} поехал!")
        else:
            print("Сначала заведи двигатель!")
class Car {
    isEngineOn = false;

    // Параметры со словом public сразу становятся полями объекта
    constructor(
        public color: string,
        public model: string,
    ) {}

    startEngine(): void {
        this.isEngineOn = true;
        console.log("Двигатель запущен!");
    }

    drive(): void {
        if (this.isEngineOn) {
            console.log(`${this.model} поехал!`);
        } else {
            console.log("Сначала заведи двигатель!");
        }
    }
}
public class Car {
    private final String color;
    private final String model;
    private boolean isEngineOn;

    // Конструктор – специальный метод для инициализации нового объекта
    public Car(String color, String model) {
        this.color = color;
        this.model = model;
        this.isEngineOn = false;
    }

    public String getColor() {
        return color;
    }

    public String getModel() {
        return model;
    }

    public void startEngine() {
        isEngineOn = true;
        System.out.println("Двигатель запущен!");
    }

    public void drive() {
        if (isEngineOn) {
            System.out.println(model + " поехал!");
        } else {
            System.out.println("Сначала заведи двигатель!");
        }
    }
}
// Свойства объявляются прямо в заголовке класса – это и есть конструктор.
class Car(val color: String, val model: String) {
    var isEngineOn = false
        private set

    fun startEngine() {
        isEngineOn = true
        println("Двигатель запущен!")
    }

    fun drive() {
        if (isEngineOn) {
            println("$model поехал!")
        } else {
            println("Сначала заведи двигатель!")
        }
    }
}