Ревью 2. Ревью 2 Вопросы
Скачать 27.81 Kb.
|
Ревью 2 Вопросы : Перед ревью, проверьте себя по контрольным вопросам: 1) что такое ООП. 2) принципы ООП 3) Модификаторы доступа 4) Указатели this и super. 5) Модификатор static 6) Наследование и реализация. 7) Интерфейсы. 8) Анонимные классы. 9) Класс Object и класс Class. 10) Контракт между equals() и hashCode(). что такое ООП. принципы ООП ООП это способ(метод) программирования, основанный на представлении программы в виде совокупности объектов, каждый из которых является экземпляром отдельного класса, а классы образуют иерархию наследования Принципы ООП абстракция, инкапсуляция, наследование, полиморфизм Абстракция выделение набора значимых характеристик объекта исключая не значимые абстрактные классы и интерфейсы Инкапсуляция это механизм обертывания данных (поля) и методов в одно целое, в класс в инкапсуляции переменные класса будут сокрыты от других классов. доступ же к ним будет через методы этого класса (гетеры и сеттеры) Наследование это свойство системы позволяющее описать новый класс на основе уже существующего с частично или полностью взаимствующейся функциональностью (extends, полиморфизм) Полиморфизм 1. это возможность применения одноименных методов с одинаковыми или различными наборами параметров в одном классе или в группе классов, связанных наследованием 2. это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта 3) Модификаторы доступа Модификаторы доступа private, default, protected, public private (закрытый) доступ к компоненту предоставляется только методам этого класса default доступ к компоненту из любых классов из этого же пакета protected доступ к компоненту из любых классов этого же пакета и классов наследников 4) Указатели this и super. переменная this ссылается на текущий экземпляр класса, в котором она используется, тогда как super — на текущий экземпляр родительского класса. Каждый конструктор при отсутствии явных вызовов других конструкторов неявно вызывает с помощью super() конструктор без аргументов родительского класса, при этом у вас всегда остается возможность явно вызвать любой другой конструктор с помощью либо this(), либо super(). 5) Модификатор static Static — модификатор, применяемый к полю, блоку, методу или внутреннему классу. Данный модификатор указывает на привязку субъекта к текущему классу. Статические поля При обозначении переменной уровня класса мы указываем на то, что это значение относится к классу. Если этого не делать, то значение переменной будет привязываться к объекту, созданному по этому классу. Если переменная не статическая, то у каждого нового объекта данного класса будет своё значение этой переменной, меняя которое мы меняем его исключительно в одном объекте Статический блок Есть два блока инициализации — обычный и статический. Блок предназначен для инициализации внутренних переменных. Если блок обычный, то им инициализируют внутренние переменные объекта, если же статический, соответственно, им задают статические переменные (то есть переменные класса). Статический метод Статические методы отличаются от обычных тем, что они также привязаны к классу, а не к объекту. Важным свойством статического метода является то, что он может обратиться только к статическим переменным/методам Статический класс в Java Статическим классом может быть только внутренний класс. Опять же, этот класс привязан к внешнему классу, и если внешний наследуется другим классом, то этот не будет наследован. При этом данный класс можно наследовать, как и он может наследоваться от любого другого класса и имплементировать интерфейс. По сути статический вложенный класс ничем не отличается от любого другого внутреннего класса за исключением того, что его объект не содержит ссылку на создавший его объект внешнего класса. Тем не менее, благодаря этому статический класс наиболее похож на обычный не вложенный, ведь единственное различие состоит в том, что он упакован в другой класс. В некоторых случаях для нас это преимущество, так как с него у нас есть доступ к приватным статическим переменным внешнего класса. Предположим, существует статический метод increment() в классе Counter, задачей которого является инкрементирование счётчика count. Для вызова данного метода можно использовать обращение вида Counter.increment(). Нет необходимости создавать экземпляр класса Counter для доступа к статическому полю или методу. Это фундаментальное отличие между статическими и НЕ статическими объектами (членами класса). Что должен знать каждый программист о модификаторе Static в Java В этом разделе мы рассмотрим основные моменты использования статических методов, полей и классов. Начнём с переменных. Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких как «состояние гонки» (race condition). Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утилит (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы (final). Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) вместо переопределения. Это явление известно как сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких как «состояние гонки» (race condition). Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утилит (utility). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы (final). Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) вместо переопределения. Это явление известно как сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. 6) Наследование и реализация. Наследование (inheritance) — механизм, который позволяет описать новый класс на основе существующего (родительского). При этом свойства и функциональность родительского класса заимствуются новым классом. Extends. Чтобы объявить один класс наследником от другого, надо использовать после имени класса-наследника ключевое слово extends, после которого идет имя базового класса. Если в базовом классе определены конструкторы, то в конструкторе производного классы необходимо вызвать один из конструкторов базового класса с помощью ключевого слова super. Производный класс имеет доступ ко всем методам и полям базового класса (даже если базовый класс находится в другом пакете) кроме тех, которые определены с модификатором private. Производный класс может определять свои методы, а может переопределять методы, которые унаследованы от базового класса. При переопределении метода он должен иметь уровень доступа не меньше, чем уровень доступа в базовом класса. Например, если в базовом классе метод имеет модификатор public, то и в производном классе метод должен иметь модификатор public Хотя наследование очень интересный и эффективный механизм, но в некоторых ситуациях его применение может быть нежелательным. И в этом случае можно запретить наследование с помощью ключевого слова final. Аналогично с методами. 7) Интерфейсы. Интерфейсы определяют некоторый функционал, не имеющий конкретной реализации, который затем реализуют классы, применяющие эти интерфейсы. И один класс может применить множество интерфейсов. Все методы интерфейса не имеют модификаторов доступа, но фактически по умолчанию доступ public, так как цель интерфейса - определение функционала для реализации его классом. Поэтому весь функционал должен быть открыт для реализации. 8) Анонимные классы. Анонимный класс– это локальный класс без имени. Можно объявить анонимный (безымянный) класс, который может расширить (extends) другой класс или реализовать (implements) интерфейс. Объявление такого класса выполняется одновременно с созданием его объекта посредством оператора new. Анонимные классы эффективно используются, как правило, для реализации (переопределения) нескольких методов и создания собственных методов объекта. Внутри джава машины: Создается безымянный Java-класс, реализующий интерфейс . Компилятор, увидев такой класс, требует от тебя реализовать все методы интерфейса . Создается один объект этого класса. 9) Класс Object и класс Class. Хотя мы можем создать обычный класс, который не является наследником, но фактически все классы наследуются от класса Object. Все остальные классы, даже те, которые мы добавляем в свой проект, являются неявно производными от класса Object. Поэтому все типы и классы могут реализовать те методы, которые определены в классе Object. oStringМетод toString служит для получения представления данного объекта в виде строки. Метод hashCodeМетод hashCode позволяет задать некоторое числовое значение, которое будет соответствовать данному объекту или его хэш-код. Получение типа объекта и метод getClassМетод getClass позволяет получить тип данного объекта: Метод equalsМетод equals сравнивает два объекта на равенство Class - это класс входящий в пакет java.lang. Его едят только в случае, когда необходимо использовать рефлексию. В Java почти все сущности являются объектами, за исключением примитивных типов. У каждого объекта есть класс. Сами классы тоже является объектами, и они принадлежат классу Class. У класса Class нет публичных конструкторов. Class - это generic тип. Методы Class предназначены для получения информации о классе (объекте типа Class). Например, можно узнать полное имя класса, какие у него аннотации, какие конструкторы и т.п. Эти методы нужны для reflection. С помощью reflection вы можете создавать объекты, которые принадлежат этому классу, и при этом заранее класс объекта вы можете не знать. 10 Контракт междуequals() и hashCode(). контракт между equals hashcode Если объекты равны по equals() то их хеш-коды тоже равны Если хеш-коды разные, то по equals() будет точно - falseЕсли объекты не равны по equals(), их хеш-коды могут быть равны А если хеш-коды равны. Объекты могут быть равны, а могут и не равняться Какой тип данных у hashcode? Может ли быть hashcode отрицательным? int Метод hashCode() должен возвращать целочисленное значение, которое может быть отрицательным Из-за чего происходят коллизии? Почему нельзя написать hashcode гарантировано без коллизий? Как известно, ситуация, когда у разных объектов одинаковые хеш-коды называется — коллизией. Вероятность возникновения коллизии зависит от используемого алгоритма генерации хеш-кода. Хеш код в java создается методом public int hashCode() У integer диапазон от -2147483648 до 2147483647, т.е. округлив получаем 4 миллиарда разных целых чисел. А теперь представим ситуацию, у вас 8-10 миллиардов объектов. Вопрос: как каждому из них дать уникальный хеш код используя диапазон в 4 миллиарда? |