Qual é a diferença entre uma variável, object e referência?

Exatamente quais são as diferenças entre variables , objects e referências ?

Por exemplo: todos eles apontam para algum tipo, e todos eles devem conter valores (a menos que você tenha o tipo temporário nulo), mas precisamente como suas funções e implementações são diferentes umas das outras?

Exemplo:

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

Eles têm os mesmos conceitos, mas como eles são diferentes?

   

(Só para ficar claro, a explicação que estou dando aqui é específica para Java e C #. Não suponha que se aplique a outras linguagens, embora algumas partes dela possam.)

Eu gosto de usar uma analogia de contar a alguém onde eu moro. Eu poderia escrever meu endereço em um pedaço de papel:

  • Uma variável é como um pedaço de papel. Ela contém um valor, mas não é o valor em si. Você pode riscar o que estiver lá e escrever outra coisa.
  • O endereço que eu escrevo no pedaço de papel é como uma referência. Não é minha casa, mas é uma maneira de navegar para minha casa.
  • Minha casa em si é como um object. Eu posso dar várias referências ao mesmo object, mas há apenas um object.

Isso ajuda?

A diferença entre um tipo de valor e um tipo de referência é o que é gravado no pedaço de papel. Por exemplo, aqui:

 int x = 12; 

é como ter um pedaço de papel com o número 12 escrito diretamente nele. Enquanto que:

 Dog myDog = new Dog(); 

não escreve o próprio conteúdo do object Dog no pedaço de papel – ele cria um novo Dog e depois escreve uma referência ao cachorro naquele papel.

Em termos não analógicos:

  • Uma variável representa um local de armazenamento na memory. Ele tem um nome pelo qual você pode consultá-lo em tempo de compilation e, no tempo de execução, ele tem um valor, que sempre será compatível com seu tipo de tempo de compilation. (Por exemplo, se você tem uma variável Button , o valor sempre será uma referência a um object do tipo Button ou alguma subclass – ou a referência null .)
  • Um object é uma espécie de entidade separada. Importante, o valor de uma variável ou qualquer expressão nunca é um object, apenas uma referência. Um object consiste efetivamente em:
    • Campos (o estado)
    • Uma referência de tipo (nunca pode mudar durante a vida útil do object)
    • Um monitor (para synchronization)
  • Uma referência é um valor usado para acessar um object – por exemplo, para chamar methods, campos de access etc. Você normalmente navega na referência com o . operador. Por exemplo, se foo for uma variável Person , foo.getAddress().getLength() o valor de foo (uma referência) e chamará getAddress() no object ao qual essa referência se refere. O resultado pode ser uma referência de String … então chamamos getLength() no object a que essa referência se refere.

Costumo usar a seguinte analogia ao explicar esses conceitos.


Imagine que um object é um balão. Uma variável é uma pessoa. Cada pessoa está na equipe do tipo de valor ou na equipe do tipo de referência . E todos eles jogam um pequeno jogo com as seguintes regras:

Regras para tipos de valor :

  • Você segura em seus arms um balão cheio de ar. (Variáveis ​​do tipo de valor armazenam o object.)
  • Você deve estar sempre segurando exatamente um balão. (Tipos de valor não são anuláveis.)
  • Quando alguém mais quer seu balão, ele pode explodir seu próprio, e segurar isso em seus arms. (Nos tipos de valor, o object é copiado.)
  • Duas pessoas não podem segurar o mesmo balão. (Tipos de valor não são compartilhados.)
  • Se você quiser segurar um balão diferente, você tem que estourar o que você já está segurando e pegar outro. (Um object de tipo de valor é destruído quando substituído.)

Regras para tipos de referência :

  • Você pode segurar um pedaço de corda que leva a um balão cheio de hélio. (Variáveis ​​do tipo de referência armazenam uma referência ao object.)
  • Você tem permissão para segurar um pedaço de corda, ou nenhum pedaço de corda. (Variáveis ​​de tipo de referência são anuláveis.)
  • Quando alguém mais quer seu balão, ele pode pegar seu próprio pedaço de barbante e amarrá-lo ao mesmo balão que você. (Nos tipos de referência, a referência é copiada.)
  • Várias pessoas podem segurar pedaços de corda que levam ao mesmo balão. (Objetos de tipo de referência podem ser compartilhados.)
  • Enquanto houver pelo menos uma pessoa ainda segurando a corda em um balão em particular, o balão estará seguro. (Um object do tipo de referência está ativo, desde que seja acessível.)
  • Para qualquer balão em particular, se todos eventualmente desistirem, então aquele balão voa para longe e ninguém mais consegue alcançá-lo. (Um object de tipo de referência pode se tornar inacessível em algum momento.)
  • Em algum momento posterior, antes do final do jogo, um balão perdido pode aparecer sozinho devido à pressão atmosférica. (Objetos inacessíveis são elegíveis para garbage collection, o que não é determinístico.)

Você pode pensar nisso como responder a perguntas.

Um object é o que …
É como qualquer coisa física no mundo, uma “coisa” que é reconhecível por si só e tem propriedades significativas que se distinguem de outras “coisas”. Como você sabe, um cão é um cachorro porque late, move o rabo e vai atrás de uma bola se você a jogar.

Uma variável é uma que …
Como se você assistisse suas próprias mãos. Cada um é uma mão em si. Eles têm dedos, unhas e ossos dentro da pele, mas você sabe que um é a sua mão esquerda e outro o direito. Ou seja, você pode ter duas “coisas” do mesmo tipo / tipo, mas cada uma pode ser diferente à sua maneira, pode ter valores diferentes.

Uma referência é um lugar onde …
Se você olhar para duas casas em uma rua, embora elas tenham sua própria fachada, você pode chegar a cada uma por seu endereço único, ou seja, se você estiver longe, a três quarteirões de distância ou em outro país, diga o endereço da casa porque eles ainda estarão lá onde você os deixou, mesmo que você não os aponte diretamente.

Agora, para fins de programação, exemplos de uma maneira C ++

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

Ou seja, Ana é uma pessoa, mas ela possui propriedades únicas que a distinguem de outra pessoa.

 &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's value(s) 

Ana si é a variável para armazenar as propriedades da pessoa chamada “Ana”

A resposta de Jon é ótima para se aproximar da analogia. Se uma redação mais concreta for útil para você, posso participar.

Vamos começar com uma variável. Uma variável é uma coisa [nomeada] que contém um valor. Por exemplo, int x = 3 define uma variável chamada x, que contém o inteiro 3. Se eu segui-lo com uma atribuição, x=4 , x agora contém o inteiro 4. A principal coisa é que não substituímos a variável. Nós não temos uma nova “variável x cujo valor é agora 4”, nós meramente substituímos o valor de x por um novo valor.

Agora vamos nos mover para objects. Objetos são úteis porque muitas vezes você precisa de uma “coisa” para ser referenciada em muitos lugares. Por exemplo, se você tiver um documento aberto em um editor e quiser enviá-lo para a impressora, seria bom ter apenas um documento, mencionado tanto pelo editor quanto pela impressora. Isso pouparia você ter que copiá-lo mais vezes do que você poderia querer.

No entanto, como você não quer copiá-lo mais de uma vez, não podemos simplesmente colocar um object em uma variável. As variables ​​mantêm um valor, portanto, se duas variables ​​mantivessem um object, elas teriam que fazer duas cópias, uma para cada variável. Referências são o intermediário que resolve isso. Referências são valores pequenos, facilmente copiados, que podem ser armazenados em variables.

Portanto, no código, quando você digita Dog dog = new Dog() , o novo operador cria um novo Dog Object e retorna uma Reference para esse object, para que possa ser atribuído a uma variável. A atribuição, em seguida, fornece ao dog o valor de uma referência ao seu object recém-criado.

new Dog () irá instanciar um object Dog ie) irá criar uma memory para o object. Você precisa acessar a variável para manipular algumas operações. Para isso você precisa de uma referência que seja Dog myDog. Se você tentar imprimir o object, ele imprimirá um valor não legível, que não é nada além do endereço.

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