Подскажите пожалуйста, чем вызвана необходимость прописывать параметры метода в круглых скобках? Ведь метод итак может использовать любые переменные, которые могут быть прописаны в своем классе.
Например, у нас есть класс с методом, вычисляющим площадь прямоугольника.
public class Rectangle {
double width; // переменные, используемые в классе
double length;
Rectangle (double a, double b) { // конструктор для ввода переменных
width = size;
length = size; }
double volume() { // метод, вычисляющий площадь и возвращающий значения в главный метод
return width*length;
}}
=======================================
public static void main(String[] args) { // А в главном методе мы вводим параметры и вычисляем площадь
Rectangle rectangle = new Rectangle(5,6); // задаем параметры
rectangle.volume(); //вызываем метод для вычисления площади.
}}
ВОПРОС: не понимаю в чем принципиальная разница между переменными в теле метода и параметрами метода, которые должны были бы указываться в скобках. Переменные в теле метода - суть те же параметры, задаваемые извне. Если разница только в количестве кода, то ее вроде нет:
Если я задаю переменные в параметрах - то точно также нужно объявлять тип переменной и ее имя. Чтобы воспользоваться методом с параметрами в главном методе - все равно нужно создавать экземпляр класса. Т.е. все примерно также. Так в чем все-таки принципиальная разница между параметрами метода, указываемых в скобках, и такими же по сути параметрами, которые используются в теле метода, который с пустыми круглыми скобками и который считается методом без параметров?
Wise Rabbit
12 уровень
Параметры в методах в скобках и в теле. В чем разница?
Решен
Комментарии (27)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Стас ПасинковSoftware Developer в ZipyMaster
31 октября 2022, 10:52полезный
вы имеете ввиду параметры, которые вы передаете в конструктор?
или о чем речь?
+1
Wise Rabbit
31 октября 2022, 11:34
В данном случае, о параметрах, передаваемых в метод. У меня получилось небольшая каша в голове)). С одной стороны есть примеры с "методами без параметров", в которых тут же указывается что метод использует в своем теле какие-то переменные (попадающие в него либо из данного класса, либо из главного метода, которые также иногда называют параметрами. (ну и по сути - параметр и переменные - синонимы). Возможно, что предоставление методу параметров через скобки "имя метода(параметр)" ну чуть меньше кода занимает, нежели бы метод брал эти переменные, инициализированные другим способом (например, через конструктор). В связи с этим вопрос: чем способ доставки данных (переменных) в метод через параметры в скобках, отличается от способа доставки этих же данных сразу в тело метода. (Метод же без проблем возьмет эти переменные из конструктора или просто с этого же класса, где сам метод располагается.
Или же есть какие-то особенные, принципиальные различия между параметрами метода и переменными в теле метода, не позволяющие одни заменить другими.
0
Стас ПасинковSoftware Developer в ZipyMaster
31 октября 2022, 14:32решение
нет
отличий нет
просто методов много бывает)
и много методов всякие утилитные. например, считают производную. и тебе придется в этом классе завести тогда переменные под все данные этого метода. что как-минимум не удобно.
удобнее сразу в метод передать что за данные нужно посчитать и он там внутри себя уже посчитал.
переменные/параметры - видны только внутри этого метода и не будут "засорять" другие области видимости.
да, бывают методы без параметров. это когда методу не нужны никакие данные для его работы (либо он возьмет данные из более глобальных областей видимости, например из класса/объекта, либо же ему вообще не нужны никакие входные данные для работы, такое тоже бывает)
насчет метода без параметров в который сразу попадают какие-то параметры - очень похоже на кашу из информации))
или может вы про this такое читали?
или может вопрос у вас немного в другом, просто вы издалека зашли)
+2
Wise Rabbit
1 ноября 2022, 08:39
Спасибо)) Очень хорошее пояснение. Вопрос вроде бы не очень серьезный)), но вот такие ситуации, которые вы отлично сформулировали - "метод без параметров в который сразу попадают какие-то параметры" - иногда приводят к зацикливанию в голове и нужен срочный break)) Спасибо! вы очень хорошо все подробно и структурно объяснили.))
0
Wise Rabbit
1 ноября 2022, 09:02
И вы правы, с this тоже есть подобная заковыка)). Например, если мы из main передаем в другой метод, параметр, то, насколько я понял, не имеет значение каким именем будет назван этот параметр. Имеет значение только его расположение. Например:
public static void main(String[] args) {
int a = 1;
int b = 2;
Box.volume(a,b);
===========
public class Box {
volume (int d, int r) { // в данном случае d = a и r = b
Казалось бы для чего давать такую свободу-ведь вроде проще и понятнее сохранять исходные имена, чем их переименовывать, увеличивая ассортимент имен всех переменных.
В то же самое время, введен специальный оператор this для того чтобы именно не пользоваться этой свободой и сохранять имеющиеся имена без переименований. И если второй случай с this выглядит логичным, то первый менее, т.к. увеличивает вероятность путаницы))) На первый взгляд, конечно) (мой и непрофессиональный ))
0
Стас ПасинковSoftware Developer в ZipyMaster
1 ноября 2022, 20:43
передача параметров в джаве всегда происходит "по значению". то-есть, всегда передается само значение.
не важно, назвали вы свою переменную в мейне а, или ааа или ddd или даже d - это все неважно. в любом случае в метод передастся само значение этой переменной, то-есть 1. которое уже внутри метода попадет в переменную d, да. но вам вот прям вообще не обязательно чтоб эти переменные назывались одинаково, или наоборот, по-разному.
передастся в метод только само значение :)
насчет this - там все чуток сложнее.
многие говорят, что в нестатический метод в любом случае первым скрытым параметром передается this. даже если ваш нестатический метод не принимает никаких параметров - внутри него все-равно можно будет обратиться к this.
наверное так говорят потому, что посмотрели в байткод, и там да, первым прилетает this, а потом уже ваши всякие a и b, или что вы там напишете.
но я это воспринимаю немного не так. мне не очень то и важно как оно там в байткоде реализовано.
я знаю, что если у меня нестатический метод - в нем у меня всегда есть this. вот и все. и сама джава позаботится об этом, и мне не надо даже задумываться об этом.
ЗЫ: кстати, ваш пример кода не совсем корректен. он не скомпилируется потому что из мейна нельзя обратиться к нестатическому контенту (к нестатическому методу volume из вашего примера).
это вот как-раз таки из-за этого this-а. внутри мейна нет никакого this-а. так что либо сначала создаете объект и потом уже у этого объекта вызываете нестатический метод (и в this там попадет сам тот объект). ну либо ошибка компиляции))
+2
Wise Rabbit
2 ноября 2022, 09:57
Спасибо)) Очень интересно)) Я еще не очень глубоко понимаю эту тему, и ваши комментарии очень помогают. (Во всяком случае, подсказывают, в каком направлении стоит подумать)).
==
Из вашего ответа я понял, что для компиляции метода нужно было писать
public class Box {
static volume (int d, int r) {
Верно?
======
А про this и взаимоотношения фрагментов кодов (взаимодействие мейн с классами и объектами) - пока у меня картинка в голове мутная-премутная))
Из ваших слов я понял, что если метод статический, то код такого метода написанный в любом классе может использоваться путем вызова этого метода из мейн. Т.е. мы добавляем к названию метода static и вызываем его из любого места программы. (ну или хотя бы из мейн).
В этом случае именно этот фрагмент кода метода как бы встраивается в мейн, как если бы он прям там и был написан изначально и выполняется. И тогда метод использует те переменные, которые есть в мейн. (при условии, что эти же переменные есть в теле самого метода.) + использует переданные в метод значения параметров.
А если метод нестатический - то надо создавать объект, т.е. копию кода метода (т.е. объект =копию кода с шаблона т.е. с класса). В этом случае названия переменных в каждом объекте (отпечатке с шаблона) будут одинаковые. И если мейн взаимодействует одновременно с 2-мы объектами, то имена переменных из разных объектов не могут быть одинаковыми. И видимо добавление this как бы уникализирует переменную объекта по отношению вообще ко всем переменным программы. И тогда для пользователя она имеет имя удобное для понимания смысла, а для машины- это совершенно уникальная переменная.
Но в этом своем понимании, я тоже очень сильно сомневаюсь))))
Еще раз спасибо, вы очень интересно рассказываете)
0
Стас ПасинковSoftware Developer в ZipyMaster
2 ноября 2022, 11:36
если метод статический - то он может вызывать другие статические методы без дополнительного гемора. а просто НазваниеКласса.имяСтатическогоМетода()
если из статического метода надо вызвать метод объекта (то-есть, вызвать не статический метод) - тогда берем этот объект и вызываем у него его нестатический метод.
если у нас нестатический метод (метод какого-то объекта).
то статические методы вызываем абсолютно так же: НазваниеКласса.имяСтатическогоМетода()
а вот если надо вызвать из этого метода объекта другой метод этого же объекта - тогда можно сделать чуть проще, сразу написать название метода и все. объект создавать не надо
но если надо вызвать нестатический метод другого объекта (не этого, не this) - тогда так же, как и вызов из статического метода: создали объект, вызвали его метод
+2
Стас ПасинковSoftware Developer в ZipyMaster
2 ноября 2022, 11:45
ваш первоначальный пример я б переписал вот так чтобы оно компилировалось.
то-есть, из статического мейна я хочу вызвать нестатический метод volume() класса Box - так что я создал объект класса Box и уже у него вызвал нестатический метод volume()
но вообще, это не по ООП, конечно :)
это, конечно, удобно, что метод volume() будет уметь считать площадь любого прямоугольника (если ему передать длины сторон).
но ведь было бы удобнее, чтобы вообще ничего не передавать в него :)
чтобы метод volume() считал площадь этого (this) объекта прямоугольника))
тот вариант метода, который умеет считать площадь любого прямоугольника - ему ведь не обязательно быть нестатическим (то-есть, он не должен принадлежать только какому-то объекту какого-то класса). ведь этот метод вполне "самостоятельный")) ему передали размеры, он их перемножил и вернул результат.
поэтому такой вариант метода можно было бы даже сделать статическим, чтобы его было проще вызывать (чтобы не приходилось создавать новый объект чтобы вызвать этот метод). и вот тогда это как-раз таки и будет тем вот "утилитным" методом.
а вариант когда этот метод не будет ничего принимать, а будет просто брать размеры своего объекта прямоугольника и считать его площадь - тут да. он нестатический (принадлежит объекту прямоугольника), к тому же ему никаких значений передавать не надо (он просто возьмет их из своего объекта)
+2
Wise Rabbit
2 ноября 2022, 17:10
Спасибо за такой подробный ответ!🙂 Ща буду переваривать)) Прямо статья получилась)) Нужно время, чтобы все это осознать🙂
0
Wise Rabbit
5 ноября 2022, 14:20
Что-то стало проясняться)) Стас, вы могли бы подсказать хорошо структурированный источник, где можно было бы легко находить нужные методы. По лекциям, когда уходишь вперед, уже сложно найти где какие методы и операторы проходили, и если забыл имя метода, то найти и в интернете сложно. Было бы хорошо, если был бы алфавитный список с названием и с переходом в краткое описание. Есть ли такие источники?
0
Стас ПасинковSoftware Developer в ZipyMaster
5 ноября 2022, 19:25
гугл, джавадоки
у меня часто гугл ведет на джавадоки первой же ссылкой)
но их можно и в самой идее посматривать. ставите курсор на класс/метод и нажимаете Ctrl+Q кажется
+2
Wise Rabbit
5 ноября 2022, 19:30
спасибо)) ctrl +Q - пока не так важно. Важно именно вспомнить название метода. Например, если нужен метод сортировки в массиве, то как быстро найти его название и описание? Особенно того метода, который уже ранее использовался в курсе. Я попытался найти такой раздел в джаводоках, но утонул в страницах((. Если вам не сложно, вы могли бы дать ссылку, может я не там искал....
0
Стас ПасинковSoftware Developer в ZipyMaster
7 ноября 2022, 17:03
ну да.
джавадоки - это докуменатция по каждому классу и методу.
открываете ее и читаете. что это за класс такой новый, что он умеет делать, какие методы в нем есть и для чего они.
оно у вас там что-то запомнилось, что-то нет. больше, конечно, не запомнилось, но это норм)
главное, что у вас осталось в голове, что что-то такое вы где-то уже видели)
потом когда вам надо что-то реализовать - тут уже открываете гугл и вводите что-то типа java array sort. потому что вы не помните в каком классе вы такое видели, и уж точно не помните как назывался метод.
и на первой же странице выдачи будет ссылка на документацию)
там же на первой странице в других результатах выдачи можно увидеть и как называется сам класс, и как называется метод)) это просто потому, что оно уж слишком совпадает с самим поисковым запросом)
я вот помню так искал какой метод разворачивает строку. потому что я помню, что где-то читал о нем, и еще подумал тогда: ооо, как удобно! вместо того чтоб циклы какие-то городить - просто метод вызвал готовый и все)
но в классе String такого метода не оказалось) но я помнил, что где-то его видел.
гугл помог "вспомнить" где именно я его видел)
поэтому я и написал их в связке.
сначала читаете джавадоки чтобы знать какие методы есть
а потом пользуетесь гуглом чтобы находить эти методы))
ЗЫ: да, гуглите сразу на английском. реально кучу времени сэкономите
там же на первой странице в других результатах выдачи можно увидеть и как называется сам класс, и как называется метод)) это просто потому, что оно уж слишком совпадает с самим поисковым запросом)
я вот помню так искал какой метод разворачивает строку. потому что я помню, что где-то читал о нем, и еще подумал тогда: ооо, как удобно! вместо того чтоб циклы какие-то городить - просто метод вызвал готовый и все)
но в классе String такого метода не оказалось) но я помнил, что где-то его видел.
гугл помог "вспомнить" где именно я его видел)
поэтому я и написал их в связке.
сначала читаете джавадоки чтобы знать какие методы есть
а потом пользуетесь гуглом чтобы находить эти методы))
ЗЫ: да, гуглите сразу на английском. реально кучу времени сэкономите +2
Wise Rabbit
8 ноября 2022, 07:57
спасибо🙂. Вы давно уже изучаете программирование?)
0
Стас ПасинковSoftware Developer в ZipyMaster
8 ноября 2022, 13:54
я давно работаю :)
и конечно, каждый день что-то новое узнаю. так что да, давно :)
+2
Wise Rabbit
16 ноября 2022, 12:29
Стас, добрый день!)) Можете подсказать, чем конструкторы отличаются от сеттеров. В чем была необходимость в их создании в синтаксисе Java? Ведь и те и другие, насколько я понял, передают в класс значения переменных, используемых в этом классе. И те и другие позволяют создать проверку входящим значениям на соответствие каким-то условиям. Получается, что они дублируют функции друг-друга?
0
Стас ПасинковSoftware Developer в ZipyMaster
16 ноября 2022, 14:45
допустим, вы создали публичный конструктор, но не создали ни одного сеттера.
теперь вы создаете объект котика, тут все ок
но вот если ваш котик постарел, или вы хотели бы его по-другому назвать - то тут у вас проблема, если ваш класс кота - в отдельном файле. потому что вы не имеете доступ к его имени и возрасту (они приватные).
можно, конечно, их сделать публичными - но тогда ж кто угодно может туда залезть своими грязными руками и поставить отрицательный возраст, например, или еще что-то такое.
для этого и нужны сеттеры. чтобы вы могли изменять уже созданный объект.
если же наоборот, сделать сеттеров и оставить только конструктор по умолчанию - тогда все будет работать, да. но само создание объекта получится слегка громоздким:
и если бы вам пришлось реально каждый объект в джаве создавать таким образом - вам было бы неудобно, я думаю))
ЗЫ: чтоб не дублировать проверки - можете в конструкторе вызывать сеттеры :) тогда проверки будут только в сеттерах и все будет ок)
+2
Wise Rabbit
17 ноября 2022, 09:53
Спасибо!! )) Что-то стало проясняться, но еще не полностью. Видимо, я еще не понимаю как код работает в законченном виде...
Я понимаю, что конструктор вводит значения параметров в классе, а не в объекте.
Cat myCat = new Cat("Murzik", 2);
но!
Когда мы хотим изменить параметр конкретного кота через конструктор, то да, мы меняем параметр в именно в классе. Но когда мы создаем объект, то имя этого объекта мы можем не менять и тогда получится, что мы пересоздаем конкретного кота заново:
Cat myCat = new Cat("Murzik", 2); - первый вариант кота
Cat myCat = new Cat("Murzik", 4); - это ведь не другой кот, а перезаписанный (или воссозданный заново кот).
Т.е. вроде как ввод параметров через сеттеры выглядит даже более громоздко:
Cat myCat = new Cat();
myCat.setName("Murzik");
myCat.setAge(2);
Но возможно, я что-то не понимаю в том как работает большой код....Т.е. возможно, что в "Большом коде" есть какая-то такая последовательность, где пересекается сам с собой один и тот же объект, но с разными параметрами (а и в):
1. Создать объект А (а)
2. Изменить параметры А (в) .
3. Применить какой-то метод одновременно к А(а) и к А(в)
И то не понятно можно ли одновременно использовать один и тот же объект с разными параметрами..
0
hidden #598481
17 ноября 2022, 10:24
Воу-воу, не, всё не так.
Давай по порядку.
1. || Я понимаю, что конструктор вводит значения параметров в классе, а не в объекте.
Я здесь вижу непонимание того, что такое класс и объект класса. Класс - это такой набор правил или можно сказать шаблон того, что из себя будет представлять объект этого класса. Если ты просто написал какой-то класс, ты не создал никаких объектов, ты просто задал правила того, что объект этого класса будет обладать теми свойствами (полями класса) и функциями (методами класса). При этом надо понимать, что мы здесь говорим только про нестатические поля и методы, потому что использование модификатора static выводит нас за пределы парадигмы ООП, то есть за рамки концепции "класс - объект класса". А объект этого класса - это представитель этого класса. Если у тебя описан класс Cat, то ты говоришь: "Коты будут такими: у них будет у каждого своё имя, возраст, и у них будет метод помурчать". Самих котов от написания класса Cat нигде не появилось. Ты просто описал правило. А вот когда ты пишешь new Cat("Murzik", 7); то ты создал своего первого объекта с конкретными значениями, и можешь к нему обращаться в соответствии правилами, заданными твоим классом.
И конструктор, как и любой другой метод, - это взаимодействие с объектом, не с классом. Разница только в том, что конструктор сначала создаёт новый объект своего класса, а потом (при наличии команд) выполняет с ним какую-то логику, а другие методы обращаются уже к имеющемуся объекту.
+3
hidden #598481
17 ноября 2022, 10:24
И отсюда мы переходим ко второму неверному тезису в твоём сообщении.
2.
|| Но когда мы создаем объект, то имя этого объекта мы можем не менять и тогда получится, что мы пересоздаем конкретного кота заново:
|| Cat myCat = new Cat("Murzik", 2); - первый вариант кота
|| Cat myCat = new Cat("Murzik", 4); - это ведь не другой кот, а перезаписанный (или воссозданный заново кот).
Ну тут во-первых неверно то, что ты два раза подряд объявляешь одну и ту же переменную. Второй раз "Cat" писать не надо, переменная уже существует.Ну а во-вторых вывод прямо противоположный действительности.
То, что у тебя используется одна и та же переменная myCat ничего не говорит о том, что это один и тот же объект или разные. Переменная - это просто коробка, в которой содержится ссылка на объект. Ты можешь положить туда одну ссылку, можешь выкинуть её и заменить её другой - никакого отношения к созданию объектов это не имеет.
А имеет к этому отношению только то, что находится справа от знака равно. Можешь запомнить как железобетонное правило: каждый раз, когда написано ключевое слово new, выполняется создание нового объекта. Верно и обратное: нельзя создать новый объект, не используя ключевое слово new.
Не всегда ключевое слово new видно при присвоении значения переменной, смотри пример:
Во второй строчке нет слова new, но если заглянуть внутрь метода toCharArray() и посмотреть, что же там возвращается в качестве результата, ты увидишь, что там создаётся именно новый массив при помощи new.
+3
hidden #598481
17 ноября 2022, 10:24
Вернёмся к твоим Мурзикам. Что происходит со старым объектом, который ты создал в первой строчке? Он остаётся существовать в т.н. "куче", но поскольку на него больше не ссылается никакая переменная, то к нему больше нельзя никак обратиться. Жизненный цикл таких объектов заканчивается тем, что их уничтожает специальный механизм джава-машины, который называется сборщиком мусора (Garbage collector, GC). Он освобождает память компьютера от объектов, к которым больше не может обратиться программа. Если ты смотрел фильм "Престиж", то (осторожно, спойлеры!) там главный герой использует такую же концепцию для воссоздания телепортации перед зрителями.
И поэтому, если код с котами написать в идее, то тебе даже сама иде подскажет, что первый кот будет создан напрасно: ты у него не вызываешь никаких действий и просто сразу заменяешь вторым, см. скриншот:
Ну а когда ты в своём коде используешь обычные методы, то там никакого слова new нет. Именно поэтому можно говорить, что методы изменяют состояние того же объекта, у которого они вызваны.
Исходя из всего выше сказанного, становится понятным, что объект не может в один и тот же момент времени обладать разными состояниями, как человек не может одновременно иметь два разных имени или два разных возраста. Он либо не изменён, либо изменён, и тогда у него другое состояние, но оно всегда одно.
Ну а когда ты в своём коде используешь обычные методы, то там никакого слова new нет. Именно поэтому можно говорить, что методы изменяют состояние того же объекта, у которого они вызваны.
Исходя из всего выше сказанного, становится понятным, что объект не может в один и тот же момент времени обладать разными состояниями, как человек не может одновременно иметь два разных имени или два разных возраста. Он либо не изменён, либо изменён, и тогда у него другое состояние, но оно всегда одно. +3
Wise Rabbit
17 ноября 2022, 10:44
Спасибо!)) Попробую переварить))
+1
hidden #598481
17 ноября 2022, 10:46
добавил мелкие правки.
+4
Wise Rabbit
18 ноября 2022, 11:27
Спасибо, очень интересно!)) но вопрос остался. Во-первых, не очень понял, про то, что конструктор в отличии от методов создает объект. Я хотел переспросить действительно ли это так. Возможно, все-таки имелось ввиду следующее:
Считывающий луч джава-машины JVM бежит по коду🙂, и натыкается на строку:
= new Cat("Murzik", 2);
1. VM создает область памяти, куда копирует весь код из класса Cat, образуя объект.
2. Далее, т.к. VM увидела в стартовом коде параметры ("Murzik", 2), то луч ищет в коде объекта конструктор и с его помощью присваивает полям этого объекта значения этих параметров. И таким образом объект у нас готов, а ссылка на него была также создана сразу еще в момент считывания стартовой строки: Cat myCat = new Cat("Murzik", 2).
============
Если нам нужно поменять значения параметров этого созданного объекта Cat myCat, мы должны воспользоваться сеттерами.
Но как только мы ими воспользуемся, можно сказать, что объект поменялся по сути (хотя место в памяти осталось то же). Теперь наш кот Мурзик уже с возрастом 4 вместо 2.
Если же мы создадим новый объект Мурзика, но уже с этими новыми значениями параметров, то да, мы получим физически другой объект (другое место в памяти), но при сохранении его в старую переменную, прежний объект будет уничтожен.
Вопрос в том, что какая нам разница? Зачем нам нужно так дорожить физически первоначальным местом в памяти, где был первый объект. Это же мы не вручную на бумаге переписываем. Компьютер делает это мгновенно. Если нам вздумалось поменять параметры объекта, ну создадим новый объект с новыми параметрами, а старый будет уничтожен. Зачем городить линий код с сеттерами?
0
hidden #598481
18 ноября 2022, 12:23
Дело не в драгоценной памяти и не во времени выполнения. Всё дело в том, что в течение своего жизненного цикла объект используется в разных местах программы, иначе зачем он был бы нужен.
Ну то есть вот создал ты кота. И поместил ссылку на него в список питомцев объекта маленькой девочки. Потом ты захотел изменить имеющегося кота. Не знаю, допустим, помыть кота, whatever. И в процессе этого создал новый объект. При этом в питомцах девочки остался старый, немытый кот, потому что ссылка в списке не менялась, а в другом месте программы появился новый объект, которого почему-то вернул метод cat.wash, и теперь в твоей программе вместо одного кота откуда-то взялось два. Ну и дальше всё пойдёт наперекосяк, изменения в одном объекте никак не будут отражены в другом.
Поэтому всегда стоит воспринимать объект как нечто материальное. В этом случае нужно понимать, что вот тот кот, который существовал у девочки, вот его и нужно помыть. Это проще, пока в ходе учебного цикла чаще используются материальные объекты: коты, дома, люди, предметы. Куда чаще в программах объекты - это всевозможные ридеры, коннекторы и всякие другие "do"-еры, то есть вещи, которые нельзя увидеть в реальном мире, но являющиеся объектами, призванными выполнять какую-то определённую функцию. И весь этот мир живёт по тем же самым правилам, что и материальный. Поэтому так важно сохранять связь между объектами.
+3
Wise Rabbit
18 ноября 2022, 13:22
Спасибо)) примерно я вроде понял...
0