В объектно-ориентированном программировании одним из ключевых принципов является полиморфизм, который позволяет объектам различных классов использовать одну и ту же функциональность. Однако, возникает ситуация, когда необходимо изменить реализацию унаследованного метода в классе-потомке без изменения самого метода в классе-родителе. В Java для этой цели используется механизм «сокрытия методов» (method hiding).
Сокрытие методов представляет собой возможность переопределения статического метода в классе-потомке с тем же именем и той же сигнатурой, что и унаследованный метод в классе-родителе. Однако, в отличие от переопределения нестатического метода, при вызове метода с применением объекта класса-потомка, будет вызван метод из класса-потомка, а не из класса-родителя.
Причина такого поведения заключается в том, что статические методы не привязаны к объектам, а являются свойством класса. Они вызываются через имя класса, а не через объект, и поэтому не могут быть полиморфичными. Поэтому, хотя класс-потомок переопределяет статический метод класса-родителя, он фактически не переопределяет его, а скрывает (hides) его.
- Основные принципы сокрытия методов method hiding в Java
- Примеры использования сокрытия методов method hiding в Java
- Принципы работы сокрытия методов method hiding в Java
- Принцип 1: Определение нового метода с таким же именем и сигнатурой в подклассе
- Принцип 2: Доступ к скрытому методу через экземпляр класса
- Примеры использования сокрытия методов method hiding в Java
- Пример 1: Сокрытие метода в подклассе
- Пример 2: Доступ к скрытому методу через экземпляр класса
Основные принципы сокрытия методов method hiding в Java
Основные принципы сокрытия методов в Java:
- Метод в классе-потомке должен иметь ту же сигнатуру, что и метод в классе-родителе, но может иметь другой тип возвращаемого значения.
- Механизм сокрытия методов используется только для статических методов.
- Класс-потомок может вызывать метод класса-родителя через статическую ссылку на объект класса-родителя.
- Метод в классе-потомке может перегружать метод класса-родителя.
Пример:
class Parent {
public static void method() {
System.out.println("Parent's method");
}
}
class Child extends Parent {
public static void method() {
System.out.println("Child's method");
}
}
public class Main {
public static void main(String[] args) {
Parent p = new Child();
p.method(); // вызов метода через ссылку на объект класса-родителя
}
}
В данном примере будет вызван метод Parent’s method, так как методы в Java статические и сокрытие методов используется только для статических методов.
Parent's method
Сокрытие методов method hiding является важной концепцией в Java и позволяет более гибко переопределять и использовать методы в классах-потомках.
Примеры использования сокрытия методов method hiding в Java
Отличие метода, скрытого с помощью keyword «static», от обычного переопределения заключается в том, что скрытый метод не может быть вызван из экземпляра подкласса. Он будет вызван только в контексте базового класса.
Вот пример, иллюстрирующий использование сокрытия методов method hiding:
«`java
class Vehicle {
static void start() {
System.out.println(«Vehicle started»);
}
}
class Car extends Vehicle {
static void start() {
System.out.println(«Car started»);
}
}
public class Main {
public static void main(String[] args) {
Vehicle vehicle = new Vehicle();
Vehicle car = new Car();
vehicle.start(); // Output: «Vehicle started»
car.start(); // Output: «Vehicle started»
}
}
В данном примере у нас есть базовый класс Vehicle и подкласс Car. Оба класса имеют метод start(). Однако, в классе Car метод start() скрыт с помощью keyword «static».
При вызове метода start() через экземпляр класса Vehicle будет вызван метод из базового класса Vehicle. А при вызове метода start() через экземпляр класса Car также будет вызван метод из базового класса Vehicle.
Таким образом, сокрытие методов method hiding позволяет иметь несколько методов с одним именем, но с разными сигнатурами или возвращаемыми типами, что может быть полезно в определенных ситуациях.
Принципы работы сокрытия методов method hiding в Java
Основные принципы работы сокрытия методов method hiding в Java:
- Метод в подклассе должен иметь тот же самый идентификатор, что и метод в суперклассе.
- Метод в подклассе должен быть статическим.
- Метод в суперклассе не должен быть статическим.
При вызове метода сокрытия в Java, компилятор выбирает метод на основе статического типа переменной, а не реального типа объекта. Если переменная имеет статический тип суперкласса и для этого типа определен метод с тем же именем, то будет вызван метод суперкласса, даже если объект на самом деле является экземпляром подкласса.
Пример использования сокрытия методов method hiding в Java:
class Superclass {
public static void print() {
System.out.println("Метод из суперкласса");
}
}
class Subclass extends Superclass {
public static void print() {
System.out.println("Метод из подкласса");
}
}
public class Main {
public static void main(String[] args) {
Superclass obj1 = new Superclass();
Superclass obj2 = new Subclass();
}
}
В данном примере метод print() определен как статический как в суперклассе, так и в подклассе. При вызове метода через переменные, тип которых является статическим типом суперкласса, будет вызван метод из суперкласса. Это иллюстрирует принцип сокрытия методов method hiding в Java.
Принцип 1: Определение нового метода с таким же именем и сигнатурой в подклассе
Когда метод с таким же именем и сигнатурой определен в подклассе, он переопределяет метод родительского класса. Теперь при вызове метода на объекте подкласса будет выполнен переопределенный метод класса-наследника, а не метод родительского класса. Таким образом, метод родительского класса будет сокрыт и недоступен для объектов подкласса.
Пример использования этого принципа:
class Parent {
public void method() {
System.out.println("Метод родительского класса");
}
}
class Child extends Parent {
public void method() {
System.out.println("Метод подкласса");
}
}
public class Main {
public static void main(String[] args) {
Parent parent = new Parent();
Child child = new Child();
Parent childAsParent = new Child();
}
}
В данном примере класс Child наследует класс Parent. Класс Child определяет новый метод с таким же именем и сигнатурой, что метод родительского класса. При вызове метода на объекте подкласса Child будет выполняться метод класса Child, а метод родительского класса будет сокрыт.
Таким образом, принцип определения нового метода с таким же именем и сигнатурой в подклассе является одним из способов сокрытия методов в Java. Он позволяет переопределить метод родительского класса и скрыть его функциональность для объектов подкласса.
Принцип 2: Доступ к скрытому методу через экземпляр класса
Как мы узнали из предыдущего раздела, в Java существует возможность скрыть методы в классе-наследнике, используя аннотацию @Override. Однако это не означает, что скрытые методы становятся полностью недоступными. Все еще есть способы вызвать скрытые методы, например, через экземпляр класса.
Для доступа к скрытому методу через экземпляр класса нужно выполнить несколько шагов:
- Создать экземпляр класса-наследника.
- Привести экземпляр класса-наследника к типу класса-родителя.
- Вызвать метод класса-родителя.
Приведем небольшой пример:
public class Parent {
public void method() {
System.out.println("Родительский метод");
}
}
public class Child extends Parent {
@Override
public void method() {
System.out.println("Скрытый метод");
}
}
public class Main {
public static void main(String[] args) {
Parent parent = new Child();
parent.method();
}
}
В данном примере создается экземпляр класса Child и приводится к типу Parent. Затем вызывается метод method() класса Parent, которым по сути является скрытый метод класса Child. Результат работы программы будет: «Родительский метод». Это происходит потому, что при вызове метода через экземпляр класса вызывается метод класса-родителя, независимо от того, скрыт ли он в классе-наследнике или нет.
Таким образом, принцип 2 показывает, что скрытые методы всегда можно вызвать через экземпляр класса и приведение его к типу класса-родителя. Это может быть полезно, если требуется вызвать метод класса-родителя, недоступный через экземпляр класса-наследника.
Примеры использования сокрытия методов method hiding в Java
Сокрытие методов method hiding в Java позволяет создавать классы-потомки, которые имеют методы с тем же именем и сигнатурой, что и методы в родительском классе, но с различной реализацией. Такой подход позволяет программисту легко переопределить поведение унаследованных методов, не нарушая принцип полиморфизма.
Рассмотрим пример использования сокрытия методов method hiding в Java:
class Animal {
public static void makeSound() {
System.out.println("Animal is making a sound");
}
}
class Dog extends Animal {
public static void makeSound() {
System.out.println("Dog is barking");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
Animal dog = new Dog();
}
}
При использовании сокрытия методов method hiding в Java следует иметь в виду, что нестатический метод может быть сокрытым только другим нестатическим методом, а статический метод может быть сокрытым как другим статическим методом, так и нестатическим методом.
Пример 1: Сокрытие метода в подклассе
Рассмотрим пример, чтобы понять, как происходит сокрытие метода в подклассе:
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
public void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
animal.sound();
Dog dog = new Dog();
dog.sound();
}
}
В данном примере у нас есть класс Animal, который содержит метод sound(). Класс Dog наследует класс Animal и также имеет свой метод sound(), который переопределяет метод родительского класса.
При вызове метода sound() на объекте класса Animal, будет выведено сообщение «Animal makes a sound». А при вызове метода sound() на объекте класса Dog, будет выведено сообщение «Dog barks». Это происходит потому, что метод sound() в классе Dog сокрывает метод sound() в классе Animal.
Пример 2: Доступ к скрытому методу через экземпляр класса
Рассмотрим следующий пример:
class Parent {
private void method() {
System.out.println("Parent's method");
}
}
class Child extends Parent {
private void method() {
System.out.println("Child's method");
}
}
public class Main {
public static void main(String[] args) {
Parent parent = new Child();
parent.method();
}
}
В данном примере у нас есть два класса: Parent и Child. Класс Parent имеет приватный метод method, который печатает «Parent’s method». Класс Child наследует от класса Parent и имеет свой собственный приватный метод method, который печатает «Child’s method».
В методе main мы создаем экземпляр класса Child и присваиваем его переменной типа Parent. Затем мы вызываем метод method через этот экземпляр. Подводя итог, мы можем обратиться к скрытому методу класса Child через экземпляр класса Parent.
В результате выполнения программы будет выведено:
Parent's method
Это происходит потому, что тип переменной parent определяется указанным типом и предоставляет доступ только к методам, объявленным в этом типе (то есть в классе Parent). Таким образом, скрытый метод класса Child скрыт от внешнего кода и не может быть вызван напрямую.