Hello! В предыдущих лекциях мы уже несколько раз мельком встречались с таким понятием How наследование. Сегодня мы тоже коснемся этой темы, но тоже не слишком глубоко. Подробная лекция об этом еще будет, а сегодня скорее просто посмотрим практические примеры и познакомимся с одним интересным оператором в Java.
Наследование Java
Итак, что такое, собственно, наследование? Наследование — это механизм в программировании, в том числе и в Java, который позволяет описать новый класс на основе уже существующего. Класс-наследник при этом получает доступ к полям и методам родительского класса. Зачем это может быть нужно? Ну, например, представь, что тебе нужно создать в программе несколько классов машин: Грузовик, Гоночная, Седан, Пикап и т.д. Даже не приступив к написанию codeа, ты точно знаешь, что у этих классов очень много общего: у всех машин есть название модели, год выпуска, объем двигателя, максимальная speed и т.д. (не говоря уже про то, что у всех них есть колеса и прочие детали). В такой ситуации ты можешь:- Создавать эти поля в каждом классе и добавлять их в новые классы машин при их создании
- Вынести общие для всех машин поля в родительский класс
Car
, а все классы конкретных типов машин наследовать отCar
с помощью слова extends.
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
Как минимум, мы избежали ненужного дублирования codeа, а к этому всегда нужно стремиться при написании программ. Кроме того, у нас есть простая и понятная структура классов: общие для всех машин поля вынесены в один класс. Если, например, у грузовиков есть Howие-то специфичные поля, которых нет у остальных машин, их можно объявить в классе Truck
. То же самое касается и методов. У всех автомобилей есть Howое-то общее поведение, которое можно описать: завести авто, газ/тормоз и т.д. Эти общие методы можно вынести в общий класс Car
, а специфическое поведения каждого конкретного типа описать в классах-наследниках.
public class Car {
public void gas() {
//...газ
}
public void brake() {
//...тормоз
}
}
public class F1Car extends Car {
public void pitStop() {
//...пит-стоп делают только гоночные автомобor
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
Мы вынесли общие методы всех автомобилей в класс Car
. А вот в класс-наследник F1Car
, который описывает гоночные автомобor “Формулы-1” — пит-стопы (остановки для срочного обслуживания машины), которые делают только в гонках и выделяются специфическим поведением.
Оператор instanceof Java
Для проверки того, создан ли an object на основе Howого-то класса, в Java существует специальный оператор —instanceof
. Он возвращает meaning true
, если проверка показала истинность, or false
, если результат был ложным. Давай посмотрим, How он работает на примере наших классов с машинами:
public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
Вывод: true Проверка с помощью оператора instanceof
вернула true
, поскольку у нас an object класса Truck
, а все грузовики — это машины. Класс Truck
— наследник класса Car
, следовательно, все грузовики создаются на основе общего родителя — машины. Обрати внимание на оператор instanceof
: он пишется без точки, поскольку это именно оператор, а не метод (“an object instanceof Класс”). Попробуем по-другому:
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
Вывод: false Класс Car
и, соответственно, его an object не происходят от класса Truck
.Все грузовики — это машины, но не все машины — грузовики. Объекты Car
не создаются на основе класса Truck
. Еще один пример:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
Вывод: True Здесь логика тоже проста: все классы в Java, включая те, которые ты создал, происходит от класса Object
(хотя ты и не пишешь в них extends Object — этот механизм заложен в них неявно). Зачем это может пригодиться и при Howих обстоятельствах? Наиболее распространенное применение оператора instanceof
— это переопределение метода equals()
. К примеру, вот How реализован метод equals
в классе String
:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Прежде чем сравнить строку с переданным an objectом, метод проверяет: а является ли, собственно, переданный an object строкой? И уж только потом он начинает сравнивать свойства двух an objectов. Без этой проверки в метод можно было бы передать любой an object, у которого есть поля value и length, и сравнивать его со строкой, что, конечно, было бы неправильно.
GO TO FULL VERSION