Поля. Модификаторы доступа. Геттеры и сеттеры

Поля

Объект может содержать в себе информацию. Информация хранится в т. н. полях — переменных, которые существуют для каждого экземпляра (объекта) определённого класса.

Опишем новый класс — MobilePhone, экземпляры которого будут иметь уровень заряда.

abstract class MobilePhone extends Phone {
    
    int batteryVoltage;
    
}

Перепишем класс Nokia3310 так, чтобы он наследовал MobilePhone, а не Phone:

class Nokia3310 extends MobilePhone {
…

Создадим новый телефон и зарядим его:

class MobilePhoneTest {
    public static void main(String[] args) {
        MobilePhone myNewPhone = new Nokia3310();
        myNewPhone.batteryVoltage = 4200;
        System.out.println("Напряжение на аккумуляторе: " + 
                myNewPhone.batteryVoltage + " мВ.");
    }
}

Вывод:

Напряжение на аккумуляторе: 4200 мВ.

Модификаторы доступа

Одной из задач ООП является сокрытие реализации: клиент класса не должен «видеть» «внутренности» класса и как-либо зависеть от них, он должен использовать только те методы, которые рассчитаны на внешнее взаимодействие. Такие методы называются публичными.

abstract class MobilePhone {
    
    private String serialNumber;
    private String imei;
    
    public void printSerialNumber() {
        System.out.println("Serial number: " + serialNumber);
    }
    
    public void printImei() {
        System.out.println("IMEI: " + imei);
    }
    
}

В этом примере нельзя получить серийный номер или IMEI мобильного телефона извне, но можно вывести их на экран.

Всего в Java четыре модификатора доступа.

private
приватный — видимость в пределах класса
модификатор не задан, доступ по умолчанию («package-private»)
доступ в пределах пакета — папки с классами
protected
защищённый — доступ в пределах пакета и из наследников — классов, которые наследуют (extends) данный
public
публичный — доступ отовсюду

Геттеры и сеттеры

Читать и записывать поля извне не стоит: для клиента общение с классом должно происходить только посредством методов. Перепишем абстрактный мобильный телефон:

abstract class MobilePhone extends Phone {
    
    private int batteryVoltage;
    
    // так называемый «геттер» — 
    // метод для получения значения поля
    public int getBatteryVoltage() {
        return batteryVoltage;
    }
    // «сеттер» или «мутатор» — метод, который 
    // изменяет значение поля (приводит к мутации)
    public void setBatteryVoltage(int newVoltage) {
        batteryVoltage = newVoltage;
    }
    
}

И его клиента:

class MobilePhoneTest {
    public static void main(String[] args) {
        MobilePhone myNewPhone = new Nokia3310();
        myNewPhone.setVoltage(4200);
        System.out.println("Напряжение на аккумуляторе: " + 
                myNewPhone.getVoltage() + " мВ.");
    }
}

Такой подход имеет несколько преимуществ. Например, можно создать метод, который возвращает значение вместе с единицей измерения:

    // в классе MobilePhone
    public String getDisplayVoltage() {
        return batteryVoltage + " мВ";
    }
    
    // в методе main класса MobilePhoneTest
    System.out.println("Напряжение на аккумуляторе: " + 
            myNewPhone.getDisplayVoltage() + ".");

Можно разрешить чтение значения, но запись сделать опосредованной:

    // подзарядить аккумулятор, добавив 10 милливольт
    public void chargeBattery() {
        batteryVoltage += 10;
    }

Добавить проверку:

    public void chargeBattery() {
        batteryVoltage += 10;
        if (batteryVoltage > 4200) {
            System.out.println("Пыщ!");
        }
    }

Сделать чтение опосредованным:

abstract class MobilePhone extends Phone {
    
    // так объявляются константы
    private static final int MIN_VOLTAGE = 3600;
    private static final int MAX_VOLTAGE = 4200;
    private static final int CHARGE_DIFF = MAX_VOLTAGE - MIN_VOLTAGE;
    
    private int batteryVoltage;
    
    // вернуть уровень заряда в процентах
    public int getBatteryChargePercent() {
        return (batteryVoltage - MIN_VOLTAGE) * 100 / CHARGE_DIFF;
    }
    
    public void chargeBattery() {
        batteryVoltage += 10;
    }
    
}
Комментарии к уроку

Сообщить об ошибке