Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Три кита ООП: Инкапсуляция, Наследование, Полиморфизм
Этот вопрос проверяет не просто знание теории, но и понимание того, как она применяется в реальной разработке. После 10+ лет в индустрии скажу: три кита ООП работают везде, включая JavaScript и React.
1. Инкапсуляция (Encapsulation)
Это сокрытие деталей реализации и предоставление только необходимого интерфейса. В JavaScript это реализуется через замыкания, приватные поля и классы.
class UserService {
#apiKey; // приватное поле
#baseUrl = "https://api.example.com";
constructor(apiKey) {
this.#apiKey = apiKey;
}
// публичный метод
async getUser(id) {
return this.#makeRequest(`/users/${id}`);
}
// приватный метод
#makeRequest(endpoint) {
return fetch(`${this.#baseUrl}${endpoint}`, {
headers: { Authorization: `Bearer ${this.#apiKey}` }
});
}
}
const service = new UserService("secret-key");
await service.getUser(123); // работает
// service.#apiKey // ошибка — приватное
В контексте React:
interface UserContextType {
user: User | null;
logout: () => void; // публичный интерфейс
}
export const UserContext = createContext<UserContextType | undefined>(undefined);
export function UserProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [token, setToken] = useState<string | null>(null); // деталь реализации
const logout = useCallback(() => {
setUser(null);
setToken(null);
}, []);
return (
<UserContext.Provider value={{ user, logout }}>
{children}
</UserContext.Provider>
);
}
2. Наследование (Inheritance)
Передача свойств и методов от родительского класса к дочерним. В JavaScript используется через прототипы и классы.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} издаёт звук`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} лает`);
}
}
const dog = new Dog("Шарик");
dog.speak(); // Шарик лает
Важный момент для React: В React наследование не приветствуется. Вместо этого используют композицию (composition over inheritance):
// ❌ Плохо — наследование
class ButtonBase {
render() { return <button>Base</button>; }
}
class PrimaryButton extends ButtonBase {}
// ✅ Хорошо — композиция
interface ButtonProps {
variant: "primary" | "secondary";
children: React.ReactNode;
}
function Button({ variant, children }: ButtonProps) {
return <button className={`btn-${variant}`}>{children}</button>;
}
3. Полиморфизм (Polymorphism)
Возможность объектов принимать несколько форм. В JavaScript это достигается через переопределение методов и утиные типы (duck typing).
class Dog {
move() { console.log("Собака бежит"); }
}
class Bird {
move() { console.log("Птица летит"); }
}
class Fish {
move() { console.log("Рыба плывёт"); }
}
function animalMove(animal) {
animal.move(); // работает с любым животным
}
animalMove(new Dog()); // Собака бежит
animalMove(new Bird()); // Птица летит
animalMove(new Fish()); // Рыба плывёт
В TypeScript это интерфейсы:
interface Drawable {
draw(): void;
}
class Circle implements Drawable {
draw() { console.log("Рисую круг"); }
}
class Square implements Drawable {
draw() { console.log("Рисую квадрат"); }
}
function renderShape(shape: Drawable) {
shape.draw();
}
Практическое применение в React
На примере компонентов формы:
// Интерфейс (полиморфизм)
interface FormFieldProps {
name: string;
value: string;
onChange: (value: string) => void;
}
// Инкапсуляция — компонент знает только о своём состоянии
function TextInput({ name, value, onChange }: FormFieldProps) {
return <input value={value} onChange={e => onChange(e.target.value)} />;
}
// Композиция вместо наследования
function Form() {
const [formData, setFormData] = useState({ name: "", email: "" });
return (
<form>
<TextInput
name="name"
value={formData.name}
onChange={(value) => setFormData(prev => ({ ...prev, name: value }))}
/>
</form>
);
}
Заключение
Три кита ООП — это фундамент структурированного кода. В современном JavaScript и React их применение отличается от классического ООП, но суть остаётся: инкапсулируй детали, переиспользуй логику через композицию и проектируй гибкие интерфейсы. Это делает код читаемым, тестируемым и легко расширяемым.