java ООП вызов метода из других классов
Программирование начал изучать не так давно и у меня возник такой вопрос каким способом лучше вызывать метод из других классов. например у меня есть такой класс и метод код в котором всегда один и тот же(неизменяем):
public class Utils < int calculation(int value) < int result = 5 + value return result; >>
вызвать из других классов я могу разными способами например создать объект класса Utils и вызвать метод
public class A
public class B
но если в классе Utils много методов и каждый раз создавать новый объект в разных классах то как мне кажется это лишний расход памяти. Можно сделать метод static но как я понял программисты не очень любят статичные поля и методы из за того что трудно за ними следить и можно получить утечку памяти и т.д. Так же есть шаблон singleton с помощью которого создаётся объект только один раз. Как правильно это сделать в данной ситуации?
Отслеживать
задан 17 фев в 18:41
33 4 4 бронзовых знака
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
На этот вопрос нет однозначного и простого ответа. Есть несколько способов, как этот вопрос решать и в каждом конкретном случае нужно взвешивать за и против для этого конкретного случая.
Статический метод
Этот способ самый простой в реализации и это его плюс. Минус такой, что клиенты класса Utils жестко привязаны к calculation и заменить его на другой нельзя просто.
Создание объекта при использовании
class A < void f() < Utils utils = new Utils(); utils.calcuation(); >>
Из плюсов — довольно просто. Иногда полезно, что экземпляры изолированны, например, если нужно добавить кеширование на время выполнения конеретного метода.
Из минусов — жесткая привязка клиента к реализации, невозможно подменить ее. Если методы вызываются часто и создание делается часто, то возможны проблемы с производительностью.
Создание объекта один раз
class A < Utils utils = new Utils(); void f() < util.calculation(); >>
Минусы и плюсы похожи на предыдущий случай, только все происходит на уровне класса, а не метода.
Паттерн Одиночка он же Синглтон
Это способ отвязать клиентов от конкретного экземпляра. В этом случае можно делать замену используемого объекта, например для тестирования, если сделать возможность замены объекта.
Внедрение зависимости a.k.a. Dependency Injection
class A < Utils utils; public A(Utils utils) < this.utils = utils; >void f() < utils.calculation(..); >>
В этом способе класс A не знает ничего о том, откуда берется объект, который он использует. Это обязанность внешнего кода сконфигурировать зависимости для A. В больших программах для этого используют фреймворки типа guice или spring.
Плюс — минимум зависимостей и максимум возможности конфигурировать. Минус — доп. код, который будет делать конфигурацию.
Паттерн Service Locator
Это более обобщенный singleton. В этом случае клиент зависит от класса, который дает доступ собственно к зависимости:
class ServiceLocator < public Util getUtil() < . >> class A < private ServiceLocator locator; public A(ServiceLocator locator) < this.locator = locator; >public void f() < locator.getUtils().calculation(..); >>
Эта зависимость на сам ServiceLocator может быть тоже выражена по разному (все способы, которые описаны выше применимы — тут я использовал внедрение зависимости).
Отслеживать
ответ дан 17 фев в 20:18
Roman-Stop RU aggression in UA Roman-Stop RU aggression in UA
23.3k 1 1 золотой знак 18 18 серебряных знаков 29 29 бронзовых знаков
программисты не очень любят статичные поля и методы из за того что трудно за ними следить и можно получить утечку памяти
С правильно реализованными статическими методами равно как и с неизменяемыми статическими полями таких проблем не возникает по определению.
Судя по вашему описанию, у вас используются чистые функции, не связанные с бизнес-логикой — т.е. такие, которые обрабатывают только входные аргументы без побочных эффектов и изменения некоего состояния за пределами данной функции, возвращая всегда один и тот же ответ для заданных входных параметров,— их как раз рекомендуется выносить в так называемые утилитарные классы в качестве статических методов.
В частности, это позволяет избежать дублирования кода и значительно упростить тестирование таких функций. Также такие функции являются потокобезопасными.
Примером такой реализации являются хорошо известный класс Math , реализующий вычисления множества математических функций, или статические фабричные методы интерфейса Comparator , позволяющие создать нужный компаратор для объектов заданного типа.
Оговорка о бизнес-логике связана с тем, что бизнес-логика подвержена изменениям, и потому должна быть легко заменяема, например, при помощи классов-потомков. Таким образом, статические методы не применимы для таких целей.
Для утилитарных классов характерно наличие приватного дефолтного конструктора, который может быть пустым, или даже выбрасывать исключение типа UnsupportedOperationException (см. Lombok @UtilityClass )
Как вызвать метод класса в основном классе
Как вызвать в классе Main метод shoot?
Если создать объекты класса Towers в Main, тогда мой switch ломается. А если создавать в классе Towers, тогда не могу вызвать, допустим, machineGun.shoot() в классе Main.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как вызвать метод из одного класса чтобы он был виден в другом классе?(Отсылка от старой темы)
Добрый вечер,Я почти разобрался только у меня последний вопрос Как исправить?Смотрите скрин. Надо.

В классе OnlyData написать метод, который выводит значение переменной i и вызвать этот метод в том же классе
Я конечно понимаю, что задача оч простая, но все же. В классе OnlyData нужно написать метод.

Как в классе А у объекта класса B вызвать метод класса B ?
Есть Класс A и класс B . В классе B лежит объект типа ArrayList , назовём его arrayList, в этом.

Как в классе А у объекта класса B вызвать метод класса B ?
Есть Класс A и класс B . В классе B лежит объект типа ArrayList , назовём его arrayList, в этом же.
Регистрация: 25.06.2018
Сообщений: 155
1 2 3 4 5 6 7 8 9 10 11
public class Main{ public static void main (String[] args) { //создаешь экземпляр класса Towers Towers exemp = new Towers (); //вызываешь нужный метод например getExp exemp.getExp(); } }
Добавлено через 1 минуту
Зачем создавать экземпляры класса Towers в самом классе Towers?
614 / 488 / 175
Регистрация: 02.03.2010
Сообщений: 1,238
Сообщение от cinemaster4d 
Зачем создавать экземпляры класса Towers в самом классе Towers?
Более интересно, почему Towers наследован от Main.
Как вызвать метод из класса java
class A <
void metA() < System.out.println("metA"); >
>
class B extends A <
void metA() < System.out.println("metB"); >
>
public class Main <
public static void main(String[] arg)
>
>
а как вызвать , чтобы напечаталось System.out.println(«metA») ?
или если B b= new B(); как вызвать metA предка?
Re: а как вызвать метод предка (OOP Java)
| От: | Аноним |
| Дата: | 04.11.07 09:14 |
| Оценка: |
Здравствуйте, Аноним, Вы писали:
А> как вызвать metA предка?
Re: а как вызвать метод предка (OOP Java)
| От: | dshe |
| Дата: | 04.11.07 09:17 |
| Оценка: |
Здравствуйте, Аноним, Вы писали:
А>class A< А>void metA() < System.out.println("metA"); > А>> А>class B extends A< А>void metA() < System.out.println("metB"); > А>> А>public class Main< А>public static void main(String[] arg)< А>A a =new B(); А>a.metA(); // А>> А>>
А>а как вызвать , чтобы напечаталось System.out.println(«metA») ?
А>или если B b= new B(); как вызвать metA предка?
Если кратко, то никак. Вызов метода предка (A) в обход потомка (B), в общем случае чревато наруpшением внутреннего инварианта потомка (B).
Однако в твоем случае можно достичь желаемой цели переписав немного код.
class A< void metA() < metAReal(); >final void metAReal() < System.out.println("metA"); > > class B extends A< void metA() < System.out.println("metB"); > > public class Main< public static void main(String[] arg)< A a =new B(); a.metAReal(); // metA
class A< void metA() < metAReal(this); > static void metAReal(A a) < System.out.println("metA"); > > class B extends A< void metA() < System.out.println("metB"); > > public class Main< public static void main(String[] arg)< A a =new B(); A.metAReal(a); // metA
Re: а как вызвать метод предка (OOP Java)
| От: | GarryIV | |
| Дата: | 04.11.07 09:27 | |
| Оценка: | 1 (1) +1 | |
Здравствуйте, Аноним, Вы писали:
А>или если B b= new B(); как вызвать metA предка?
Когда возникают такие желания, надо в первую очередь смотреть а почему так происходит. Не нарушаются ли LSP и OCP.
Если твой вопрос не теоретического характера а вызван реальной проблемой то лучше опиши все как есть на самом деле. Потому как то что тебе тут посоветовали уже криво до безобразия.
WBR, Igor Evgrafov
Re[2]: а как вызвать метод предка (OOP Java)
| От: | dshe |
| Дата: | 05.11.07 09:05 |
| Оценка: |
Здравствуйте, GarryIV, Вы писали:
GIV> . Потому как то что тебе тут посоветовали уже криво до безобразия.
Как вызвать метод из класса java
public static void main(String[] args) Каждый раз пишем эту магическую строку, что бы запустить нашу программу. MAIN — обозначает точку входа в программу. Мы можем один раз написать этот метод в главном классе, например Main:
public class Main public static void main(String[] args) // просто тестирование > >
Следующим методом мы можем написать метод сложения двух целых чисел. Название метода addition мы пишем с маленькой буквы.
static void addition ()
И тогда мы можем в нашей точке входа запустить(вызвать) метод сложения и весь наш класс тогда будет выглядеть вот так:
public class Main public static void main(String[] args) addition(); > static void addition() int a = 4; int b = 5; int c = a + b; System.out.println(c); > >
Создание класса #
Точно также мы можем создать совсем новый класс для вычисления целых чисел. И назвать его Calculator, и в нём написать наш метод:
public class Calculator static void addition() int a = 4; int b = 5; int c = a + b; System.out.println(c); > >
Аргументы #
Мы можем сделать метод принимающим параметры(атрибуты, аргументы), например так:
static void addition (int a, int b)
Тогда запустить этот метод в Main можно, давайте сначала подумаем как, а потом попробуем посмотреть:
Calculator.addition(a, b); //Запускать метод мы можем один или несколько раз Calculator.addition(4, 7); Calculator.addition(17, 25);
Метод сам по себе у нас может быть нетронутым и только в месте его вызова мы “манипулируем” с аргументами.
Типы методов #
Принципиально в Java два типа методов:
- Исполняемые (void). Эти методы просто исполняют команды.
- Возвратные. Эти методы всегда что-то возвращают.
Пример метода, который возвращает значение int:
public static int devide()
Пример метода, который возвращает int и принимает два int аргумента
public static int devide(int a, int b) < return a / b; >
Пример метода, который принимает String, а возвращает int:
public static int vornameAndName(String vorname, String name)
Очень важно понимать, что main вход в программу, с этого метода начинаются необходимые действия. Например на условной кассе в магазине в точке мейн запускается процесс подсчитывания стоимости продуктов, и после этого стоимость передаётся в метод вывода чека на печать и ещё раз на экране у кассира. Нет хороших или плохих методов, удобных или неудобных; это просто инструменты и левша может использовать другие инструменты чем правша. “Правильность” особо нигде не прописана.
Ещё один пример. Нам надо поехать в отпуск:
public class Main public static void main(String[] args) weGoOnVacation(); > static void weGoOnVacation() // псевдометод, который описывает, что надо сделать что бы поехать в отпуск bookFlights(); bookHotel(); packUp(); callTaxi(); excellentMood(); > static void excellentMood() //каждый из этих методов описывает как добиться поставленной цели. а может вызывать и другие дополнительные методы. // например для хорошего настроения нужно отключиться от работы и улететь туда где тепло > >
Зарезервированные слова #
| Нельзя | использовать | в | переменных |
|---|---|---|---|
| abstract | double | int | super |
| boolean | else | interface | switch |
| break | extends | long | synchronized |
| byte | final | native | this |
| case | finally | new | throw |
| catch | float | package | throws |
| char | for | private | transient* |
| class | goto* | protected | try |
| const* | if | public | void |
| continue | implements | return | volatile |
| default | import | short | while |
| do | instanceof | static |
Модификаторы доступа. Private, protected, default, public #
- private;
- default;
- protected;
- public.
Private — наиболее строгий модификатор доступа. Он ограничивает видимость данных и методов пределами одного класса.
Default — package visible.
Protected — package visible.
Protected data member and method are only accessible by the classes of the same package and the subclasses present in any package. You can also say that the protected access modifier is similar to default access modifier with one exception that it has visibility in sub classes.
Public — Кто угодно может этим пользоваться.
| _ | Class | Package | Subclass(same pkg) | Subclass(diff pkg) | World |
|---|---|---|---|---|---|
| public | + | + | + | + | + |
| protected | + | + | + | + | |
| no modifier | + | + | + | ||
| private | + |
Модификатор static в Java #
Static показывает, что это метод или переменная класса. На данном этапе большего нам знать пока не надо.
public class HelloStatic private static int count = 10; public static void main(String args[]) System.out.println(count); //compile time error > >
Дополнительные материалы #
- https://www.oreilly.com/library/view/think-java/9781491929551/ch04.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/returnvalue.html
- https://www.baeldung.com/java-methods
- Ещё раз ссылка с конвенцией (договор о правописании и синтаксисе) — https://www.oracle.com/technetwork/articles/javaee/codeconventions-135099.html
- https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Домашнее задание #
- Давайте попробуем написать методы для вычисления площади и периметра фигур: квадрата, прямоугольника, треугольника, круга. И один раз напишем их исполняющими, а один раз возвратными. В обоих случаях методы должны принимать необходимые данные для вычисления: как радиус, длину сторон или прочее.
- Давайте напишем генератор паролей. Методу передаётся длина пароля. И метод генерирует пароль используя латиницу, цифры и некоторые спецсимволы(на ваш выбор). Подсказка — использовать только те знания, которые были уже изучены. Существует как минимум два(на самом деле 222) разных подхода к решению этой проблемы. Не бойтесь пробовать.
