The term "Interface" is widely used in tech and computer science, and its meaning is similar to when we use it in everyday life. For example, a user interface is a set of controls for a website, ATM, or phone, among other things. The interface on a TV remote control is the buttons. A car's interface is its gear stick, steering wheel, and buttons. Essentially, we can say that an interface defines the way you interact with a system.
Creating interfaces is not as easy as it may seem at first sight. I'd even say that it's rather challenging. Every day we encounter annoying interfaces, from the way doors open to how elevators work. The more complex the system (that is, the more states it can have), the harder it is to make an interface. Even if we use a simple example like a TV's power button (two states – on/off), you can implement either two buttons or one button that behaves differently depending on the current state.
Everything in programming works similarly. An interface is a set of functions (their names and signatures, i.e., the number and types of incoming parameters and the return value) that don't depend on a particular implementation. This definition is identical to the concept of an abstract data type. For example, for points, all functions that we have implemented in exercises and described in lessons, are interface functions.
How do the concepts of abstraction and interface relate to each other? Abstraction is a word that primarily describes the data we are working with. For example, almost every web application includes a “user” abstraction. On Hexlet, we have the “course,” “project,” and other abstractions. And an interface is a set of functions to interact with data.
But there are not only interface functions, but also helper functions that are not used by calling code and work exclusively within the abstraction:
// The makeUser, getAge, and isAdult functions are part of the User abstraction interface
// They are used by external (client, calling) code
const makeUser = (name, birthday) => ({ name, birthday });
const getAge = user => calculateAge(user.birthday);
const isAdult = user => getAge(user) >= 18;
// This function is not part of the User abstraction interface
// It's internal
const calculateAge = (birthday) => {
const milliSecondsInYear = 31556926 * 1000;
// Date.now() - returns the number of milliseconds,
// elapsed since January 1, 1970 00:00:00 UTC
// Date.parse(str) - parses the string representation of the date
// and also returns the number of milliseconds
return Math.trunc((Date.now() - Date.parse(birthday)) / milliSecondsInYear);
};
In complex abstractions (which can be presented by external libraries), the number of non-interface functions is much larger than that of interface functions. So much so that the library interface may have one or two functions while the library itself has hundreds of them. How good your abstraction is can be determined, among other things, by how user-friendly its interface is.
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.