# Programación orientada a obxectos

A **programación orientada a obxectos** (POO ou OOP segundo as súas siglas en inglés) é un paradigma de programación que usa obxectos e as súas interaccións para deseñar aplicacións e programas de ordenador. Baséase en varias técnicas, incluíndo herdanza, modularidade, polimorfismo, e encapsulamento. O seu uso popularizouse a principios da década de 1990. Actualmente varias linguaxes de programación soportan a orientación a obxectos.

## Introdución

Os obxectos son entidades que combinan *estado*, *comportamento* e identidade. O estado está composto de datos, e o comportamento por procedementos ou *métodos*. A identidade é unha propiedade dun obxecto que o diferenza do resto. A programación orientada a obxectos expresa un programa como un conxunto destes obxectos, que colaboran entre eles para realizar tarefas. Isto permite facer os programas e módulos máis fáciles de escribir, manter e reutilizar.

Desta maneira, un obxecto contén toda a información que permite definilo e identificalo fronte a outros obxectos pertencentes a outras clases ou fronte a obxectos dunha mesma clase, ao poder ter valores ben diferenciados nos seus atributos. Á súa vez, os obxectos dispoñen de mecanismos de interacción chamados métodos que favorecen a comunicación entre eles. Esta comunicación favorece á súa vez o cambio de estado nos propios obxectos. Esta característica leva a tratalos como unidades indivisibles, nas que non se separan nin deben separarse estado e comportamento.

Os métodos e atributos están estreitamente relacionados pola propiedade de conxunto. Esta propiedade destaca que unha clase require de métodos para poder tratar os atributos cos que conta. O programador debe pensar indistintamente en ambos os dous conceptos, sen separar nin darlle maior importancia a ningún deles. Facelo podería resultar en seguir o hábito erróneo de crear clases colectoras de información por unha banda e clases con métodos que a manexen polo outro. Deste xeito estaríase chegando a unha programación estruturada camuflada nunha linguaxe de programación orientado a obxectos.

Isto difire da programación estruturada tradicional, na que os datos e os procedementos están separados e sen relación, xa que o único que se busca é o procesamento duns datos de entrada para obter outros de saída. A programación estruturada anima ao programador a pensar sobre todo en termos de procedementos ou funcións, e en segundo lugar nas estruturas de datos que eses procedementos manexan. Na programación estruturada só se escriben funcións que procesan datos. Os programadores que empregan este novo paradigma, en cambio, primeiro definen obxectos para logo enviarlles mensaxes solicitándolles que realicen os seus métodos por si mesmos.

## Orixe

Os conceptos da programación orientada a obxectos teñen a súa orixe en Simula 67, unha linguaxe deseñada para facer simulacións, creado por Ole-Johan Dahl e Kristen Nygaard do Centro de Cómputo Noruegués en Oslo. Segundo se informa, a historia é que traballaban en simulacións de naves, e foron confundidos pola explosión combinatoria de como as diversas calidades de diversas naves podían afectar unhas ás outras. A idea ocorreu para agrupar os diversos tipos de naves en diversas clases de obxectos, sendo responsable cada clase de obxectos de definir os seus *propios* datos e comportamento. Foron refinados máis tarde en Smalltalk, que foi desenvolvido en Simula en Xerox PARC (e cuxa primeira versión foi escrita sobre Basic) pero deseñado para ser un sistema completamente dinámico no cal os obxectos poderíanse crear e modificar "en marcha" no canto de ter un sistema baseado en programas estáticos.

A programación orientada a obxectos revelouse como o estilo de programación dominante a mediados dos anos oitenta, en gran parte debido á influencia de C++ , unha extensión da linguaxe de programación C. O seu dominio consolidouse grazas ao auxe das Interfaces gráficas de usuario, para as cales a programación orientada a obxectos está particularmente ben adaptada. Neste caso, fálase tamén de programación dirixida por eventos.

As características de orientación a obxectos foron agregadas a moitas linguaxes existentes durante ese tempo, incluíndo Ada, BASIC, Lisp, Pascal, entre outros. A adición desas características ás linguaxes que non foron deseñados inicialmente para elas causou moitas veces problemas de compatibilidade e mantemento do código. As linguaxes orientadas a obxectos "puros", por outra banda, carecían das características das cales moitos programadores viñeran a depender. Para saltar este obstáculo, fixéronse moitas tentativas para crear novas linguaxes baseadas en métodos orientados a obxectos, pero permitindo algunhas características imperativas de xeitos "seguros". A Eiffel de Bertrand Meyer foi unha temperán e moderadamente acertada linguaxe con eses obxectivos pero agora foi esencialmente substituído por Java, en gran parte debido á aparición de Internet, e á implementación da máquina virtual de Java na maioría de navegadores. PHP na súa versión 5 foise modificando e soporta unha orientación completa a obxectos, cumprindo todas as características propias da orientación a obxectos.

## Conceptos fundamentais

A programación orientada a obxectos é unha nova forma de programar que trata de atopar unha solución a estes problemas. Introduce novos conceptos, que superan e amplían conceptos antigos xa coñecidos. Entre eles destacan os seguintes:

* **Obxecto**: entidade provista dun conxunto de propiedades ou atributos (datos) e de comportamento ou funcionalidade (métodos). Corresponden aos obxectos reais do mundo que nos rodea, ou a obxectos internos do sistema (do programa). É unha instancia a unha clase.
* **Clase**: definicións das propiedades e comportamento dun tipo de obxecto concreto. A instanciación é a lectura destas definicións e a creación dun obxecto a partir delas.
* **Método**: algoritmo asociado a un obxecto (ou a unha clase de obxectos), cuxa execución desencadease tras a recepción dunha "mensaxe". Desde o punto de vista do comportamento, é o que o obxecto pode facer. Un método pode producir un cambio nas propiedades do obxecto, ou a xeración dun "evento" cunha nova mensaxe para outro obxecto do sistema.
* **Evento**: un suceso no sistema (tal como unha interacción do usuario coa máquina, ou unha mensaxe enviada por un obxecto). O sistema manexa o evento enviando a mensaxe adecuada ao obxecto pertinente. Tamén se pode definir como evento, á reacción que pode desencadear un obxecto, é dicir a acción que xera.
* **Mensaxe**: unha comunicación dirixida a un obxecto, que lle ordena que execute un dos seus métodos con certos parámetros asociados ao evento que o xerou.
* **Propiedade ou atributo**: colector dun tipo de datos asociados a un obxecto (ou a unha clase de obxectos), que fai os datos visibles desde fóra do obxecto e isto defínese como as súas características predeterminadas, e cuxo valor pode ser alterado pola execución dalgún método.
* **Estado interno**: é unha propiedade invisible dos obxectos, que pode ser unicamente accedida e alterada por un método do obxecto, e que se utiliza para indicar distintas situacións posibles para o obxecto (ou clase de obxectos).
* **Compoñentes dun obxecto**:atributos, identidade, relacións e métodos.
* **Representación dun obxecto**: un obxecto represéntase por medio dunha táboa ou entidade que estea composta polos seus atributos e funcións correspondentes.

En comparación cunha linguaxe imperativa, unha "variable", non é máis que un colector interno do atributo do obxecto ou dun estado interno, así como a "función" é un procedemento interno do método do obxecto.

## Características da POO

Hai un certo desacordo sobre exactamente que características dun método de programación ou linguaxe defínenlle como "orientado a obxectos", pero hai un consenso xeral en que as características seguintes son as máis importantes (para máis información, seguir enlácelos respectivos):

* **Abstracción**: Cada obxecto no sistema serve como modelo dun "axente" abstracto que pode realizar traballo, informar e cambiar o seu estado, e "comunicarse" con outros obxectos no sistema sen revelar *como* se implementan estas características. Os procesos, as funcións ou os métodos poden tamén ser abstraídos e cando o están, unha variedade de técnicas son requiridas para ampliar unha abstracción.
* **Encapsulamento**: Significa reunir a todos os elementos que poden considerarse pertencentes a unha mesma entidade, ao mesmo nivel de abstracción. Isto permite aumentar a cohesión dos compoñentes do sistema. Algúns autores confunden este concepto co principio de ocultación, principalmente porque se adoitan empregar conxuntamente.
* **Principio de ocultación**: Cada obxecto está illado do exterior, é un módulo natural, e cada tipo de obxecto expón unha *interface* a outros obxectos que especifica como poden interactuar cos obxectos da clase. O illamento protexe ás propiedades dun obxecto contra a súa modificación por quen non teña dereito a acceder a elas, soamente os propios métodos internos do obxecto poden acceder ao seu estado. Isto asegura que outros obxectos non poden cambiar o estado interno dun obxecto de xeitos inesperados, eliminando efectos secundarios e interaccións inesperadas. Algunhas linguaxes relaxan isto, permitindo un acceso directo aos datos internos do obxecto dun xeito controlado e limitando o grao de abstracción. A aplicación enteira redúcese a un agregado ou crebacabezas de obxectos.
* **Polimorfismo**: comportamentos diferentes, asociados a obxectos distintos, poden compartir o mesmo nome, ao chamalos por ese nome utilizarase o comportamento correspondente ao obxecto que se estea usando. Ou dito doutro xeito, as referencias e as coleccións de obxectos poden conter obxectos de diferentes tipos, e a invocación dun comportamento nunha referencia producirá o comportamento correcto para o tipo real do obxecto referenciado. Cando isto ocorre en tempo "de execución", esta última característica chámase *asignación tardía* ou *asignación dinámica*. Algunhas linguaxes proporcionan medios máis estáticos (en tempo "de compilación") de polimorfismo, tales como os persoais e a sobrecarga de operadores de C++.
* **Herdanza**: as clases non están illadas, senón que se relacionan entre si, formando unha xerarquía de clasificación. Os obxectos herdan as propiedades e o comportamento de todas as clases ás que pertencen. A herdanza organiza e facilita o polimorfismo e o encapsulamento permitindo aos obxectos ser definidos e creados como tipos especializados de obxectos preexistentes. Estes poden compartir (e estender) o seu comportamento sen ter que reimplementar o seu comportamento. Isto adoita facerse habitualmente agrupando os obxectos en *clases* e estas en *árbores* ou *enrejados* que reflicten un comportamento común. Cando un obxecto herda de máis dunha clase dise que hai *herdanza múltiple*; esta característica non está soportada por algunhas linguaxes (como Java).

## Linguaxes orientadas a obxectos

Entre as linguaxes orientadas a obxectos destacan os seguintes:

* ActionScript 3
* Ada
* C++
* C#
* Clarion
* Common Lisp
* D
* Dart
* Delphi
* Harbour
* Eiffel
* Java
* Lexico (en castelán)
* Object Pascal
* Objective-C
* Ocaml
* Oz
* R
* Perl (soporta herdanza múltiple)
* PHP (na súa versión 5)
* PowerBuilder
* Python
* Ruby
* Scala
* Smalltalk
* Swift
* Magik (SmallWorld)
* VB.NET
* Visual FoxPro
* XBase++

Moitas destas linguaxes de programación non son puramente orientadas a obxectos, senón que son híbridos que combinan a POO con outros paradigmas.

Do mesmo xeito que C++ outras linguaxes, como OOCOBOL, OOLISP, OOPROLOG e Object REXX, foron creados engadindo extensións orientadas a obxectos a unha linguaxe de programación clásico.

Un novo paso na abstracción de paradigmas de programación é a Programación Orientada a Aspectos (POA). Aínda que é aínda unha metodoloxía en estado de maduración, cada vez atrae a máis investigadores e ata proxectos comerciais en todo o mundo.

Tamén é necesario recalcar que na programación orientada a obxectos é factible de utilizar en JavaScript.

## Véxase tamén

### Outros artigos

* Problema do diamante