JavaRush /Java блог /Random /Кофе-брейк #245. Что такое переопределение в Java? Для че...

Кофе-брейк #245. Что такое переопределение в Java? Для чего в Java необходимо ключевое слово Volatile?

Статья из группы Random

Что такое переопределение в Java?

Источник: Medium Из этой публикации вы узнаете о переопределении в Java и правилах переопределения методов в Java. Кофе-брейк #245. Что такое переопределение в Java? Для чего в Java необходимо ключевое слово Volatile? - 1Иногда дочерний класс или подкласс не устраивает реализация метода своего родительского класса или суперкласса, который доступен дочернему классу через наследование. Поэтому у дочернего класса имеется собственная реализация этого метода. Этот процесс известен как переопределение. В переопределяющей функции метод родительского класса называется переопределенным (overridden) методом, а метод дочернего класса называется переопределяющим (overriding) методом Java.

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

Мы можем создать простой пример, чтобы понять концепцию переопределения. У нас есть два класса: класс Parent и класс Child. В классе Parent есть метод marry(), а класс Child расширяет класс Parent. Однако класс Child не удовлетворен реализацией метода marry(), поэтому он обеспечивает реализацию этого метода по-своему. Таким образом, класс Child переопределяет метод marry().

class Parent{
public void marry(){
System.out.println("Arrange Marriage with the Parent's choice");//переопределенный метод (overridden)
   }
}
class Child extends Parent{
public void marry(){
System.out.println("Love/Arrange Marriage with His/Her choice");//переопределяющий метод (overriding)
    }
}


public class Test {
public static void main(String args[]) {
Parent p=new Parent();
p.marry();
Child c=new Child();
c.marry();
Parent p1=new Child();
p1.marry();
    }
}
Вывод:
Arrange Marriage with the Parent's choice Love/Arrange Marriage with His/Her choice Love/Arrange Marriage with His/Her choice
  • В методе переопределения разрешение всегда учитывает JVM (виртуальная машина Java) на основе объекта среды выполнения, поэтому переопределение также известно как полиморфизм времени выполнения, динамический полиморфизм или позднее связывание (late binding).
  • Процесс переопределения разрешения метода также называется отправкой динамического метода (dynamic method dispatch).

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

  • В переопределяющем методе имена и аргументы должны быть одинаковыми, то есть сигнатура метода должна быть такой же.
  • При переопределении метода используемые возвращаемые типы должны быть одинаковыми до версии Java 1.4, но, начиная с версии Java 1.5, разрешено использовать ковариантные возвращаемые типы.
Пример ковариантных возвращаемых типов в переопределении метода:

class Parent {
public Object method1()
{
System.out.println("This is the method in the Parent class");
return new Object();
    }
}
class Child extends Parent {
public String method1()
{
System.out.println("This is the method in the Child class");
return "";
    }
}
public class Test {
public static void main(String[] args)
{
Parent p = new Parent();
p.method1();
Child c = new Child();
c.method1();
    }
}
Вывод:
This is the method in the Parent class This is the method in the Child class
  • Private методы не видны в дочерних классах, поэтому концепция переопределения не применима к таким методам.
  • Final методы родительского класса нельзя переопределить в дочернем классе.
Пример final метода в переопределении:

class Parent {
public final void method1() {}
}
class Child extends Parent {
public void method1() {}
}
public class MyClass {
public static void main(String args[]) {
Parent p=new Child();
p.method1();
    }
}
Вывод:
Test.java:6: error: method1() in Child cannot override method1() in Parent void method1() {} ^ overridden method is final 1 error
  • При переопределении метода мы не можем уменьшить область действия модификатора доступа.
Пример модификатора доступа в переопределении метода:

class Parent{
public void method1()
{
System.out.println("This is the Parent class method");
   }
}
public class Child extends Parent{
protected void method1(){
System.out.println("This is the Child class method");
}
public static void main( String args[]) {
Parent p = new Child();
p.method1();
   }
}
Вывод:
Compile time error: /Child.java:8: error: method() in Child cannot override method() in Parent protected void method(){ ^ attempting to assign weaker access privileges; was public 1 error
→ public → public protected → protected/public → <default> → <default>/protected/public
  • При переопределении, если дочерний класс выдает какое-либо обязательное проверенное исключение, метод родительского класса должен выдавать то же проверенное исключение или исключение его родителя, иначе мы получим ошибку времени компиляции. Но ограничений для непроверенных исключений при переопределении метода нет.
Пример проверенного исключения в переопределении метода:

class Parent {
public void method1() {}
}
class Child extends Parent {
public void method1() throws Exception  {}
}
public class Test {
public static void main(String args[]) {
Parent p=new Child();
p.method1();
    }
}
Вывод:
/Test.java:6: error: method1() in Child cannot override method1() in Parent public void method1() throws Exception {} ^ overridden method does not throw Exception 1 error
Пример непроверенного исключения в переопределении метода:

class Parent {
public void method1() {}
}
class Child extends Parent {
public void method1() throws ArithmeticException  {}
}
public class Test {
public static void main(String args[]) {
Parent p=new Child();
p.method1();
    }
}
  • Мы не можем переопределить статический метод как нестатический и нестатический метод как статический.
  • Метод var-arg следует переопределять только методом var-arg. Если мы попытаемся переопределить с помощью обычного метода, он станет перегруженным, но не переопределяющим.

Для чего в Java необходимо ключевое слово Volatile

Источник: Medium С помощью этого руководства вы получите полное представление о необходимости ключевого слова Volatile и вариантах его использования в Java. Для начала выясним, что мы знаем о ключевом слове Volatile из теории языка Java. Volatile в Java используется для обозначения переменных, которые могут быть изменены разными потоками. Кроме того:
  1. Ключевое слово Volatile указывает, что все операции чтения переменной Volatile произошли до операции записи.
  2. Volatile гарантирует, что каждый поток увидит самое актуальное значение переменной, объявленной как Volatile.
  3. Volatile гарантирует, что значение переменной Volatile считывается непосредственно из основной памяти перед тем, как мы ее используем.
  4. Volatile гарантирует, что значение, записанное потоком, всегда сбрасывается в основную память до завершения инструкции байт-кода.
  5. Volatile не эквивалентно синхронизации критической секции, поскольку оно не требует блокировки.
  6. Ключевым моментом в отношении Volatile является то, что оно допускает только одну операцию в ячейке памяти, которая будет немедленно сброшена в основную память.
  7. Volatile — это режим доступа к оборудованию, который создает инструкцию процессору, в которой говорится игнорировать аппаратное обеспечение кэша и вместо этого читать или записывать в основную память.

Где использовать Volatile

Переменная Volatile должна использоваться для моделирования переменной, где запись в переменную не зависит от текущего состояния переменной. Это следствие того, что Volatile поддерживает только одну операцию. Например, операции ++ и -- -- операции небезопасны для использования с volatile, потому что они эквивалентны v=v+1 и v=v-1. Пример инкремента является классическим примером обновления, зависящего от состояния. Для всех случаев использования, которые зависят от состояния, должны использоваться блокировки взаимного исключения. Volatile не использует никаких блокировок, поэтому не может создавать взаимоблокировки.

public class TaskManager implements Runnable {
    
    private volatile boolean shutdown=false;
    
    public void shutdown()
    {
        shutdown=true;
    }

    @Override
    public void run() {
        while(!shutdown)
        {
            //processing
        }
    }
}
Из кода, показанного выше, следует:
  • Все время, пока флаг выключения равен false, обработка будет продолжаться.
  • Если поток меняется на завершение работы (shutdown), то TaskManager завершит работу после того, как завершит текущую рабочую единицу.
  • Более тонкий момент вытекает из модели памяти Java: любая запись в переменную Volatile происходит до любого последующего чтения этой переменной.
  • Как только другой поток вызовет shutdown() в TaskManager, флаг изменится на true, и эффект этого изменения гарантированно будет виден при следующем чтении этой переменной, то есть до того, как будет принята следующая рабочая единица.
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Кот Уровень 26
2 августа 2023
Наконец-то дошел до уровня, когда понимаю кофе-брейки😎