Изучение наследования на языке программирования Java
Наследование – одна из основных концепций объектно-ориентированного программирования. В программировании слово наследование представляет отношения, в которых дочерний класс принимает состояние и поведение родительского класса.
Цель наследования при разработке программного обеспечения – облегчить повторное использование безопасного и надежного программного обеспечения. Одним из основных преимуществ использования наследования является то, что оно устраняет избыточный код в ваших программах.
Как работает наследование
Идея наследования заключается в том, что многие классы или объекты имеют один и тот же набор атрибутов и методов. Следовательно, в духе создания надежного программного обеспечения новые классы теперь могут извлекать из уже существующих связанных классов и, при необходимости, расширять существующие состояния и поведения.
Реальный пример того, как работает наследование, – это фрукты. Это широкий ярлык, который служит для обозначения ряда различных элементов.
Яблоко – это фрукт, и апельсин – тоже. Однако апельсин – это не яблоко, поэтому у вас не было бы фруктов в качестве одного из предметов на складе, если бы у вас был магазин. Возможно, у вас в инвентаре есть секция фруктов, и в ней будут более конкретные предметы, такие как яблоки и апельсины.
Так работает наследование.
Использование наследования в Java
Наследование можно использовать на любом языке программирования, который использует парадигму объектно-ориентированного программирования . Однако точный способ использования наследования зависит от конкретного языка программирования.
Например, C ++ также является объектно-ориентированным языком программирования . C ++ поддерживает так называемое множественное наследование, тогда как Java поддерживает только одиночное наследование.
Это означает, что в Java родительский класс может иметь много дочерних классов, но каждый дочерний класс может иметь только один родительский класс (единственное наследование). Однако в Java есть способ добиться непрямого множественного наследования, создав отношения между дедушкой и дедушкой, родителем и потомком.
Создание родительского класса в Java
Процесс выбора родительского класса из документа требований к программному обеспечению известен как объектно-ориентированный анализ. Во время этого процесса фраза «is a» часто используется для обозначения возможных отношений наследования. Из приведенного выше примера вы должны увидеть, что плод будет нашим родительским классом.
Пример родительского класса Fruit
public class Fruit {
//Variable Declaration
protected String seed;
protected String skinColor;
protected String taste;
//Default Constructor
public Fruit(){
seed = "";
skinColor ="";
taste ="";
}
//Primary Constructor
public Fruit(String seed, String skinColor, String taste){
this.seed = seed;
this.skinColor = skinColor;
this.taste = taste;
}
//getters and setters
public String getSeed() {
return seed;
}
public void setSeed(String seed) {
this.seed = seed;
}
public String getSkinColor() {
return skinColor;
}
public void setSkinColor(String skinColor) {
this.skinColor = skinColor;
}
public String getTaste() {
return taste;
}
public void setTaste(String taste) {
this.taste = taste;
}
//eat method
public void eat(){
//general code on how to eat a fruit
}
//juice method
public void juice() {
//general code on how to juice a fruit
}
}
Одним из наиболее примечательных аспектов вышеприведенного родительского класса является модификатор доступа, который используется с каждым объявлением переменной. Модификатор доступа «protected» идеально подходит для использования в родительских классах, поскольку он предотвращает доступ недочерних классов к атрибутам данных родительского класса.
Далее в коде вы познакомитесь с конструкторами, геттерами и сеттерами, которые являются общими строительными блоками для любого класса Java. Наконец, вы познакомитесь с двумя методами (сок и есть), которые созданы в родительском классе нашей программы, потому что они универсальны для всех фруктов – все фрукты можно есть и выжимать сок.
Создание дочерних классов в Java
Дочерние классы обычно называются специализированными или производными классами, потому что они наследуют состояние и поведение от родительского и часто настраивают эти атрибуты, чтобы быть более конкретными.
Продолжая наш пример, вы должны быть в состоянии понять, почему апельсин может быть подходящим дочерним классом вышеупомянутого фруктового класса.
Пример дочернего класса Orange
public class Orange extends Fruit{
//variable declaration
private int supremes;
//default constructor
public Orange() {
supremes = 0;
}
//primary constructor
public Orange(String seed, String skinColor, String taste, int supremes){
super(seed, skinColor, taste);
this.supremes = supremes;
}
//getters and setters
public int getsupremes() {
return supremes;
}
public void setsupremes(int supremes) {
this.supremes = supremes;
}
//eat method
public void eat(){
//how to eat an orange
}
//juice method
public void juice() {
//how to juice and orange
}
//peel method
public void peel(){
//how to peel an orange
}
}
Есть разница между тем, как выглядит обычное объявление класса Java, и тем, что есть в нашем коде выше. Ключевое слово extends – это то, что используется в Java, чтобы сделать наследование возможным.
В нашем примере выше дочерний класс (оранжевый) расширяет родительский класс (фрукт). Следовательно, состояние и поведение класса фруктов теперь могут быть доступны и изменены классом апельсина.
Уникальный атрибут, которым обладает наш оранжевый класс, идентифицируется с помощью имени переменной supremes (которое является официальным названием маленьких сегментов апельсинов). Здесь в игру вступает специализация; не все фрукты имеют супремы, но все апельсины имеют, поэтому резервирование переменной supremes для апельсинового класса логично.
Добавление метода «чистки» к уже существующим методам «съесть» и «сок» также логично, потому что, хотя не все фрукты можно очистить от кожуры, апельсины часто снимаются.
Вы должны иметь в виду, что если бы мы не намеревались изменять существующие методы «eat» и «сок», нам не нужно было бы включать их в наш класс Orange. Методы оранжевого класса переопределяют любой аналогичный метод в классе фруктов. Итак, если бы все фрукты съедались и выжимались одинаково, нам не нужно было бы создавать эти методы в классе апельсина.
Роль конструкторов в наследовании
По умолчанию конструкторы родительского класса наследуются дочерними классами. Следовательно, если создается объект дочернего класса, это означает, что объект родительского класса также создается автоматически.
Возвращаясь к нашему примеру, каждый раз, когда создается новый оранжевый объект, также создается фруктовый объект, потому что апельсин – это фрукт.
За кулисами, когда создается объект дочернего класса, сначала вызывается конструктор родительского класса, а затем конструктор дочернего класса. В нашем оранжевом дочернем классе выше, если оранжевый объект создается без каких-либо параметров, будет вызван конструктор класса фруктов по умолчанию, за которым следует наш подрядчик оранжевого класса по умолчанию.
Метод «super» в нашем первичном конструкторе выше необходим, потому что он указывает, что основной конструктор – а не конструктор по умолчанию – родительского фруктового класса должен вызываться всякий раз, когда создается оранжевый объект с параметрами.
Теперь вы можете использовать наследование в Java
Из этой статьи вы узнали, что такое наследование, как оно работает и почему это так важно в программировании. Теперь вы можете создавать отношения наследования, используя язык программирования Java. Более того, теперь вы знаете, как обойти правило единственного наследования Java, создавая отношения дедушки и бабушки.
Кредит изображения: Андреас Вольфарт / Pexels