Класс в Java

Класс в 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, а в CatFish) будем создавать только специфические для 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() {};
}
О модификаторах доступа public, private, protected читайте далее.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *