Eu vim de um background em C ++ e estou fazendo um C # no meu trabalho atual e acabei de ler muitas perguntas e respostas sobre qual é a diferença entre campos e propriedades públicas e todas as variações e encarnações disso pergunta básica (por exemplo, este post do SO e todas as perguntas relacionadas ). Todas essas questões são abordadas em termos de diferenças práticas que dão como certa a existência de um sistema de propriedades, mas acho que seria bom abordar esse assunto em termos do que os designers de todas as linguagens que decidiram apoiar propriedades no primeiro lugar estava pensando (confira a lista no artigo da Wikipedia aqui) Como o OOP evoluiu do C ++ / Java para se estender ao que o artigo da Wikipedia identifica de maneira interessante como um meio termo entre métodos e dados de membros:
"Ou seja, as propriedades são intermediárias entre o código do membro (métodos) e os dados do membro (variáveis de instância) da classe, e as propriedades fornecem um nível mais alto de encapsulamento que os campos públicos".
O MSDN adiciona mais informações:
"Embora as propriedades sejam tecnicamente muito semelhantes aos métodos, elas são bastante diferentes em termos de cenários de uso. Elas devem ser vistas como campos inteligentes. Elas têm a sintaxe de chamada dos campos e a flexibilidade dos métodos".
Gostaria de saber como chegou a esse nível intermediário de encapsulamento que se mostrou útil para a programação em geral. Estou assumindo que esse conceito não estava presente na primeira encarnação de linguagens de programação que expressavam o paradigma OOP.
BMI = bob.weight/sq(bob.height)
lê melhor sem()
IMO.Respostas:
É tudo sobre encapsulamento e o princípio de acesso uniforme.
Um objeto deve poder responder a uma mensagem retornando dados existentes ou executando um método, mas o remetente não deve saber qual é qual. Ou, se você vê isso do lado do remetente: o remetente deve poder acessar os dados existentes ou executar um método por meio de uma interface uniforme.
Existem várias maneiras de conseguir isso:
se livrar dos dados por completo, basta ter métodos (o Newspeak faz isso)
livrar-se de métodos completamente, basta ter dados (Self faz isso, "métodos" são apenas
Method
objetos atribuídos a variáveis de instância, variáveis de instância são pesquisadas com despacho virtual)não faça distinção sintática ou semântica entre métodos e dados (Scala faz isso, acessar um campo é sintaticamente indistinguível de chamar um método sem uma lista de argumentos (
foo.bar
), atribuir a um campo é sintaticamente indistinguível de chamar um método especialmente nomeado (foo.bar = baz
) é o mesmo como, por exemplo,foo.bar_=(baz)
chamar um método nomeadofoo_=
e valores somente leitura podem ser substituídos ou implementados por um método sem lista de parâmetros (ou sejaval foo
) em uma superclasse pode ser substituída (ouabstract
val
implementada) em uma subclasse com um métododef foo
)Java, no entanto, não segue o Princípio de acesso uniforme. Em Java, é possível distinguir entre acessar dados e executar um método.
foo.bar
é diferente defoo.bar()
. A razão para isso é que os campos e métodos são semanticamente e sintaticamente distintos.O C # tenta corrigir isso adicionando propriedades ao idioma, basicamente métodos que se parecem com campos. No entanto, as chamadas de método ainda parecem diferentes dos acessos a campos e propriedades. Agora, campos e propriedades têm acesso uniforme, mas os métodos ainda não.
Portanto, isso não resolve o problema: você não pode corrigir duas maneiras diferentes de acessar as coisas adicionando uma terceira maneira de acessar as coisas! Mesmo que essa terceira via pareça uma das outras duas, você ainda terá (pelo menos) duas maneiras diferentes. Você só pode corrigi-lo se livrando de todas as maneiras diferentes, exceto uma, ou se livrando das diferenças.
É perfeitamente bom ter uma linguagem com métodos, propriedades e campos, mas todos os três devem ter acesso uniforme.
fonte
Bem, não tenho 100% de certeza, mas acho que as coisas provavelmente são mais simples do que você espera. Nas escolas de modelagem OO dos anos 90, havia uma demanda por classes de modelagem com atributos de membro encapsulados e, quando implementado em linguagens como C ++ ou Java, isso geralmente leva ao código com muitos getters e setters, portanto, muito "ruído" código para um requisito relativamente simples. Observe que a maioria (provavelmente todas, não verificou isso) dos idiomas listados no artigo vinculado da Wikipedia começou a introduzir "propriedades" de objetos no final dos anos 90 ou posterior.
Eu acho que essa foi a principal razão pela qual os designers de linguagem decidiram adicionar um pouco de açúcar sintático para reduzir esse ruído. E, embora as propriedades certamente não sejam um "conceito essencial de OO", elas pelo menos têm algo a ver com orientação a objetos. Eles não mostram "uma evolução do OOP" (como o título da sua pergunta assume), mas suportam a modelagem de OO no nível da linguagem de programação para facilitar a implementação.
fonte
Você tem isso ao contrário (mais ou menos). O Cálculo Lambda existe como praticamente a base formal para linguagens de programação e existe há décadas. Não possui campos.
Para modelar o estado mutável, é necessário fazer duas abstrações. Um representa a configuração de algum estado, e outro que recupera esse estado (capítulo 13 na minha versão do TaPL para referência). Soa familiar? Do ponto de vista teórico , o OO não evoluiu para ter esse material. OO leu Linguagens de Programação 101 e deu um passo à frente.
De uma perspectiva prática , existem duas motivações bastante claras. Você vem de um background em C ++, então o que precisaria acontecer se você tivesse um campo público - digamos ... o texto em uma caixa de texto. O que acontece quando você deseja alterar seu design para que "sempre que essa caixa de texto for alterada, faça blá"? Você pode matar esse campo, criar uma função ou duas e conectar essa lógica, pois não pode confiar nos desenvolvedores para chamar "UpdateTextbox". Essa é uma alteração muito marcante na sua API (e infelizmente ainda é uma alteração marcante na implementação de propriedades do .NET). Esse tipo de comportamento está em todo lugar na API do Windows. Como isso é um grande negócio na Microsoft, o C # provavelmente queria tornar isso menos doloroso.
A outra grande motivação é o Java Beans e seus parentes. Várias estruturas foram construídas para usar a reflexão Java para procurar
GetX
eSetX
emparelhar e tratá-las efetivamente como propriedades modernas. Mas, como não eram construções reais de linguagem, essas estruturas eram frágeis e pouco controladas. Se você digitasse um nome, as coisas simplesmente quebrariam silenciosamente. Se alguém fosse refatorado, nada mudaria para o outro lado da propriedade. E fazer todo o campo / get / set clichê foi detalhado e tedioso (mesmo para Java!). Como o C # foi desenvolvido amplamente como "Java com lições aprendidas", esse tipo de dor foi uma dessas lições.Mas o mais importante é que o conceito de propriedade foi bem-sucedido. É fácil de entender, é fácil de usar. Isso ajuda muito na adoção e, como ferramenta , os programadores descobriram que as propriedades resolvem um subconjunto de problemas de maneira mais limpa do que funções ou campos.
fonte
No .net especificamente, as propriedades se originam dos dias antigos do Visual Basic, que, por acaso, não eram orientados a objetos da maneira como pensamos hoje. Ele foi amplamente construído em torno do então novo sistema COM, que tratava superficialmente tudo, não necessariamente como classes, mas em termos de componentes que expunham propriedades que poderiam ser acessadas tanto no código quanto nos editores gráficos. Quando o VB e o C # recém-criado foram mesclados no .net, o VB ganhou vários recursos de OOP e manteve propriedades, pois removê-los seria um passo atrás - imagine se a ferramenta de atualização automática de código que eles tinham no Visual Studio tivesse sido usada. substituindo todas as suas propriedades por getters e setters e estava quebrando a compatibilidade com todas as bibliotecas COM. Seria lógico apoiá-los em todos.
fonte
Propriedades não têm nada a ver com programação orientada a objetos, porque propriedades são apenas açúcar sintático. As propriedades parecem superficialmente campos e, no mundo .net, é recomendável que elas se comportem como campos de alguma maneira, mas não são campos em nenhum sentido. As propriedades são açúcar sintático para um ou dois métodos: um para obter um valor e outro para definir um valor. O método definido ou o método get podem ser omitidos, mas não os dois. Pode não haver campo armazenando o valor retornado pelo método get. Como eles compartilham uma sintaxe com os campos e porque costumam usar campos, as pessoas associam propriedades aos campos.
As propriedades têm vantagens sobre os campos:
Como as propriedades são a abstração de campos e, por conveniência sintática, idiomas como C # adotaram a sintaxe de campo para propriedades.
fonte
É uma questão de implementação versus implicação . As propriedades estavam no OOP antes de C ++ ou Java entrarem em cena (elas estavam lá, com alguma rugosidade nas bordas, no Simula, e são fundamentais para o Smalltalk). Entidades com propriedades são conceitualmente diferentes dos valores com código anexado. Os prefixos get & set em algumas convenções de idiomas servem apenas para enlamear as águas; eles informam a diferença entre campos e propriedades, supondo que os campos possam ser acessados diretamente sem obter / definir de uma maneira idiomática para o idioma e com vazamento.
O objetivo principal do OOP é tratar as coisas como se fossem entidades no mundo "real", não apenas como estruturas com algum código misturado. Outro programador deve precisar saber muito, muito pouco, sobre como implementei as coisas, e não deve se preocupar com quais dos vários valores que eles têm permissão para obter e / ou definir são reais e virtuais. Se você encontrar um vetor meu, não precisará saber se estou armazenando ângulo e magnitude ou componentes reais e imaginários internos ao objeto vetorial. Se eu alterar a representação na V2.0 da minha biblioteca, isso não deve afetar o seu código (embora você possa aproveitar os novos recursos interessantes). Da mesma forma, existem propriedades que uma entidade pode ter que dependem de dados externos à entidade, mas que são indubitavelmente propriedades do ponto de vista lexical. Você pergunta às pessoas "quantos anos você tem", e não "faça o cálculo que me revelará sua idade", mesmo sabendo que os dados disponíveis para esse "objeto" são a data de nascimento (um membro imutável privado) e a data de hoje date (uma propriedade ambiental pública com incremento automático, dependente do fuso horário, horário de verão e Linha Internacional de Data). A idade é uma propriedade, não um método, mesmo que seja necessário algum cálculo para chegar lá e não possa (exceto em representações de brinquedos de coisas com vida útil limitada artificialmente) ser armazenada como um campo. mesmo que você saiba que os dados disponíveis para esse "objeto" são a data de nascimento (um membro imutável privado) e a data de hoje (uma propriedade ambiental pública com incremento automático, dependente do fuso horário, horário de verão e Linha Internacional de Data ) A idade é uma propriedade, não um método, mesmo que seja necessário algum cálculo para chegar lá e não possa (exceto em representações de brinquedos de coisas com vida útil limitada artificialmente) ser armazenada como um campo. mesmo que você saiba que os dados disponíveis para esse "objeto" são a data de nascimento (um membro imutável privado) e a data de hoje (uma propriedade ambiental pública com incremento automático, dependente do fuso horário, horário de verão e Linha Internacional de Data ) A idade é uma propriedade, não um método, mesmo que seja necessário algum cálculo para chegar lá e não possa (exceto em representações de brinquedos de coisas com vida útil limitada artificialmente) ser armazenada como um campo.
Em vez de pensar em propriedades como filho bastardo de campos e métodos, é muito mais gratificante considerar os métodos como um tipo especializado de propriedade - coisas que suas entidades podem fazer em vez de coisas que são. Caso contrário, você não está lidando conceitualmente com objetos / entidades, mas com coleções de dados que possuem código anexado a elas. As implementações podem ser idênticas, mas as implicações são diferentes.
Não é necessário dizer, no entanto, que essa abstração tem um custo. Se um programador que usa uma classe não pode dizer se está acessando dados como estão armazenados ou obtendo / configurando valores que precisam ser calculados, haverá um nível em que o idioma também é necessariamente incerto (e, portanto, pode requer que tudo exija código para intermediar entre acessadores / seletores e valores). Não há nada conceitualmente errado com "estruturas com código" - elas certamente podem ser muito mais eficientes - mas vazam a implementação por todo o lado, e essa é uma das coisas que o OOP deve eliminar.
fonte
Absolutamente nada. Propriedades e POO não têm nada a ver uma com a outra. As propriedades nada mais são do que o açúcar sintático para chamadas de função e, portanto, têm exatamente o mesmo anexo de OOP que as chamadas de função fazem - ou seja, nenhuma.
A propósito, a Wikipedia está completamente incorreta. O padrão getMember / setMember que você vê em Java oferece exatamente as mesmas vantagens (e desvantagens) das propriedades em C #. E você pode replicar esse padrão mesmo em C, se desejar.
As propriedades em C # nada mais são do que açúcar sintático suportado por idioma.
fonte