Класс в Java — это описание или прототип объекта. Класс содержит свойства и методы объекта. В свойствах хранится состояние объекта, а методы описывают поведение объекта.
Возьмем простую строку из программы на Java:
Animal animal = new Animal();
Здесь создается объект animal класса Animal с помощью оператора new.
Давайте рассмотрим подробнее, из чего состоит класс.
Декларация класса
В простейшем случае класс Animal декларируется так:
public class Animal { // ... }
Двойным слэшем обозначается комментарий. Между фигурными скобками находится тело класса — поля и методы.
Обычно класс декларируется в отдельном файле, и имя файла совпадает с именем класса и имеет расширение java. Например, класс Animal хранится в файле Animal.java.
Скомпилируется и несколько классов в файле, но не любых — два публичных класса (с модификатором public) не могут находиться в одном файле. Также имя публичного класса обязано совпадать с именем файла.
Модификаторы доступа рассмотрим позднее, но в данном случае public означает, что к классу Animal доступ возможен из любого места программы, в том числе из другого пакета.
Бывают еще внутренние классы — класс внутри класса — их рассмотрим позднее.
Также класс может наследоваться от другого класса или реализовывать интерфейс.
Тело класса
Тело класса — это то, что находится между фигурными скобками. Оно состоит из полей и методов. Также в нем может быть конструктор — один или несколько.
package ru.sysout.oklassah; public class Animal { // поле private int size; // конструктор public Animal() { } // конструктор public Animal(int size) { this.size = size; } // метод public int getSize() { return size; } }
В вышеприведенном классе Animal есть поле size, метод getSize() и два конструктора Animal() и Animal (int size).
Конструктор
Конструктор используется для создания объектов. То есть он выполняется при создании объекта с помощью оператора new.
Он отличается от метода тем, что его имя совпадает с именем класса и он не возвращает никакого типа. Тут у нас два конструктора, поэтому мы можем создавать объекты типа Animal двумя способами:
Animal animal = new Animal();
или с аргументом:
Animal animal = new Animal(5);
Учтите, что если в теле класса отсутствуют любые конструкторы, то компилятор сам подставляет конструктор без аргументов. То есть первый конструктор можно и не писать, если нужен только он. Но если уже написан конструктор с аргументами, и при этом пустой конструктор без аргументов тоже нужен, то его надо прописать, т.к. компилятор не добавит автоматически конструктор без аргументов при наличии хоть какого-то конструктора в классе.
Наследование
Создадим класс Cat, который наследуется от Animal:
public class Cat extends Animal { // ... }
Смысл наследования в том, чтобы заново не создавать повторяющиеся поля и методы. Ясно, что кошка — это животное, у нее могут быть такие присущие всем животным свойства, как вес, размер. Допустим, у нас будет еще рыба, и она тоже имеет размер и вес. Чтобы не создавать эти свойства в каждом классе, мы их положим в Animal, а в Cat (и Fish) будем создавать только специфические для Cat (и Fish) свойства.
Animal считается суперклассом Cat. Вообще в Java у любого класса уже есть суперкласс, даже если он явно не прописывается, как для Animal. Это суперкласс Object, Animal под капотом наследуется от Object. Компилятор не требует прописывать это наследование в коде, но тем не менее любой объект уже обладает некоторыми свойствами и методами Object (носящими технический характер — например, методом для сравнения объектов), но об этом поговорим позднее.
Реализация интерфейса
Интерфейс — набор абстрактных методов. Реализуются эти методы в классах. (В Java 8 появились default-методы, которые реализуются прямо в интерфейсах, но обычно они не нужны).
Интерфейс — это контракт, который реализуется каждым классом по-своему. Рассмотрим пример. Создадим интерфейс Movable:
public interface Movable { public void move(); }
В нем задекларирован метод move(), но не реализован. Предполагается, что любой класс, реализующий интерфейс Movable, по-своему реализует этот метод. Вот так его реализует Cat:
public class Cat extends Animal implements Movable { @Override public void move() { System.out.println("cat is running"); } }
А вот так его реализует Fish:
public class Fish extends Animal implements Movable { @Override public void move() { System.out.println("fish is swimming"); } }
Как показано выше, implements Movable означает, что класс реализует интерфейс Movable, то есть реализует все абстрактные методы, прописанные в интерфейсе.
Если класс реализует несколько интерфейсов, то они пречисляются через запятую.
Абстрактный класс
Есть еще один вариант задекларировать абстрактный метод move() — можно сделать это не в интерфейсе Movable, а в абстрактном классе — точнее, суперклассе Animal:
public abstract class Animal { public abstract void move(); }
Здесь мы помечаем метод move() ключевым словом abstract и не реализуем его. Также мы помечаем словом abstract сам класс Animal — любой класс, который содержит хотя бы один абстрактный метод, должен быть абстрактным.
Итоги
- Декларация класса выглядит так:
[ модификатор_доступа ] class ClassName [ extends SuperClassName ] [ implements InterfaceNames ] { . . . }
В квадратных скобках выше перечислены необязательные элементы декларации.
- Публичный класс должен находиться в файле с таким же именем.
- Класс можно унаследовать от одного другого класса.
- Любой класс, который мы сами не наследуем от другого класса, является наследником Object.
- Класс может реализовывать несколько интерфейсов.
- Если класс содержит хотя бы один абстрактный метод, то он должен быть абстрактным.
Упражнения
задача 1
Ниже показано содержимое файла Car.java, почему файл не компилируется — найдите ошибку:
class Car{ } public class Toyota extends Car{ }
Задача 2
Скомпилируется ли такой файл Car.java?
class Nexia { } class Mazda { }
Задача 3
Скомпилируется ли Animal.java, если Movable и Eatable — корректно определенные в отдельных файлах интерфейсы:
class Animal implements Eatable, Movable { }
Задача 4
Скомпилируется ли Cat.java, если Animal и Feline — публичные, корректно определенные в отдельных файлах классы:
public class Cat extends Animal, Feline { }
Задача 5
Найдите ошибку компиляции:
class Animal { abstract public void move(); public void eat() {}; }