Адаптивный фон, фиксированный контент
В своей книге о секретах CSS Лия Веру предложила интересную технику, которая может быть использована для секций с адаптивным фоном (фон, занимающий всю ширину окна просмотра), внутри которых есть контейнер. Давайте рассмотрим распространенный способ, позволяющий сделать это:
HTML
<section> <div class="wrapper"></div> </section>
CSS
section { background-color: #ccc; } .wrapper { max-width: 1170px; margin-left: auto; margin-right: auto; padding-left: 16px; padding-right: 16px; }
Принцип работы margin-left: auto и margin-right: auto заключается в вычислении половины ширины окна просмотра и вычитании из неё ширины контента. То же самое можно сделать, используя padding.
CSS
section { padding: 1rem calc(50% - 585px); }
Мы ещё не закончили. На мобильных устройствах контент будет соприкасаться с границами экрана. Решить это можно следующим способом:
CSS
section { padding: 1rem; } @media (min-width: 1170px) { section { padding: 1rem calc(50% - 585px); } }
В качестве альтернативного решения можно использовать новую функцию CSS max(). Мы просто устанавливаем минимальный padding размером в 1rem, а вычисление 50% — 585px будет использовано в качестве другого значения.
CSS
section { padding: 1rem max(1rem, (50% - 585px)); }
Вспоминаем основные понятия
- Есть программа. В императивном программировании программа представляет собой последовательность заданий, которые мы даём компьютеру. Делай одно, потом второе, потом третье. Есть ещё функциональное программирование, но это немного другое.
- Сами задания простые, но из простых заданий можно сделать более сложные. Если такое более сложное задание как-то назвать, можно сказать, что это функция — мини-программа внутри программы.
- В функцию можно упаковать любые последовательности действий, которые вам часто нужны в программе: например сохранить файл особым образом, вывести что-то на особый экран или отправить электронное письмо на особый адрес.
- Внутри одних функций можно вызывать другие. Например, в таск-менеджере может быть функция «Закрыть задачу», внутри которой сначала сохраняется файл, потом отправляется письмо, потом всё выводится на особый экран.
- Проблема: когда много функций вызываются друг из друга, они переплетаются и создают много зависимостей. Если изменить работу одной из функций, могут посыпаться другие.
- Решение: стандартизировать подходы к работе функций. В частности, для этого придумали объектно-ориентированное программирование.
- В объектно-ориентированном программировании главная не функция, а объект. Объект можно представить как коробку с данными и функциями.
Слишком длинная строка на больших экранах
Будет очень сложно читать текст абзаца на больших экранах, так как строка слишком длинная. Сайт «Элементы типографического стиля, используемые в сети» рекомендует, чтобы в строке было 45-75 символов. Чем дальше от этого диапазона, тем сложнее будет читать текст, представленный на веб-странице.
Для устранения подобных проблем, можно использовать контейнер, который не даст строке текста стать слишком длинной и добавит отступ на мобильных устройствах.
HTML
<section class="hero"> <div class="hero__wrapper"> <h2>How to make bread at home</h2> <p>...</p> <p><a href="/sign-up">Sign up</a></p> </div> </section>
Я использовал класс hero__wrapper, так как этот контейнер может принадлежать только первой секции (Hero Section), поэтому его ширина может быть меньше ширины других контейнеров.
CSS
.hero__wrapper { max-width: 720px; margin-left: auto; margin-right: auto; padding-left: 16px; padding-right: 16px; }
Для центрирования содержимого вы можете применить любой метод, который хотите, в зависимости от варианта использования. В этом примере будет достаточно применить text-align: center, чтобы расположить контент в центре.
Модификаторы доступа private и public
Модификаторы доступа служат для определения полномочий доступа к членам класса извне. Если перед полем или методом стоит ключевое слово private, то обращаться к данному члену можно только внутри класса. Член с модификатором public доступен за пределами класса: то есть другие классы могут напрямую получить или модифицировать значение поля (категорически не рекомендуется поле делать public, для безопасного получения и установки значения нужно использовать геттеры и сеттеры), либо вызвать публичный метод.
С помощью модификаторов доступа реализуется ключевой принцип ООП – инкапсуляция данных (их сокрытие).
Если не указывать модификатор доступа, то по умолчанию он принимается равным:
- private в C#;
- public в Java.
Не больше двух переменных экземпляра (instance variable) на класс
Один класс должен иметь дело с одним состоянием, максимум с двумя. Так что, если в классе более двух переменных экземпляра, возможно, он нарушает принцип единственной ответственности.
Примечание переводчика
Переменная экземпляра (instance variable, атрибут) — переменная, которая хранит свойство объекта — экземпляра класса. Этим она отличается от статической переменной (относится к классу, а не к его экземпляру) и от локальной переменной, которая объявляется в членах класса — например, в методах.
Кажется, это требование очень сложно выполнить. Уверен, вы видели классы с десятками параметров в конструкторе, так ведь?
Отлично! Почему бы не сгруппировать их в один объект? Или ещё раз хорошенько подумать о том, точно ли у этого класса идеальная архитектура и не делает ли он слишком много лишнего.
Какие бывают профили
Под «профилем» подразумевается более глубокое изучение определённых предметов. На них выделяют больше часов, а количество уроков по «непрофильным» предметам сокращают до минимума, необходимого для освоения программы.
В федеральном государственном образовательном стандарте 2020 года указаны 4 основных профиля:
- естественные и математические науки;
- гуманитарные науки;
- технологии;
- социально-экономические науки.
Пятый профиль – общеобразовательный – предназначен для детей, которые не выбрали ни одио из узких направлений.
ФГОС предусматривает, что в программе каждого профиля обязательно должны быть русский язык и литература, математика, иностранные языки, общественные и естественные науки, а также физкультура и ОБЖ. Но в каком объёме и какие именно предметы включить в учебный план профильного класса – решает школа. На основе перечня ФГОС школа формирует более узкие профильные классы. Самые распространённые варианты:
Профиль | Предметы |
Физико-математический | Физика, математика |
Информационно-технологический | Информатика, математика, физика |
Химико-биологический | Биология, химия |
Лингвистический | Русский язык, литература, иностранный язык |
Филологический | Русский язык, литература |
Гуманитарный | Русский язык, литература, история, обществознание |
Социально-экономический | Обществознание, география |
Бывают и другие профили: инженерные, культурологические, педагогические, юридические, художественно-эстетические и даже театральные.
В чем разница между классом оболочки и примитивным типом в Java?
Класс Wrapper предоставляет механизм для преобразования примитивного типа в объект и объекта в примитивный тип. | Примитивный тип — это предопределенный тип данных, предоставляемый Java. |
Связанный класс | |
Класс Wrapper используется для создания объекта; следовательно, он имеет соответствующий класс. | Примитивный тип не является объектом, поэтому он не принадлежит классу. |
Нулевые значения | |
Объекты класса оболочки допускают нулевые значения. | Примитивный тип данных не допускает значений NULL. |
Требуется память | |
Требуемая память больше, чем у примитивных типов. Кластерный индекс не требует дополнительного места. | Требуемая память ниже по сравнению с классами-оболочками. |
Коллекции | |
Класс Wrapper можно использовать с коллекцией, такой как ArrayList и т. Д. | Примитивный тип не используется с коллекциями. |
Центрирование контейнера
Чтобы разместить контейнер в центре, вы должны присвоить свойству margin значение auto с левой и правой стороны. Смотрите пример, приведенный ниже:
CSS
.wrapper { max-width: 1170px; margin: 0 auto; }
Согласно спецификации CSS, auto margin работает следующим образом:
Если свойствам margin-left и margin-right присвоено значение auto, то размер отступа с обеих сторон будет одинаковым. Это горизонтально центрирует объект, относительно краёв содержащего блока.
Я использовал параметр «margin: 0 auto», который сбрасывает значение margin сверху и снизу до нуля, а справа и слева устанавливает значение auto. Пользуясь этим способом, можно ожидать некоторых последствий, о которых я расскажу в этой статье чуть позже.
Пока что рекомендую установить значения margin вручную.
CSS
.wrapper { max-width: 1170px; margin-left: auto; margin-right: auto; }
Автобокс и распаковка
В предыдущем разделе мы показали, как вручную преобразовать примитивное значение в объект.
После Java 5 это преобразование может быть выполнено автоматически с помощью функций, называемых автобоксом и распаковкой.
“Бокс” относится к преобразованию примитивного значения в соответствующий объект-оболочку. Поскольку это может произойти автоматически, это называется автобоксом.
Аналогично, когда объект-оболочка разворачивается в примитивное значение, это называется распаковкой.
На практике это означает, что мы можем передать примитивное значение методу, который ожидает объект-оболочку , или назначить примитив переменной, которая ожидает объект:
List list = new ArrayList<>(); list.add(1); // autoboxing Integer val = 2; // autoboxing
В этом примере Java автоматически преобразует значение примитива int в оболочку.
Внутренне он использует метод valueOf() для облегчения преобразования. Например, следующие строки эквивалентны:
Integer value = 3; Integer value = Integer.valueOf(3);
Хотя это упрощает преобразование и делает коды более читаемыми, есть некоторые случаи, когда мы не должны использовать автобокс, например, внутри цикла .
Подобно автобоксу, распаковка выполняется автоматически при передаче объекта методу, ожидающему примитив, или при назначении его переменной примитива:
Integer object = new Integer(1); int val1 = getSquareValue(object); //unboxing int val2 = object; //unboxing public static int getSquareValue(int i) { return i*i; }
В принципе, если мы напишем метод, который принимает примитивное значение или объект-оболочку, мы все равно сможем передать им оба значения. Java позаботится о передаче правильного типа, например, примитива или оболочки, в зависимости от контекста.
Постановка задачи
Написать программу, которая умеет сравнивать двух супергероев и определять, у кого из них больше шансов выжить в битве.
В нашем маленьком мирке будут два типа героев: зелёные и красные. Каждый из них может обладать одной или несколькими сверхспособностями: суперсила, суперловкость и суперинтеллект.
Судьба героя зависит от его шанса на выживание. Он изначально чуть выше у красных героев, но каждая суперспособность увеличивает шанс:
- суперсила — на 4;
- суперловкость — на 3;
- суперинтеллект — на 7.
В битве двух супергероев выживает тот, у кого итоговое значение шанса больше.
В рамках задачи нас не интересует ничего, кроме описания героя и его способности выжить. Поэтому базовый интерфейс супергероя будет выглядеть так:
Класс для зелёного супергероя:
И для красного, более живучего:
Используем переменные CSS для вариаций контейнеров
Редко случается так, что вам нужен контейнер только одного размера. Ширина контейнера может быть большой или маленькой, в зависимости от содержимого и варианта использования. Применяя переменные CSS, мы можем по-новому взглянуть на wrapper и сделать его максимально пластичным
Обратите внимание на следующее:
HTML
<div class="wrapper"></div>
CSS
.wrapper { max-width: var(--wrapper-width, 1170px); margin-left: auto; margin-right: auto; padding-left: 16px; padding-right: 16px; }
Возможно, вы заметили, что у функции var есть два значения: первое – —wrapper-width, и второе – 1170px. Вторая переменная является резервной, то есть используется, если значение переменной —wrapper-width не установлено.
Что это значит? Это значит, что вы можете создать вариацию контейнера, установив свойство —wrapper-width, как показано ниже.
HTML
<div class="wrapper" style="--wrapper-width: 720px"></div>
Таким образом, я создал вариацию контейнера:
- Без добавления новых классов;
- Не копируя и не вставляя стили;
- Более надежную и легко редактируемую с помощью DevTools.
Если вам не нравится использовать встроенные стили для изменения переменной CSS, вы можете вместо этого добавить новый класс. Смотрите пример, приведенный ниже:
HTML
<div class="wrapper wrapper--small"></div>
CSS
.wrapper--small { --wrapper-width: 720px; /* это изменит ширину контейнера, установленную по умолчанию */ }
Логический и символьный типы данных
Чтобы работать с логическими значениями, используют тип данных boolean — это его единственное применение. У такой переменной может быть только два значения: false (ложь) и true (истина).
В Java boolean — отдельная переменная. Это не аналог 1 или , как, например, в JavaScript и PHP.
Тип данных char используют, чтобы хранить в переменных любые 16-разрядные символы Unicode. Но их нужно записывать строго в одинарные кавычки ‘ ‘, и только по одному.
Не стоит путать символьные и строковые переменные — ‘ж’ не равно «ж», потому что в двойных кавычках хранится тип данных String. А это уже не примитив.
Оборачивайте примитивные типы
Оборачивая примитивные типы в классы, мы инкапсулируем (скрываем) тип. Если позже в ходе рефакторинга мы захотим изменить примитивные типы, это можно будет сделать в одном месте.
А ещё такой код легче воспринимать, ведь по сигнатуре объекта-обёртки сразу ясно, что передавать методу в качестве параметров.
Примечание переводчика
В оригинальной книге правило звучит так: «оборачивайте примитивы и строки».
Например, если метод принимает параметр типа int, это мало о чём говорит. Другое дело, если тип параметра будет, скажем, Hour. Мы оборачиваем целое число (часов) в класс. В тот же класс можно добавить проверку допустимых значений, и тогда никто не сможет передать в метод 36 или другое неподходящее число.
Как используют целочисленные переменные
Целочисленные типы данных различаются только диапазонами значений. Их основная задача — хранить информацию для вычислений.
Тип byte. Эти переменные используют, чтобы работать с потоком данных, который получили из файла или по сети.
Тип short. По сравнению с byte у него увеличенный, но всё же ограниченный диапазон значений. Применяют short редко — например, когда нужно экономить память.
Тип int. В языке Java int — самый популярный тип целочисленных данных. При вычислениях в виртуальной машине остальные целочисленные типы (byte, short) занимают столько же памяти, сколько int.
Множество классов в Java обладают значениями типа int — например, длина массива внутри класса String выражается целочисленным значением int:
Если переменная хранит количество элементов в коллекциях List, Set и Map, она тоже относится к типу int:
Тип возвращаемого значения подсказывает, сколько элементов можно хранить в списке или множестве. Максимум для int — 2 147 483 647.
Тип long применяют, когда нужно работать с большими целочисленными значениями.
Создадим много классов-индивидуальностей
Можем поступить как в Marvel и каждому возможному варианту героя дать своё имя — создать отдельный класс. Например, зелёный супергерой с суперсилой и суперинтеллектом будет Халком, а красного — с суперинтеллектом и суперловкостью — назовём Человеком-пауком.
Всего получится 16 классов: восемь комбинаций из трёх суперспособностей для красных и восемь — для зелёных:
Суперсила | Суперловкость | Суперинтеллект | |
---|---|---|---|
1 | — | — | — |
2 | + | — | — |
3 | — | + | — |
4 | — | — | + |
5 | + | + | — |
6 | — | + | + |
7 | + | — | + |
8 | + | + | + |
Например, так будет выглядеть класс Халка:
Что здесь плохо
Классов и так слишком много, а при добавлении каждой новой суперспособности их число будет увеличиваться вдвое для каждого типа супергероя.
Если же мы захотим добавить не суперспособность, а тип — например, жёлтых супергероев, — то классов станет больше на 2n, где n — варианты суперспособностей.
Как это посчитать
Для каждого типа героя (красного или зелёного) суперсила либо есть, либо нет — ровно два варианта.
Независимо от этого, у каждого такого варианта суперловкость либо есть, либо нет. Итого: для каждого из 2 вариантов ещё по 2 варианта = 4 варианта.
У каждого из этих 4 вариантов суперинтеллект либо есть, либо нет:
4 ∗ 2 = 8 вариантов.
Таким образом, каждая суперспособность увеличивает число вариантов супергероев каждого цвета вдвое, то есть при n суперспособностей их число равно 2n.
Классы обертки
“Какова цель класса обертки?”. Это один из самых распространенных вопросов для интервью на Java .
В принципе, универсальные классы работают только с объектами и не поддерживают примитивы . В результате, если мы хотим работать с ними, мы должны преобразовать примитивные значения в объекты-оболочки.
Например, фреймворк коллекции Java работает исключительно с объектами. Давным-давно (до Java 5, почти 15 лет назад) не было автобоксов, и мы, например, не могли просто вызвать add(5) для набора целых чисел.
В то время эти примитивные значения должны были быть вручную преобразованы в соответствующие классы-оболочки и сохранены в коллекциях.
Сегодня, с помощью autoboxing, мы можем легко сделать ArrayList.add(101) но внутренне Java преобразует примитивное значение в Целое число перед сохранением его в ArrayList с помощью метода valueOf () .
Преобразование примитива в класс-оболочку
Теперь большой вопрос: как мы преобразуем примитивное значение в соответствующий класс-оболочку, например, int в Целое число или char в Символ?
Ну, мы можем использовать либо конструкторские, либо статические фабричные методы для преобразования примитивного значения в объект класса-оболочки.
Однако начиная с Java 9 конструкторы для многих коробочных примитивов, таких как | или Long
Поэтому настоятельно рекомендуется использовать только заводские методы в новом коде .
Давайте рассмотрим пример преобразования значения int в объект Integer в Java:
Integer object = new Integer(1); Integer anotherObject = Integer.valueOf(1);
Метод valueOf() возвращает экземпляр, представляющий указанное значение int .
Он возвращает кэшированные значения, что делает его эффективным. Он всегда кэширует значения от -128 до 127, но также может кэшировать другие значения за пределами этого диапазона.
Аналогично, мы также можем преобразовать boolean в Boolean, byte в Byte, char в Символ, long в Long, float в Float, и double to Double. Хотя, если нам нужно преобразовать строку в целое число , нам нужно использовать метод parseInt () , потому что String не является классом-оболочкой.
С другой стороны, для преобразования объекта-оболочки в примитивное значение мы можем использовать соответствующий метод, такой как intValue(), doubleValue () |/и т. Д:
int val = object.intValue();
Исчерпывающую справку можно найти здесь .
Где применять классы и ООП, а где — функции
Если вы делаете простую программу, которую можно сделать тремя функциями — делайте. Или даже если программа станет сложнее, в ней будет много функций, но все они логично связаны и понятно, почему сделано именно так, — тоже хорошо. Нет ничего плохого в том, что вы не используете объектно-ориентированное программирование там, где можно обойтись без него.
А вот если у вас проект со множеством абстракций, взаимосвязей внутри и вы заранее не можете предсказать, когда что с чем будет взаимодействовать, то лучше использовать классы и все преимущества ООП. Возможно, код станет сложнее, но это не всегда так. С другой стороны, вы сможете реализовать такую логику, которую на функциях было бы сделать непросто.
Текст
Миша Полянин
Редактировал и рисовал
Максим Ильяхов
Корректор
Ира Михеева
Иллюстратор
Даня Берковский
Вёрстка
Маша Дронова
Доставка
Олег Вешкурцев
Boxing и unboxing — как превратить примитив в объект
Иногда с примитивами приходится работать как с объектами — например, передавать им значение по ссылке или создавать список из чисел (а списки работают только с объектами).
Поэтому у каждого примитива есть соответствующий ему ссылочный тип — его называют классом-обёрткой. В таких классах хранятся методы для преобразования типов данных, а также другие константы и методы, которые применяются при работе с примитивами.
Тип данных | Класс-обёртка |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
Ссылочные типы данных (обёртки) пишут с прописной буквы, потому что это полноценные классы. А в Java названия всех классов должны начинаться с большой буквы — язык чувствителен к регистру.
Чтобы создать ссылку на примитивный тип данных, нужно использовать соответствующую обёртку:
Если использовать valueOf, процесс упаковывания становится проще и быстрее, потому что он проводит кэширование и потребляет меньше памяти, а конструктор всегда создаёт новый объект.
Классы-обёртки полезны, когда нужно одновременно работать и с числами, и с объектами — например, в коллекциях.
В этой статье мы рассмотрели примитивные типы данных (byte, short, int, long, float, double, char и boolean), ссылочные типы данных (String и остальные). Вы узнали, чем они отличаются друг от друга и какие значения принимают по умолчанию.
В следующей статье мы расскажем, что можно делать с этими переменными с помощью арифметических и логических операторов языка Java.
Ключевое отличие — оболочка Класс против примитивного типа в Java
Java — популярный язык программирования, который используется для разработки различных приложений. Одним из преимуществ Java является то, что она поддерживает объектно-ориентированное программирование (ООП). Используя ООП, программу или программное обеспечение можно моделировать с помощью объектов. Класс используется как образец для создания объекта. В программировании необходимо хранить данные. Зарезервированные области памяти для хранения данных известны как переменные. Каждая переменная имеет определенный тип данных. В языке Java предусмотрено восемь примитивных типов. Они короткие, байтовые, int, float, double, char, логическое значение. Иногда требуется преобразовать примитивный тип в объект, а объект — обратно в примитивный тип. Для этого преобразования используются классы-оболочки. В этой статье обсуждается разница между классом-оболочкой и примитивным типом в Java. В ключевое отличие между классом-оболочкой и примитивным типом в Java заключается в том, что Класс-оболочка используется для преобразования примитивного типа в объект и объекта обратно в примитивный тип, в то время как примитивный тип — это предопределенный тип данных, предоставляемый языком программирования Java.
1. Обзор и основные отличия 2. Что такое класс-оболочка в Java 3. Что такое примитивный тип в Java 4. Сходства между классом-оболочкой и примитивным типом в Java 5. Параллельное сравнение — класс оболочки и примитивный тип в Java в табличной форме 6. Резюме
Что такое класс Wrapper в Java?
Класс Wrapper в Java используется для преобразования примитивного типа данных в объект и объекта в примитивный тип. Даже примитивные типы данных используются для хранения первичных типов данных, структур данных, таких как списки массивов и объекты хранилища векторов. Следовательно, для преобразования необходимо использовать классы-оболочки. Соответствующие классы-оболочки для примитивных типов char, byte, short и int — это Character, Byte, Short и Integer. Соответствующие классы-оболочки для long, float, double и boolean — Long, Float, Double и Boolean.
Согласно приведенной выше программе intobj является объектом класса-оболочки Integer. Floatobj — это объект класса-оболочки Float. Doubleobj — это объект класса двойной оболочки. Объект Integer преобразуется в примитивный тип int с помощью intValue (). Точно так же объект Float преобразуется в примитивный float с помощью floatValue (). Объект Double преобразуется в примитивный тип double с помощью doubleValue (). Если программист записывает оператор как int i = intobj; компилятор внутренне записывает в bj.Value (). Процесс автоматического преобразования объекта класса-оболочки в соответствующий ему примитивный тип известен как распаковка. Коллекции, такие как ArrayLists, используют класс Wrapper, потому что они хранят объекты.
Что такое класс?
В объектно-ориентированном программировании (ООП) – класс это основной элемент, в рамках которого осуществляется конструирование программ. Класс содержит в себе данные и код, который управляет этими данными.
Класс зачастую описывает объект реального мира. Как и реальный объект, класс содержит свой набор параметров и характеристик. Каждый такой параметр называется поле класса (очень похоже на обычные переменные). Также класс способен манипулировать своими характеристиками (полями) с помощью методов класса (похожи на функции в процедурных языках). Рассмотрим такой объект, как автомобиль.
Оговоримся, что данная статья исключительно для начинающих. В ней не рассматривается наследование, абстрактные классы и т.д.