1-freelance.ru

Журнал "Фрилансер"
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Переопределение метода; private; в java

Переопределение метода "private" в java

В этой идее есть что-то двусмысленное, и мне нужны некоторые разъяснения.

Моя проблема заключается в использовании этого кода:

Выход- hoho private .

Это потому, что основная функция находится в том же классе , что и метод don , или из-за переопределения?

Я прочитал эту идею в книге, и когда я помещаю функцию main в другой класс, я получаю ошибку компилятора.

5 ответов

  • переопределение метода в Java

Как реализовано переопределение метода в Java? В C++ у нас есть понятие vtable.. как это реализовано внутренне в Java?

Как можно переопределить метод из суперкласса в классе, который расширяет суперкласс, в Groovy? Способ Java не работает, так как выполняются оба метода (один в суперклассе и один в подклассе). Например: class SuperClass < SuperClass()< println(This is the superclass) >def awaitServer()<.

Вы не можете переопределить метод private . Он не будет виден, если вы приведете A к B . Вы можете переопределить метод protected , но это не то, что вы делаете здесь (и да, здесь, если вы переместите свой main в A , вы получите другой метод. Я бы рекомендовал аннотацию @Override , когда вы собираетесь переопределить,

В этом случае почему компилятор не выдал ошибку при использовании t.don() , которая равна private ?

Хотя при переопределении метода не требуется использовать эту аннотацию, она помогает предотвратить ошибки. Если метод, отмеченный знаком @Override , не может правильно переопределить метод в одном из своих суперклассов, компилятор генерирует ошибку.

это потому, что основная функция находится в том же классе, что и метод «don»

Нет, это потому, что A ‘s don() не имеет отношения к B ‘s don() методу, несмотря на то, что у него одно и то же имя и список аргументов. private методы скрыты внутри своего класса. Они не могут быть вызваны непосредственно внешними вызывающими устройствами, такими как метод main в вашем случае, поскольку они инкапсулированы внутри класса. Они не участвуют в переопределении методов.

Нет, частный метод не может быть переопределен, так как он не виден ни из какого другого класса. Вы объявили новый метод для своего подкласса, который не имеет никакого отношения к методу суперкласса. Один из способов взглянуть на это-спросить себя, было бы законно писать super.func() в производном классе.

Вы не можете переопределить частный метод, но вы можете без проблем ввести его в производный класс. Производный класс не может получить доступ к закрытому методу на предке.

Поскольку t является объектом типа B , вызов метода don() вызовет метод, определенный в B. Он даже не знает, что в классе А есть метод с именем don()

частные члены не видны никаким другим классам, даже детям

Вы не можете переопределить частный метод, но, с другой стороны, вы также не можете его вызвать. Однако вы можете создать идентичный метод с тем же именем в дочернем элементе.

Если вы вызовете A.visibleMethod(), он выведет 1.

Если вы вызовете B.visibleMethod(), он напечатает 2.

Если вы не реализуете метод private calculate() в B, он не будет компилироваться, потому что открытый метод, который его вызывает, не может видеть частный метод в A.

  • Как переопределение ковариантного метода реализуется с помощью метода мостов в java
Читайте так же:
Мой киевстар моя страница вход

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

Я узнал о полиморфизме в java и когда метод в (дочернем) расширяющемся классе переопределит метод в родительском классе, а также когда метод перегрузит другой метод. этот сайт очень помог мне разобраться в этих вопросах. Но я не нашел ничего, что объясняло бы, что и как приведение объекта и/или.

Похожие вопросы:

У меня есть Java interface Writer , определенный следующим образом: public interface Writer<K, V> < Iterator<Product2<K, V>> iterator (); >И я пытаюсь реализовать этот интерфейс в.

Java платформа SE 5 API спецификация для метода Instrumentation.redefineClasses(ClassDefinition[]) говорит: Переопределение может изменить тела методов, постоянный пул и атрибуты. Переопределение не.

Возможный Дубликат : переопределение статического метода и конечного метода Будет ли саб класс, основной способ переопределить супер класс главная? Надеюсь, что основной метод в суперклассе получит.

Как реализовано переопределение метода в Java? В C++ у нас есть понятие vtable.. как это реализовано внутренне в Java?

Как можно переопределить метод из суперкласса в классе, который расширяет суперкласс, в Groovy? Способ Java не работает, так как выполняются оба метода (один в суперклассе и один в подклассе).

Читая о Ковариантном переопределении, я обнаруживаю очень странный факт, переопределение ковариантного метода реализуется с помощью метода мостиков. он также сказал, что эта функция реализована в.

Я узнал о полиморфизме в java и когда метод в (дочернем) расширяющемся классе переопределит метод в родительском классе, а также когда метод перегрузит другой метод. этот сайт очень помог мне.

Я действительно запутался в том, как переопределение сильно отличается от перегрузки в java, так как при реализации перегрузки я вызываю метод с тем же именем, но другой сигнатурой, который является.

У меня есть этот интерфейс Java public interface IFoo < List<Map<String, Object>> getMaps() throws Exception; >как я могу переопределить этот метод ? я пытался : import.

23. Java – Переопределение (overriding)

В предыдущей главе мы рассказали про суперклассы и подклассы. Если класс наследует метод из своего суперкласса, тогда есть шанс переопределить взятый метод, если он не помечен final.

Так что такое в Java overriding или override – это переопределение.

Преимущество в Java переопределения заключается в том, что оно позволяет определять (описывать) поведение, характерное для типа подкласса, значит подкласс может реализовать метод родительского класса на основе его требования.

В объектно-ориентированных терминах, переопределение значит перезапись функционала существующего метода.

Содержание

Пример 1

После запуска программы будет выдан такой результат:

В вышеприведённом примере вы можете заметить, что b хоть и является типом Animal, оно запускает метод move в классе Dog. Причина тому: во время компиляции проходит проверка ссылочного типа. Однако, во время выполнения, JVM определяет тип объекта и запускает метод, который принадлежит этому конкретному объекту.

Следовательно, по примеру выше, программа запустится правильно, так как класс Animal имеет метод move. Затем, во время выполнения, он запускает метод, принадлежащий этому объекту.

Читайте так же:
Можно ли поклеить обои на масляную краску

Рассмотрите следующий пример:

Пример 2

После запуска программы будет выдан такой результат:

Программа выдаст ошибку во время компиляции, так как ссылочный тип b у Animal не имеет метода под именем bark.

Правила переопределения метода

  • Список аргументов должен быть точно таким же, как и для переопределённого метода.
  • Возвращаемый тип должен быть таким же или подтипом возвращаемого типа, объявленного в исходном переопределенном методе в суперклассе.
  • Уровень доступа не может быть более ограниченным, чем уровень доступа переопределённого метода. Например, если метод суперкласса объявлен public, то переопределяемый метод в подклассе не может быть private или protected.
  • Методы экземпляров могут быть переопределены только если они наследованы подклассом.
  • Методы, которые объявлены как final, не могут быть переопределены.
  • Статические методы, которые объявлены как static, не могут быть переопределены, но могут быть повторно объявлены.
  • Если метод нельзя наследовать, то его нельзя переопределить.
  • Подкласс внутри того же пакета, что и суперкласс экземпляра, может переопределять любой метод суперкласса, который не объявлен как private или final.
  • Подкласс в другом пакете может переопределять только не final методы, объявленные как public или protected.
  • Переопределяемый метод может выдавать любые непроверенные исключения вне зависимости от того, переопределяет ли переопределённый метод какие-либо непроверенные исключения или нет. Однако, переопределяемый метод не должен генерировать проверенные исключения, которые являются новыми или более широкими, чем те, которые объявлены переопределённым методом. Переопределенный метод может генерировать более узкие или меньшие исключения, чем переопределенный метод.
  • Конструкторы нельзя переопределить.

Использование ключевого слова super

Вызывая версию суперкласса переопределённого метода, используется ключевое слово super.

Переопределение методов

Если в иерархии классов совпадают имена и сигнатуры типов методов из подкласса и супер класса, то говорят, что метод из подкласса переопределяет метод из супер-класса.

Переопределение методов выполняется только в том случае, если имена и сигнатуры типов обоих методов одинаковы. В противном случае оба методы считаются перегружаемыми.

В следующем примере в классе M определен метод print() . В его наследнике классе N тоже определен метод print() с такой же сигнатурой, но другим поведением. Это и называется переопределением методов:

Существует такое понятие в Java как динамическая диспетчеризация методов — это механизм, с помощью которого вызов переопределенного метода разрешается во время выполнения, а не компиляции.

Переопределение методов это одна из форм реализации полиморфизма. Переопределение метода позволяет определить в общем классе методы, которые станут общими для всех производных от него классов, а в подклассах — конкретные реализации некоторых или всех этих методов.

Рассмотрим более конкретный пример, который показывает зачем переопределяются методы.

Создадим класс Figure , описывающий какую-то абстрактную фигуру и классы наследники Triangle и Rectangle . Класс Figure содержит метод calculateArea() , подсчитывающий площадь фигуры. У каждой фигуры своя формула для подсчета площади, поэтому в классах Triangle и Rectangle метод calculateArea() переопределяется соответствующим образом:

Создадим массив типа Figure , который будет содержать объекты типа Figure , Triangle и Rectangle . Подсчитаем площадь для каждого элемента перебирая элементы массива и вызывая метод calculateArea() для каждого элемента. Нам все равно какого типа объект — у каждого есть вызываемый метод calculateArea() . JVM с помощью динамической диспетчеризации выбирает нужный вариант метода, основываясь на реальном типе объекта:

Читайте так же:
Можно ли убрать батарею в комнате

Результат выполнения кода:

2. Методы подставки

После выхода Java 5 появилась возможность при переопределении методов указывать другой тип возвращаемого значения, в качестве которого можно использовать только типы, находящиеся ниже в иерархии наследования, чем исходный тип. Такие типы еще называются ковариантными.

Например, класс S наследует класс R и переопределяет метод getInstance() . При переопределении возвращаемый тип метода может или остаться таким же — Box6 , или быть изменен на любого наследника класса Box6 — HeavyBox , ColorBox или Shipment :

3. Переопределение и статические методы

Статические методы не могут быть переопределены. Класс наследник может объявлять метод с такой же сигнатурой, что и супер класс, но это не будет переопределением. При вызове переопределенного метода JVM выбирает нужный вариант основываясь на типе объекта. Вызов же статического метода происходит без объекта. Версия вызываемого статического метода всегда определяется на этапе компиляции.

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

Создадим в супер классе и наследнике статические методы с одинаковой сигнатурой:

Попробуем вызвать статический метод используя переменную типа Base , которая указывает на объект типа Sub . При вызове статического метода JVM найдет тип переменной и вызовет метод того же класса:

4. Переопределение методов в классах наследниках

Методы объявленные как private никто, кроме самого класса не видит. Поэтому их наличие/отсутствие никак не отражается на классах наследниках. Они с легкостью могут объявлять методы с такой же сигнатурой и любыми модификаторами. Но это плохой тон! Также класс наследник может расширить видимость protected метода до public . Сузить видимость класс наследник не может.

5. Аннотация @Override

Необязательная аннотация @Override используется с методом для указания того, что он переопределен. Если метод переопределен неверно, код не будет компилироваться:

Русские Блоги

Перегрузка метода Java (Over) и переопределение (override Override)

Перегрузка метода

Определение: Имена методов одинаковы, типы параметров или числа различны, а порядок различен. Это не имеет ничего общего с возвращаемым значением!

Каждый перегруженный метод (или конструктор) должен иметь уникальный список типов параметров.
Наиболее распространенным местом является перегрузка конструктора
Правила перегрузки:

  • Перегруженный метод должен изменить список параметров (количество или тип параметров отличается);
  • Перегруженные методы могут изменить тип возвращаемого значения;
  • Переопределенные методы могут изменять модификаторы доступа;
  • Переопределенные методы могут объявлять новые или более широкие проверки исключений;
  • Методы могут быть перегружены в том же классе или в подклассе
  • Тип возврата перегруженной функции должен оставаться прежним!

Переопределение метода (override)

Прежде всего, определение переопределения таково: если дочерний класс определяет метод или свойство точно так же, как родительский класс (не считая разрешений), такая операция называется переопределением.
Определение переопределения метода: Дочерний класс определяет методы точно так же, как имя метода родительского класса, список параметров и возвращаемое значение. Переопределенные методы не могут иметь более строгие права доступа, чем родительский класс.
Например:

Обратите внимание на следующие два момента при выполнении операции перезаписи:

1. Какой класс new является объектом, который вы используете в данный момент.
2. Используйте объект подкласса для вызова метода. Если метод был переопределен подклассом, то метод должен быть переопределен.

При переопределении метода предъявляются четкие требования: переопределенный объект не должен иметь более строгих разрешений на управление доступом, чем родительский класс.
private <default (ничего не писать) — права доступа к пакету, права доступа в том же исходном файле <public. То есть, если родительский класс использует public для объявления метода, тогда дочерний Класс также должен использовать public: если родительский класс использует default, дочерний класс может использовать default или public.
Неверное переопределение:

Читайте так же:
Можно ли напиться квасом

Вопрос: если родительский метод теперь использует закрытое определение, а дочерний класс использует открытые переопределения, верно?

Если родительский метод теперь использует частное определение, это означает, что метод может использоваться только родительским классом, а дочерний класс не может быть использован. То есть подкласс даже не знает, что родительский класс имеет такой метод.
Если дочерний класс использует public для переопределения вышеуказанного родительского метода, то этот метод является просто новым методом, определенным дочерним классом, и не имеет ничего общего с методом родительского класса.

Модификаторы private, protected, public в Java

Модификаторы доступа private, protected, public ставятся перед именем класса, метода или поля и ограничивают доступ к нему. К локальным переменным модификаторы доступа не применимы.
Помимо этих трех явных модификаторов, есть еще так называемый default-модификатор, или модификатор по умолчанию, иначе говоря — это отсутствие всякого модификатора. Но это отсутствие тоже подразумевает свои правила доступа (видимость только внутри пакета).

Зачем нужны модификаторы доступа

Модификаторы доступа существуют для того, чтобы сделать код надежнее и защищеннее. Нужно максимально ограничивать видимость своих классов, методов и полей, и открывать их только там, где это действительно необходимо. Если вы откроете что-то лишнее, то другой разработчик (или даже вы сами) может по ошибке воспользоваться открытым классом/методом. Чем это чревато? А тем, что если в дальнейшем вы исправите свой код (отвечающий за внутреннюю реализацию, но открытый для пользования извне), то код другого программиста перестанет работать, так как опирается на ваш код. Открывать нужно только то, что вы планируете поддерживать и что будет стабильно работать (без изменения контракта) во всех последующих версиях. Все остальное — внутренняя реализация, которая касается только вас и может меняться, ее никто не должен использовать.

Правила доступа

На картинке показаны правила доступа к полю или методу с конкретным модификатором (последний столбец — про модули, они появились в Java 9):

Модификаторы доступа в Java

Модификаторы доступа в Java

Модификатор private

Это самый ограничивающий модификатор. К полям и методам, помеченным ключевым словом private, можно обратиться только из того же класса, где они находятся.

Допустим у нас есть класс A с private полем privateVar и с private методом privateMethod(). Из класса A мы можем обращаться к полю, см. обращение this.privateVar:

А теперь попробуем обратиться к этому полю и методу из класса B, код не скомпилируется:

Вышеприведенный код выдает ошибки компиляции:

Иногда возникает вопрос

Читайте так же:
Можно ли переделать дизель на газ
Может ли объект A получить доступ к private методам и полям другого объекта A?

Да, может. Обратите внимание на функцию main() из вышеприведенного класса A, в которой создается новый объект A и идет обращение к его методам и полям (не через this):

Как показано выше, мы обращаемся в методе main() к private полю privateVar другого объекта A, и это законно. Все потому, что в Java ограничения доступа применимы на уровне класса, а не на уровне объекта (не обязательно, чтоб обращение шло к тому же экземпляру, главное, что он в том же классе).

Можно ли переопределить private метод?

Нельзя, метод в подклассе не будет иметь никакого отношения к методу в суперклассе, так как private метод нигде не виден. Давайте попытаемся унаследоваться от класса A и «переопределить» private метод privateMethod():

Попробуем создать объект SubA и вызвать privateMethod() на A:

Как видите, срабатывает метод privateMethod() класса A, то есть переопределения не происходит:

Это происходит потому, что метод privateMethod() класса SubA не переопределяет метод privateMethod() класса A, а является независимым методом.

Модификатор default

Если мы не ставим никакого модификатора доступа перед методом, полем или классом, то этот метод/поле/класс видимы из кода только внутри пакета, в котором они находятся.

Давайте продемонстрируем это. Создадим снова класс A в пакете .def:

И создадим в этом же пакете класс B, из которого будем пытаться получить доступ к полям и методам A, как и раньше:

В этот раз код компилируется, все в порядке — доступ есть.

Если бы класс B находится в другом пакете (отличном от ru.sysout.accessmodifiers.def, в том числе в подпакете), то доступа бы не было.

Модификатор protected

Следующий по строгости — модификатор protected. Он также разрешает доступ к помеченным с помощью него полям и методам из кода внутри того же пакета. Но помимо этого, он дает поблажки подклассам, находящимся в другом пакете. Подкласс может обращаться к protected полям и методам суперкласса, даже если подкласс находится в другом пакете.

Снова создадим класс A с protected полем и методом:

Создадим в другом пакете класс C — наследника класса A и попытаемся получить доступ к полям методам класса A из класса C:

Как показано выше, обращение к полю и методу через this работает из другого пакета.

Также работает обращение ко всем другим экземплярам типа C, но к другим экземплярам типа A обращение не работает.

Модификатор public

Тут все просто — к полю и методу с модификатором public имеет доступ любой код. Давайте еще раз перепишем класс A:

И обратимся к его полю и методу из класса B, который находится в другом пакете и никакого отношения к классу A не имеет:

Все получилось, обращение работает.

Какой модификатор выбрать?

Правило выбора модификатора такое — надо по возможности выбирать:

  1. private
  2. default
  3. protected
  4. public

То есть надо максимально ограничивать видимость члена класса. Сначала надо попробовать сделать все private, и при необходимости открывать видимость.

Мы рассмотрели тонкости использования модификаторов доступа. Код примеров можно посмотреть на GitHub.

голоса
Рейтинг статьи
Ссылка на основную публикацию
Adblock
detector