В чем разница между переменной, объектом и ссылкой?

Каковы различия между переменными, объектами и ссылками?

Например: все они указывают на какой-то тип, и все они должны содержать значения (если, конечно, у вас нет временного типа с нулевым значением), но точно, как их функции и реализации отличаются друг от друга?

Пример:

Dog myDog = new Dog(); //variable myDog that holds a reference to object Dog
int x = 12; //variable x that hold a value of 12

У них одни и те же понятия, но как они отличаются?

Ответ 1

(Просто для того, чтобы быть ясным, объяснение, которое я здесь даю, относится к Java и С#. Не предполагайте, что это относится к другим языкам, хотя его могут быть биты.)

Мне нравится использовать аналогию, рассказывая кому-то, где я живу. Я могу написать свой адрес на листе бумаги:

  • Переменная, как лист бумаги. Он содержит значение, но это не само значение. Вы можете перечеркнуть все там и написать что-то другое.
  • Адрес, который я пишу на листе бумаги, похож на ссылку. Это не мой дом, но это способ навигации к моему дому.
  • Мой дом сам по себе подобен объекту. Я могу дать несколько ссылок на один и тот же объект, но есть только один объект.

Помогает ли это?

Разница между типом значения и ссылочным типом - это то, что написано на листе бумаги. Например, здесь:

int x = 12;

похож на листок бумаги с номером 12, написанным на нем напрямую. Принимая во внимание:

Dog myDog = new Dog();

не записывает сам контент объекта Dog на листе бумаги - он создает новый Dog, а затем записывает ссылку на собаку на этой бумаге.

В терминах не-аналогии:

  • Переменная представляет собой место хранения в памяти. Он имеет имя, с помощью которого вы можете ссылаться на него во время компиляции, а во время выполнения оно имеет значение, которое всегда будет совместимо с его типом времени компиляции. (Например, если у вас есть переменная Button, значение всегда будет ссылкой на объект типа Button или некоторый подкласс или ссылку null.)
  • Объект - это своего рода отдельный объект. Важно отметить, что значение переменной или любого выражения никогда не является объектом, а только ссылкой. Объект эффективно состоит из:
    • Поля (состояние)
    • Ссылка на тип (никогда не может меняться через время жизни объекта)
    • Монитор (для синхронизации)
  • Ссылка - это значение, используемое для доступа к объекту - например, вызывать методы на нем, поля доступа и т.д. Обычно вы перемещаетесь по ссылке с помощью оператора .. Например, если foo является переменной Person, foo.getAddress().getLength() принимает значение foo (ссылка) и вызывает getAddress() объекта, на который ссылается эта ссылка. Результатом может быть ссылка String... затем мы вызываем getLength() на объект, на который ссылается эта ссылка.

Ответ 2

Я часто использую следующую аналогию при объяснении этих понятий.


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

Правила для типов значений:

  • Вы держите в своих руках воздушный шар, наполненный воздухом. (Переменные типа значения хранят объект.)
  • Вы всегда должны держать один воздушный шар. (Типы значений не могут быть нулевыми.)
  • Когда кто-то хочет ваш воздушный шар, они могут взорвать свой собственный идентичный и держать его на руках. (В типах значений объект копируется.)
  • Два человека не могут держать один и тот же воздушный шар. (Типы значений не разделяются.)
  • Если вы хотите провести другой воздушный шар, вы должны вытащить тот, который вы уже держите, и захватить другой. (Объект типа значения уничтожается при замене.)

Правила для ссылочных типов:

  • Вы можете держать кусок шнура, который ведет к воздушному шару, заполненному гелием. (Ссылочные типы переменных хранят ссылку на объект.)
  • Вам разрешено удерживать одну часть строки или вообще не содержать ни одной строки. (Переменные ссылочного типа имеют значение NULL.)
  • Когда кто-то хочет ваш воздушный шар, они могут получить свой собственный шнур и привязать его к тому же воздушному шару, который у вас есть. (В ссылочных типах ссылка копируется.)
  • Несколько человек могут удерживать фрагменты строки, которые все ведут к одному воздушному шару. (Объекты ссылочного типа могут совместно использоваться.)
  • Пока есть хотя бы один человек, все еще держащий строку на конкретном шаре, воздушный шар безопасен. (Объект ссылочного типа жив до тех пор, пока он доступен.)
  • Для любого конкретного воздушного шара, если все в конце концов его уйдут, тогда этот воздушный шар улетит, и никто больше не сможет его дотянуться. (Объект ссылочного типа может стать недоступным в какой-то момент.)
  • В какой-то более поздний момент до окончания игры потерянный воздушный шар может появиться сам по себе из-за атмосферного давления. (Недостижимые объекты имеют право на сбор мусора, который не является детерминированным.)

Ответ 3

Вы можете думать об этом как ответы на вопросы.

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

Переменная - это...
Например, если ты смотришь своими руками. Каждый из них - это сама рука. У них есть пальцы, гвозди и кости в коже, но вы знаете, что это ваша левая рука, а другая - правая. То есть вы можете иметь две "вещи" того же типа/вида, но каждый может быть другим по-своему, может иметь разные значения.

Ссылка - это где...
Если вы посмотрите на два дома на улице, хотя у них есть собственный фасад, вы можете добраться до каждого по одному уникальному адресу, то есть если вы далеко, как три квартала далеко или в другой стране, вы можете сообщите адрес дома, потому что они все равно будут там, где вы их оставили, даже если вы не можете указать их напрямую.

Теперь для программирования, примеры в С++-способе

class Person{...}
Person Ana = new Person(); //An object is an instance of a class(normally)

То есть, Ана - это человек, но у нее есть уникальные свойства, которые отличает ее от другого человека.

&Ana //This is a reference to Ana, that is to say, a "where" does the variable 
     //"Ana" is stored, wether or not you know it value(s)

Ana сам является переменной для хранения свойств человека с именем "Ana"

Ответ 4

Джон отлично подходит для приближения к нему по аналогии. Если для вас полезна более конкретная формулировка, я могу подать.

Начнем с переменной. Переменная - это [named] вещь, которая содержит значение. Например, int x = 3 определяет переменную с именем x, которая содержит целое число 3. Если я последую за ней с назначением, x=4, x теперь содержит целое число 4. Главное, что мы не заменили переменная. У нас нет новой "переменной x, значение которой теперь 4", мы просто заменили значение x новым значением.

Теперь перейдите к объектам. Объекты полезны, потому что часто вам нужна одна "вещь", на которую можно ссылаться со многих мест. Например, если у вас открыт документ в редакторе и вы хотите отправить его на принтер, было бы неплохо иметь только один документ, на который ссылаются как редактор, так и принтер. Это избавит вас от необходимости копировать его больше времени, чем вы могли бы захотеть.

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

Итак, в коде при вводе Dog dog = new Dog() новый оператор создает новый объект Dog и возвращает ссылку на этот объект, чтобы он мог быть назначен переменной. Затем присваивание присваивает dog значение ссылки на ваш вновь созданный объект.

Ответ 5

new Dog() будет создавать экземпляр объекта Dog ie), он создаст память для объекта. Вам нужно получить доступ к переменной, чтобы манипулировать некоторыми операциями. Для этого вам нужна ссылка, которая является Dog myDog. Если вы попытаетесь распечатать объект, он выведет нечитаемое значение, которое является не чем иным, как адресом.

      myDog -------> new Dog().