No primeiro semestre, fomos apresentados aos conceitos de OOP, como encapsulamento, ocultação de dados, modularidade, herança e assim por diante através de Java e UML. (Java é minha primeira linguagem de programação)
Nenhum desses são conceitos de POO. Todos eles existem fora do OO, independentemente do OO e muitos até foram inventados antes do OO.
Então, se você acha que é disso que se trata o OO, sua conclusão é correta: você pode fazer tudo isso em linguagens processuais, porque eles não têm nada a ver com o OO .
Por exemplo, um dos documentos seminais sobre Modularidade é Sobre os critérios a serem usados na decomposição de sistemas em módulos . Não há menção de OO lá. (Foi escrito em 1972, então o OO ainda era um nicho obscuro, apesar de já ter mais de uma década.)
Embora a Abstração de Dados seja importante no OO, é mais uma consequência do recurso principal do OO (Sistema de Mensagens) do que um recurso definidor. Além disso, é muito importante lembrar que existem diferentes tipos de abstração de dados. Os dois tipos mais comuns de abstração de dados em uso atualmente (se ignorarmos "nenhuma abstração", que provavelmente ainda é usada mais do que as outras duas combinadas) são tipos e objetos de dados abstratos . Assim, apenas dizendo "Information Hiding", "Encapsulation" e "Data Abstraction", você não disse nada sobre OO, pois OO é apenas uma forma de Abstração de Dados, e as duas são de fato fundamentalmente diferentes:
- Com tipos de dados abstratos, o mecanismo para abstração é o sistema de tipos ; é o sistema de tipos que oculta a implementação. (O sistema de tipos não precisa necessariamente ser estático.) Com Objetos, a implementação fica oculta por trás de uma interface procedural , que não requer tipos. (Por exemplo, ele pode ser implementado com fechamentos, como é feito no ECMAScript.)
- Com Tipos de dados abstratos, instâncias de ADTs diferentes são encapsuladas uma da outra, mas instâncias do mesmo ADT podem inspecionar e acessar a representação e implementação privada uma da outra. Os objetos são sempre encapsulados de tudo . Somente o próprio objeto pode inspecionar sua própria representação e acessar sua própria implementação privada. Nenhum outro objeto , nem mesmo outros objetos do mesmo tipo, outras instâncias da mesma classe, outros objetos com o mesmo protótipo, clones do objeto ou qualquer outra coisa que possa fazer isso. Nenhuma .
A propósito, o que isso significa é que, em Java, as classes não são orientadas a objetos. Duas instâncias da mesma classe podem acessar a representação e a implementação privada uma da outra. Portanto, instâncias de classes não são objetos, na verdade são instâncias ADT. Java interface
s, no entanto, não fornecem abstração de dados orientado a objetos. Portanto, em outras palavras: apenas instâncias de interfaces são objetos em Java, instâncias de classes não.
Basicamente, para tipos, você só pode usar interfaces. Isso significa tipos de parâmetros de métodos e construtores, tipos de métodos de retorno, tipos de campos de instância, campos estáticos e campos locais, o argumento para um instanceof
operador ou operador de conversão e argumentos de tipo para um construtor de tipo genérico sempre devem ser interfaces. Uma classe pode ser usada apenas diretamente após o new
operador, em nenhum outro lugar.
Por exemplo, para modularidade, podemos simplesmente dividir o programa em muitos pequenos programas que executam tarefas bem definidas, cujo código está contido em arquivos separados. Esses programas interagem entre si por meio de entradas e saídas bem definidas. Os arquivos podem ser protegidos (criptografados?) Para obter o encapsulamento. Para reutilização de código, podemos chamar esses arquivos sempre que forem necessários em novos programas. Isso não captura tudo o que é OOP ou estou perdendo algo muito óbvio?
O que você descreve é OO.
Essa é realmente uma boa maneira de pensar sobre OO. De fato, isso é exatamente o que os inventores originais da OO tinham em mente. (Alan Kay foi um passo além: ele imaginava muitos computadores pequenos enviando mensagens entre si pela rede.) O que você chama de "programa" geralmente é chamado de "objeto" e, em vez de "chamada", costumamos dizer "enviar uma mensagem" "
Orientação a Objetos tem tudo a ver com Mensagens (também conhecido como despacho dinâmico ). O termo "Orientado a Objetos" foi cunhado pelo Dr. Alan Kay, o principal designer do Smalltalk, e ele o define assim :
OOP para mim significa apenas mensagens, retenção e proteção local e ocultação de processos estatais e vinculação extrema de todas as coisas.
Vamos detalhar isso:
- sistema de mensagens ("despacho de método virtual", se você não estiver familiarizado com o Smalltalk)
- processo estadual deve ser
- retido localmente
- protegido
- escondido
- extrema ligação tardia de todas as coisas
Em termos de implementação, o sistema de mensagens é uma chamada de procedimento com limite tardio e, se as chamadas de procedimento são limitadas com atraso, não é possível saber em tempo de design o que você chamará, portanto, não é possível fazer suposições sobre a representação concreta do estado. Então, realmente se trata de mensagens, a ligação tardia é uma implementação de mensagens e o encapsulamento é uma conseqüência disso.
Mais tarde, ele esclareceu que " a grande idéia é ' enviar mensagens' " e lamenta tê-la chamado de "orientado a objetos" em vez de "orientado a mensagens", porque o termo "orientado a objetos" coloca o foco na coisa sem importância (objetos ) e distrai o que é realmente importante (mensagens):
Apenas um lembrete gentil de que eu me esforcei no último OOPSLA para tentar lembrar a todos que o Smalltalk não é apenas NÃO sua sintaxe ou a biblioteca de classes, nem mesmo sobre aulas. Sinto muito que, há muito tempo, cunhei o termo "objetos" para este tópico porque leva muitas pessoas a se concentrarem na idéia menor.
A grande idéia é "mensagens" - é disso que trata o kernal do Smalltalk / Squeak (e é algo que nunca foi totalmente concluído em nossa fase do Xerox PARC). Os japoneses têm uma pequena palavra - ma - para "o que está no meio" - talvez o equivalente em inglês mais próximo seja "intersticial". A chave para criar sistemas grandes e cultiváveis é muito mais para projetar como seus módulos se comunicam do que quais devem ser suas propriedades e comportamentos internos. Pense na Internet - para viver, ela (a) precisa permitir muitos tipos diferentes de idéias e realizações que estão além de qualquer padrão único e (b) permitir graus variados de interoperabilidade segura entre essas idéias.
(É claro que hoje em dia a maioria das pessoas nem se concentra nos objetos, mas nas classes, o que é ainda mais errado.)
As mensagens são fundamentais para o OO, tanto como metáfora quanto como mecanismo.
Se você envia uma mensagem a alguém, não sabe o que ela faz. A única coisa que você pode observar é a resposta deles. Você não sabe se eles próprios processaram a mensagem (por exemplo, se o objeto possui um método), se encaminharam a mensagem para outra pessoa (delegação / proxy), se eles a entenderam. É disso que se trata o encapsulamento, do OO. Você não pode nem distinguir um proxy do real, desde que ele responda como você espera.
Um termo mais "moderno" para "sistema de mensagens" é "envio dinâmico de método" ou "chamada virtual de método", mas que perde a metáfora e se concentra no mecanismo.
Portanto, existem duas maneiras de analisar a definição de Alan Kay: se você a considerar por conta própria, poderá observar que as mensagens são basicamente uma chamada de procedimento de ligação tardia e a ligação tardia implica encapsulamento, para que possamos concluir que # 1 e # 2 são realmente redundantes, e OO é tudo sobre ligação tardia.
No entanto, mais tarde ele esclareceu que o importante é o envio de mensagens e, portanto, podemos vê-lo de um ângulo diferente: o envio de mensagens é tardio. Agora, se as mensagens fossem a única coisa possível, o número 3 seria trivialmente verdadeiro: se houver apenas uma coisa, e essa coisa for atrasada, todas as coisas serão atrasadas. E mais uma vez, o encapsulamento segue as mensagens.
Pontos semelhantes também são apresentados em On Understanding Data Abstraction, revisitado por William R. Cook e também em sua Proposta de definições modernas e simplificadas de "Objeto" e "Objeto Orientado" :
O envio dinâmico de operações é a característica essencial dos objetos. Isso significa que a operação a ser invocada é uma propriedade dinâmica do próprio objeto. As operações não podem ser identificadas estaticamente e, em geral, não há como saber exatamente qual operação será executada em resposta a uma determinada solicitação, exceto executando-a. É exatamente igual às funções de primeira classe, sempre despachadas dinamicamente.
No Smalltalk-72, não havia nenhum objeto! Havia apenas fluxos de mensagens que foram analisados, reescritos e redirecionados. Primeiro vieram os métodos (maneiras padrão de analisar e redirecionar os fluxos de mensagens), depois vieram os objetos (agrupamentos de métodos que compartilham algum estado privado). A herança veio muito mais tarde, e as classes foram introduzidas apenas como uma maneira de apoiar a herança. Se o grupo de pesquisa de Kay já soubesse sobre protótipos, eles provavelmente nunca teriam introduzido aulas em primeiro lugar.
Benjamin Pierce, em Tipos e linguagens de programação, argumenta que o recurso definidor da orientação a objetos é a recursão aberta .
Então: de acordo com Alan Kay, OO é tudo sobre mensagens. De acordo com William Cook, OO tem tudo a ver com o envio de método dinâmico (que é realmente a mesma coisa). De acordo com Benjamin Pierce, OO é tudo sobre Open Recursion, o que basicamente significa que as referências automáticas são resolvidas dinamicamente (ou pelo menos é uma maneira de pensar), ou, em outras palavras, mensagens.
Como você pode ver, a pessoa que cunhou o termo "OO" tem uma visão bastante metafísica dos objetos, Cook tem uma visão bastante pragmática e Pierce uma visão matemática muito rigorosa. Mas o importante é: o filósofo, o pragmatista e o teórico concordam! As mensagens são o único pilar da OO. Período.
Observe que não há menção de herança aqui! A herança não é essencial para o OO. Em geral, a maioria das linguagens OO tem algum modo de reutilização da implementação, mas isso não necessariamente tem que ser herança. Também poderia ser uma forma de delegação, por exemplo. De fato, o Tratado de Orlando discute a delegação como uma alternativa à herança e como diferentes formas de delegação e herança levam a diferentes pontos de design no espaço de design das linguagens orientadas a objetos. (Observe que, mesmo em linguagens que suportam herança, como Java, as pessoas são ensinadas a evitá-la, indicando novamente que não é necessário para o OO).