1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-thinking-in-java-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
5.4 类访问.md 14 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 11.03.2025 09:15 d56454c

5.4 Доступ к классам

В Java также можно использовать спецификаторы доступа для определения, какие классы в библиотеке могут использоваться её пользователями. Чтобы сделать класс доступным для вызова клиентским программистом, следует поместить ключевое слово public перед открывающей фигурной скобкой объявления класса. Это контролирует возможность создания объектов этого класса клиентским программистом.

Для управления доступом к классу спецификатор должен располагаться до ключевого слова class. Таким образом, мы можем использовать:

public class Widget {

Таким образом, если имя нашей библиотеки — mylib, то все клиентские программисты смогут получить доступ к классу Widget с помощью следующего импорта:

import mylib.Widget;

или

import mylib.*;

Однако стоит обратить внимание на некоторые дополнительные ограничения:

(1) В каждом компиляционном модуле (файле) может быть только один публичный класс. Концепция наличия общего интерфейса для каждого модуля выражается через этот публичный класс. Этот класс может иметь любое количество "дружественных" классов, поддерживающих его работу. Однако использование нескольких публичных классов в одном модуле приведёт к ошибке компилятора.(2) Имя публичного класса должно точно совпадать с именем файла, содержащего этот модуль, включая регистр букв. Так что для класса Widget имя файла должно быть Widget.java, а не widget.java или WIDGET.java. Несоответствие имени файла и имени класса приведёт к ошибке компиляции.(3) Возможно (хотя это и не так распространено), что в некоторых компиляционных модулях нет ни одного публичного класса. В этом случае имя файла можно выбрать произвольно.

Если вы уже получили доступ к одному из классов внутри mylib и планируете использовать его для выполнения задач, выполняемых классами Widget или другими публичными классами внутри mylib, какие роли будут играть эти классы? Вы можете не захотеть тратить время на документацию для клиентских программистов и предпочесть удаление своих классов в будущем в пользу других. Для получения такой гибкости важно обеспечить, чтобы клиентские программисты не могли зависеть от конкретных деталей реализации, скрытых внутри mylib. Для достижения этой цели достаточно просто удалить ключевое слово public из объявления класса, тем самым делая его "дружественным" (класс будет доступен только внутри пакета). Не следует объявлять класс как private (это сделает его недоступным для всего остального), а также не следует использовать protected (замечание ④). Поэтому у нас остаются два варианта доступа для класса: "дружественный" или public. Если вы не хотите, чтобы кто-либо другой имел доступ к этому классу, все конструкторы можно объявить как private. В этом случае никто, кроме вас, не сможет создать объект этого класса внутри статического члена класса (замечание ⑤). Пример:```markdown Пример:

public class MyClass {
    private MyClass() {} // Конструктор объявлен как private

    public static void main(String[] args) {
        MyClass myClass = new MyClass(); // Это будет работать
    }

    public static void createInstance() {
        MyClass myClass = new MyClass(); // Это вызовет ошибку компиляции
    }
}

//: Lunch.java
// Демонстрирует спецификаторы доступа класса.
// Создает класс фактически приватным с помощью приватных конструкторов:

class Суп {
  private Суп() {}
  // (1) Разрешает создание через статический метод:
  public static Суп приготовитьСуп() {
    return new Суп();
  }
  // (2) Создает статический объект и возвращает ссылку по запросу.
  // ("Шаблон Singleton"):
  private static Суп псс1 = new Суп();
  public static Суп получитьДоступ() {
    return псс1;
  }
  public void f() {}
}

class Сэндвич { // Использует Обед
  void f() { new Обед(); }
}

// В одном файле может быть только один публичный класс:
public class Обед {
  void тест() {
    // Нельзя сделать это! Приватный конструктор:
    //! Суп прив1 = new Суп();
    Суп прив2 = Суп.приготовитьСуп();
    Сэндвич f1 = new Сэндвич();
    Суп.получитьДоступ().f();
  }
} ///:~
```

4: На самом деле, внутренние классы Java  Yöntemleri 1.1 могут быть как "защищёнными", так и "приватными", но это относится к особым случаям. Подробное объяснение этого вопроса будет дано в главе 7.

5: Также можно достичь этого путём наследования от того класса.
```На данный момент большинство методов, которые мы создали, либо ничего не возвращают (`void`), либо возвращают базовые типы данных. Поэтому следующее определение может вызвать некоторое замешательство:```  
public static Суп получитьДоступ() {
    return псс1;
}
```

Перед названием метода (`получитьДоступ`) указывается слово, которое показывает, что именно этот метод возвращает. До этого момента мы видели только `void`, что означало "ничего не возвращается". Однако также можно вернуть ссылку на объект. В данном случае метод возвращает ссылку на объект класса `Суп`.Класс `Суп` демонстрирует, как можно предотвратить прямое создание экземпляра класса, сделав все его конструкторы приватными. Учтите, что если явно не создан ни один конструктор, то автоматически создается дефолтный конструктор без аргументов. Если вы создаёте свой дефолтный конструктор, он уже не будет автоматически создан. После того, как вы сделали его приватным, никто больше не сможет создать объект данного класса. Но как же использовать этот класс? Пример выше показывает два варианта решения этой проблемы. Первый вариант заключается в том, чтобы создать статический метод, который создает новый объект `Суп` и возвращает ссылку на него. Этот подход особенно полезен, если вам нужно выполнить какие-то действия перед тем, как вернуть объект `Суп`, или если вам нужно контролировать количество создаваемых объектов `Суп`. Второй вариант использует технику "шаблона проектирования" (Design Pattern), которая подробно рассматривается позднее в этой книге. Обычно этот подход называют "синглтоном", так как он позволяет создать только один объект. Объект класса `Soup` создаётся как `static private` член этого же класса `Soup`, поэтому существует только одна его версия и больше создать нельзя. Доступ к нему возможен только через публичный метод `access()`.

```markdown
# Класс Soup

Класс `Soup` демонстрирует, как можно предотвратить прямое создание экземпляра класса, сделав все его конструкторы приватными. Учтите, что если явно не создан ни один конструктор, то автоматически создается дефолтный конструктор без аргументов. Если вы создаёте свой дефолтный конструктор, он уже не будет автоматически создан. После того, как вы сделали его приватным, никто больше не сможет создать объект данного класса. Но как же использовать этот класс?

Пример выше показывает два варианта решения этой проблемы. Первый вариант заключается в том, чтобы создать статический метод, который создает новый объект `Soup` и возвращает ссылку на него. Этот подход особенно полезен, если вам нужно выполнить какие-то действия перед тем, как вернуть объект `Soup`, или если вам нужно контролировать количество создаваемых объектов `Soup`.

Второй вариант использует технику "шаблона проектирования" (Design Pattern), которая подробно рассматривается позднее в этой книге. Обычно этот подход называют "синглтоном", так как он позволяет создать только один объект. Объект класса `Soup` создаётся как `static private` член этого же класса `Soup`, поэтому существует только одна его версия и больше создать нельзя. Доступ к нему возможен только через публичный метод `access()`.
```
Как было отмечено ранее, если для доступа к классу нет явного модификатора доступа, то он автоматически становится "добрым" (friendly). Это значит, что объекты этого класса могут создаваться другими классами внутри того же пакета, но вне него — нет. Важно помнить, что все файлы в одной директории принадлежат по умолчанию к одному и тому же пакету, если они не имеют явной декларации `package`. Однако, если свойство статического члена является `public`, клиентский программист всё равно сможет получить доступ к этому статическому члену, даже если он не может создать экземпляр данного класса.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-thinking-in-java-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-thinking-in-java-zh.git
oschina-mirror
wizardforcel-thinking-in-java-zh
wizardforcel-thinking-in-java-zh
master