Baixe o app para aproveitar ainda mais
Prévia do material em texto
PARADIGMAS DE LINGUAGENS DE PROGRAMAÇÃO Aula 10: Paradigmas: estruturado, orientado a objetos, funcional e lógico Apresentação Durante as aulas desta disciplina, mostramos a você os principais critérios de avaliação de linguagens de programação (LPs) imperativas tendo como base as implementações de cada LP. As imperativas, por sua vez, são a base para a implementação dos métodos das linguagens orientadas a objetos (OO), trazendo uma mudança radical na forma de se pensar a estrutura dos programas. Mas, ainda assim, para codi�car a lógica dos métodos das classes a serem criadas para a solução de um problema, usamos os mesmos comandos das LPs imperativos. Nesta aula, portanto, estudaremos os conceitos, as propriedades, as técnicas e a própria implementação das LPs dos paradigmas orientados a objeto, funcional e lógico. Objetivos Anunciar propriedades, técnicas e implementações das LPs orientadas a objeto; Apontar estes itens nas linguagens funcionais; Ordenar propriedades, técnicas e implementações das LPs lógicas; Paradigma orientado a objeto Os paradigmas orientado a objetos, estruturado e concorrente estão contidos numa classi�cação maior, a das LPs imperativas; estas, por sua vez, pertencem a uma classe ainda maior de paradigma imperativo, que é caracterizada pelos conceitos de variáveis, atribuição e valor. Isso se deve à troca de estados pelas mudanças nos conteúdos das variáveis (estado da memória do computador), ou seja, às propriedades e ao funcionamento da máquina de Von Neumman. Fonte: (VAREJÃO, 2004, p. 17) Pensar num programa sob o ponto de vista da orientação a objeto é uma mudança signi�cativa na forma de olhar a própria estrutura de um programa. Enquanto na programação com LP estruturada a preocupação é dividir o programa em partes (procedimentos ou funções) mais facilmente administráveis, na orientação a objeto a modularização é feita com base nas classes necessárias para a resolução do problema. Na programação estruturada, um conjunto de subprogramas (procedimentos e funções) acessa os dados que precisam na memória de forma totalmente segmentada. O programa tinha de conhecer os dados, sua estrutura e identi�cadores (vide a �gura a seguir). Já nas linguagens OO, procedimentos e dados são encapsulados em objetos, onde os dados são protegidos pelos métodos pertencentes ao objeto como apontam as duas �guras adiante. 1 Figura 1: Programação estruturada x OO Observe que os atributos (dados) são acessados apenas pelos métodos implementados pelo próprio objeto (classe): Figura 2: Métodos protegendo o acesso aos atributos. http://estacio.webaula.com.br/cursos/go0138/aula10.html Nas linguagens estruturadas, os procedimentos contêm as funcionalidades que realizam operações com os dados compartilhados. O código-fonte acessa o dado diretamente, referenciando os nomes das variáveis. Já nas orientadas a objeto, uma funcionalidade é implementada pela troca de mensagens entre objetos. Cada objeto implementa uma parte da funcionalidade, enquanto os demais mandam mensagem àquele a executar a tarefa necessária: A tabela a seguir mostra a correlação entre os paradigmas estruturado e orientado a objeto: Tabela 1: programação OO x estruturada. Programação estruturada Programação OO Procedimentos e funções Métodos das classes Variáveis Instâncias = objetos Chamadas a procedimentos e funções Mensagens entre os objetos Classes Tipo abstrato de dados definido pelo programador Herança Polimorfismo Toda classe tem três compartimentos: Seu nome (Conta); Seus atributos (Numero, Nome, Saldo, Limite); Seus métodos (3o compartimento contendo as assinaturas dos métodos das classes: CriarConta (): void; e MostrarSaldoLimite (saldolimite:double): doble). Além destes compartimentos, os atributos e os métodos possuem visibilidade. Uma classe é um molde que especi�ca propriedades (atributos) e comportamento (métodos) para um conjunto de objetos similares (mesmas propriedades e mesmo comportamento). Figura 4: Classe x objeto. Exemplo Na imagem a seguir, é possível notar os símbolos # antes de cada atributo e os + antes de cada método da classe. Figura 5: Representação da classe Conta em UML. Vejamos a especi�cação da classe acima na linguagem C++: Class Conta { // atributos da classe protected int numero; char *nome[30]; double saldo; double limite; // métodos da classe public: CriarConta():void; { // implementação do método } MostrarSaldoLimite(SaldoLimite: double): double; { // implementação do método } } } Pela �gura 5, a imagem da classe Conta em UML mostra que os atributos têm visibilidade protegida (símbolo # antes de cada atributo); os métodos, visibilidade pública (símbolo + antes de cada método). A maioria das LPs orientadas a objeto implementa estes três tipos de visibilidade: Pública (todas as classes têm acesso); Privada (apenas a própria classe o tem); Protegida (as classes pertencentes ao mecanismo de herança possuem acesso). Algumas LPs implementam a visibilidade pacote, em que estão os atributos e métodos são acessíveis aos atributos e métodos das classes que pertencem ao pacote. Exemplo São exemplos desses, como CLOS, Eiffel e Java. A �gura a seguir mostra como a visibilidade pública e a privada afetam o atributo e os métodos. A�nal, ao atribuirmos a visibilidade pública a eles, estamos ferindo o seguinte princípio do encapsulamento: os atributos de uma classe devem ser acessados única e exclusivamente por métodos dela própria. Quando associada a métodos, a visibilidade pública demonstra que eles prestam o serviço da respectiva classe às demais. Já os métodos privados servem para estruturar o serviço que a classe presta às outras, reforçando, assim, a necessidade de se obedecer ao conceito de encapsulamento. public private Atributos Viola encapsulamento Reforça encapsulamento Métodos Proporciona Serviços aos clientes Suporta outros metodos na classe Figura 6: Visibilidade de atributos e métodos. Em um programa OO, cada objeto tem sua função em um contexto, oferecendo serviços aos demais objetos. Para um objeto (origem) usar o serviço oferecido por outro (destino), ele envia uma mensagem contendo a identi�cação dos objetos de origem e destino, além do método do objeto destino a ser ativado e seus parâmetros (se for o caso). Este conceito assemelha-se à chamada de procedimentos e funções (subprogramas). Os dados (atributos) de um objeto somente podem ser acessados por meio dos próprios métodos, garantindo o princípio do encapsulamento (proteção) a atributos e métodos dele: Encapsular; Proteção aos atributos e a algumas operações; Interface: Serviços que são oferecidos aos demais objetos. Conjunto de operações que a classe implementa por intermédio dos métodos públicos (em que todas as classes podem enviar mensagem); Garante a preservação de atributos e operações de cunho privado (encapsulamento). Uma vez criada, uma classe pode ser reutilizada no mesmo programa ou em outro. A partir de uma classe pronta, pode-se herdá-la (princípio da herança ) e, em seguida, adicionar atributos e métodos, bem como rede�nir método(s) com novas implementações (lógica de funcionamento), ainda que com a mesma assinatura (dados de uma mensagem ao objeto destino), caracterizando, assim, o princípio do polimor�smo . 2 3 A imagem a seguir ilustra os princípios da herança e do polimor�smo. Seu diagrama de classes da UML mostra os seguintes aspectos: Na classe PESSOA (ancestral ou classe-pai), antes dos atributos, temos ‘#’ (uma das possíveis visibilidades), indicando que eles poderão ser herdados pelas classes-�lhas (Aluno, Professor, Funcionário e outras que puderem ser adicionadas a qualquer momento) e usados por elas. Os métodos de PESSOA também serão herdados, pois têm visibilidade pública; Representado pelas três setas que chegam à classe PESSOA, o símbolo da UML representa a herança: as classes Aluno, Funcionário e Professor herdam os atributos e métodos da classe PESSOA quetenham visibilidade pública (+) e protegida (#); As classes Aluno, Funcionário e Professor herdam todos os atributos e métodos com ‘#’, além de declararem os próprios métodos e atributos. Figura 7: Visibilidade, herança e polimorfismo. Exibiremos agora a de�nição simpli�cada (com menos atributos e métodos) das classes envolvidas na modelagem UML http://estacio.webaula.com.br/cursos/go0138/aula10.html http://estacio.webaula.com.br/cursos/go0138/aula10.html apresentada nesta imagem na linguagem Java. A superclasse, classe mãe ou ancestral chama-se PESSOA. Ela pode ser declarada conforme o código a seguir: public class Pessoa { protected String nome; protected String cpf; protected string estciv; protected Date data_nascimento; } // constructor public Pessoa(String _nome, String _cpf, Date _data, string_estciv) { this.nome = _nome; this.cpf = _cpf; this.data_nascimento = _data; this.estciv = _estciv; } Vamos de�nir agora as subclasses, classes �lhas ou descendentes, todas herdando do pai PESSOA (de�nido acima). As pessoas importantes no contexto são ALUNO, PROFESSOR E FUNCIONARIO. // sub classe ALUNO public class Aluno extends Pessoa { public Aluno(String _nome, String _cpf, Date _data, string_estCiv) { super(_nome, _cpf, _data, _estciv); } protected String matricula; } // sub classe PROFESSOR public class Professor extends Pessoa { public Professor(String _nome, String _cpf, Date _data, string_estciv) { super(_nome, _cpf, _data, _estciv); } protected double salario; } // sub classe FUNCIONARIO public class Funcionario extends Pessoa { public Funcionario(String _nome, String _cpf, Date _data, string_estciv) { super(_nome, _cpf,_data,_estciv); } protected double salario; protected String cargo; } Avaliando o código acima, percebemos o uso, em cada construtor de subclasse, de uma denominada SUPER, que representa a chamada de um método ou acesso a determinado atributo da superclasse (daí deriva o seu nome). Vejamos a instrução: Com “new Aluno(“nome”,”cpf”,new Date(),”estciv”)”, a classe ALUNO invocará o construtor Pessoa (String,String,Date,String), enquanto os atributos receberão os dados dos respectivos parâmetros; Com “new Professor(“nome”,”cpf”,new Date(),”estciv”)”, a classe PROFESSOR invocará seu constructor – e assim por diante com cada subclasse criada. O trecho de código a seguir pode ser usado para instanciar a classe Aluno e exempli�car o uso das classes: public class main { public static void main(String[] args) { Aluno i = new Aluno("Jose Francisco", "123.456.789- 00", newDate()),”S”; System.out.println("Atributos\n\nNome: " + i.nome); System.out.println("CPF: " + i.cpf); System.out.println("Nasc:"+i.data_nascimento.toString()); System.out.println("Civil:"+i.estcivil); } } A herança que exempli�camos acima é a simples, em que uma classe ou mais classes herdam de apenas uma delas. Existem linguagens OO que implementam a herança múltipla, quando uma classe pode herdar propriedades de uma ou mais classes. Atenção As LPs OO Eiffel, Java e Smalltalk não implementam herança múltipla. Uma vez entendido o uso da herança em classes Java, vamos compreender o uso do polimor�smo. Acompanhe a �gura 7 (acima) para compreender a solução: suponhamos que as pessoas, em geral paguem, R$0,10 por cada cópia. Os alunos, diferentemente de professores e funcionários, pagam R$0,70. A solução encontrada foi criar: Um método PrecoCopias (int qtde) na classe PESSOA (podendo ser herdado pelas subclasses); Na classe ALUNO o mesmo método (polimor�smo do tipo sobrecarga) com implementação diferenciada (usar 0,70 em vez de 0,10). Observe este código: public class Pessoa { protected String nome; protected String cpf; protected string estciv; protected Date data_nascimento; // constructor public Pessoa(String _nome, String _cpf, Date _data, string_estciv) { this.nome = _nome; this.cpf = _cpf; this.data_nascimento = _data; this.estciv = _estciv; } // método para calcular copias public double precocopias (int qtde); { return 0,10 * (double) qtde; } } } Vejamos agora o uso do mesmo método (com os mesmos nome e assinatura) na classe Aluno com a diferença da implementação do cálculo: public class Aluno extends Pessoa { public Aluno(String _nome, String _cpf, Date _data, string_estCiv) { super(_nome, _cpf, _data, _estciv); } protected String matricula; // método para calcular copias public double precocopias (int qtde); { return 0,10 * (double) qtde; } } Exemplo Veja a tabela apresenta alguns critérios de comparação e como cada linguagem se comporta em relação a cada critério apresentado. Paradigma funcional Derivado da programação funcional, o paradigma funcional nasceu na década de 1960 motivado pela necessidade de implementação de aplicações no campo da Inteligência Arti�cal (IA): computação simbólica, prova de teoremos, sistema baseado em regras e processamento de linguagem natural (falada e escrita). Exemplo javascript:void(0); As linguagens funcionais mais populares são LISP e Prolog, mas existem ainda Scheme, ASpecT, Calm, Haskell, Miranda, Nesl etc. Criada em 1958, a linguagem LISP deu vida à programação funcional, criando um novo paradigma de desenvolvimento, uma inovadora forma de pensar em função de LPs diferenciadas. LISP tem sido usado, ao longo dos anos, para cálculos simbólicos, projeto de circutos elétricos, lógica matemática, jogos e outros campos da IA. Esta linguagem tem duas variantes ativas até os dias de hoje: COMMON LISP (1990) e Scheme (1998). Normalmente, as linguagens funcionais são interpretadas; contudo, também podem ser compiladas. A essência da programação funcional é combinar funções para produzir outras mais poderosas. Por isso, o objetivo do projeto de uma LP funcional é imitar as funções matemáticas no maior grau possível. Ela, portanto, faz uso das propriedades matemáticas das funções. Uma linguagem funcional possui: Conjunto de funções primitivas; Conjunto de formas funcionais para construir funções complexas a partir das primitivas; Estruturas (listas) para representar dados. Uma linguagem puramente funcional não faz uso de variáveis e comando de atribuição. O programador não precisa se preocupar com células de memória; a�nal, sem variáveis, não há iteração. Linguagens funcionais simulam repetições pelo uso de funções recursivas (chamando a elas próprias). A título de de exemplo, considere a seguinte função para calcular o fatorial de um número em uma linguagem imperativa C: Int Fatorial (int n) { Int Fat=1; While (n > 0) { fat=fat*n n— } return fat } Podemos usar a mesma função sem utilizar a variável local fat para armazenar os valores, eliminando a repetição WHILE. Para isso, faremos uso desta recursividade: Int Fatorial (int n) { If (n > 0) Factorial (n-1,f*n) Else Return f; } Se quisermos calcular o fatorial de 5, basta chamar Fatorial (5,1). Outra LP bem característica e usada do paradigma funcional é a Haskell. Vamos conhecer um pouco esta poderosa linguagem funcional. Acompanhemos duas formas de escrever a função de cálculo de fatorial nesta LP: 1 A função é recursiva Primeiramente, de�ne-se o caso especial (fatorial de 0) e, depois, o caso geral: Fatorial 0 = 1 Fatorial num = num * fatorial (num-1) 2 Usa-se o if-then-else. Fatorial num = if num ==0 then 1 else num * fatorial (num-1) As expressões em Haskell são escritas, em geral, com a notação inter�xada, na qual tanto o operador quanto a função aparecem entre seus operandos. No exemplo a seguir, que retorna o valor 48, segue-se a precedência de operadores (vide tabela também a seguir): 5*(4+6)-2 = 5*10-2 = 50-2 = 48 Haskell dispõe de um bom conjunto de operadores: Assim como em LISP e Sheme,a estrutura de dados essencial em Haskell é composta pelas listas, que são um conjunto de elementos do mesmo tipo de�nido pela enumeração deles conforme as duas opções a seguir: Pares = [0,2,4,6,8]; Ímpares = [1,3 .. 9]. Na lista dos pares, está enumerado cada elemento; na dos ímpares, usamos o intervalo, omitindo elementos quando a lista for óbvia. Haskell dispõe do operador ++, que concatena listas conforme o exemplo a seguir: [1,2] ++ [3,4] ++ [5] 🡪 retornará [1,2,3,4,5] Pares ++ Ímpares -> retornará [0,2,4,6,8,1,3,5,7,9] [1,2] ++ [] 🡪 retornará [1,2] [1,2] ++ 3:[] 🡪 retornará [1,2,3] 1+2 🡪 retornará erro “wrong type of arguments for ++” Haskell tem operadores para veri�car se dois objetos são iguais (==): 5==5 🡪 retorna TRUE 0==1 🡪 retorna FALSE [1,2]==[1,2] 🡪 retorna TRUE [1,2==[2,1] 🡪 retorna FALSE Esta linguagem também suporta vários tipos de dados elementares: Booleanos (chamados de bool); Inteiros (int e integer); Caracteres (char); Cadeias de caracteres (string); Números em ponto �utuante (Float). Os principais construtores de �uxo de controle em Haskell são o guarded e o if-then-else. Ambos se equivalem. A seguir, con�ra dois trechos de código que apresentam o maior de três números: As funções em Haskell são descritas em dois pedaços: Parte 1: Identi�ca o nome da função, o domínio e o intervalo; Parte 2: Descreve a função em si. A descrição da função é ilustrada pelo trecho de código a seguir: Vejamos outra função para declarar o maior de três inteiros: Agora podemos veri�car outra para calcular o fatorial de um número usando a recursividade: Esta imagem apresenta algumas das funções Haskell para lidar com listas: Outra estrutura de dados usada em Haskell é a tupla, que representa uma coleção de valores de diferentes tipos postos entre parêntesis e separados por vírgula: (“Marcelo”,”99876-9865”) Saibamos como de�nir uma lista telefônica usando o conceito de tupla em Haskell. Esta mostra uma de nome de Pessoa e Telefone: A LP possui funções prede�nidas para acessar os elementos, como fst e snd, que acessam o primeiro e o segundo membro de uma tupla de acordo com o código a seguir: fst (“Marcelo”,”99876-9865”) = “Marcelo” snd (“Marcelo”, ”99876-9865” = ”99876-9865” Pode-se de�nir um tipo ListaTelefonica como uma lista de pares de nomes e números de pessoas: Type ListaTelefonica = [(Pessoa, Telefone)] Com base nesta lista, podem ser implementadas funções úteis como a demonstrada a seguir, que retorna os números de telefone de determinada pessoa: Esta função retorna a lista de todos os números do catálogo telefônico para os quais há uma entrada (pessoa,n) e pessoa==p (a pessoa desejada). Exemplo pb = [(“Bob”, 2771234), (“Aline”, 2772345), (“Bob”, 2770123)] A chamada à função �nd pb “Bob” teria como resposta [2771234, 2770123]. O sistema de tipos de Haskell concede poder à LP. Haskell implementa instruções condicionais e de repetição: Condicional Se o teste for verdadeiro, o sentido de Conditional terá o sentido da Statement thenbranch; caso contrário, ele terá o sentido da Statement elsebranch. Repetição Uma instrução Loop tem um teste booleano, que é uma expressão, e um corpo Statement. Se o teste não for Verdade (True), o sentido (estado de saída) de um Loop será o mesmo que o estado de entrada; caso contrário, será o estado resultante de se executar primeiramente seu corpo uma vez, passando depois o estado resultante para a nova execução do Loop (laço). A instrução Assignment (atribuição) consiste em um destino Variable (variável) e uma origem Expression. O estado de saída é computado a partir do estado de entrada, substituindo o Value (valor) do destino Variable pelo valor calculado da origem Expression, que é avaliada usando o estado de entrada. Todas as outras variáveis têm, no estado de saída, o mesmo valor que elas tinham no de entrada. Paradigma lógico Também chamado de declarativo, ele surgiu nos anos 1970. Sua vinda oferecia uma perspectiva diferente de tudo que se fazia naquela época, cujo predomínio das LPs estruturadas expressava a lógica do programa sob a forma de algoritmos escritos na linguagem. O paradigma lógico declara os objetivos do programa - e não sua solução. Na programação lógica, os objetivos são estabelecidos por intermédio de um conjunto de regras; por isso, às vezes, ela é chamada de programação baseada em regras. Ele tem duas grandes vertentes de aplicação: campo da IA e acesso de informações em bancos de dados. No segmento da IA, a LP Prolog tem sido a preferida. Em outros campos dela, temos a linguagem Mycin, também declarativa, para modelar sistemas especializados. No campo de banco de dados, o predomínio absoluto é da LP SQL (Structured Qyery Language). Os programas escritos em LPs lógicas têm duas peculiaridades: Não determinismo: Podem achar mais de uma solução para o problema; Backtracking: Mecanismo do compilador da linguagem lógica (como, por exemplo, Prolog), o que permite o não determinismo. Um programa escrito em LP do paradigma lógico tem diversas aplicações, destacando-se: 1 Processamento de linguagem natural ( escrita ou falada)4 2 Raciocínio automático 3 Prova de teoremas 4 Pesquisas em bancos de dados 5 Sistemas especialistas Um programa escrito na linguagem do paradigma lógico expressa as especi�cações para a solução de problemas com o uso de expressões em lógica matemática. Como já mencionamos acima, Prolog é a LP principal quando falamos deste tipo de programação. Os programas em Prolog são escritos usando termos, que podem ser: Constantes (nomes constantes); Variáveis (formado por letras); Estruturas (predicado com zero ou mais argumentos). Exemplo Estruturas: N (lista) e palestrantes (quem, Arábia) Vejamos como expressar fatos e regras em Prolog: Um fato é um termo seguido de um ponto (.); uma variável não pode ser um fato. Uma regra é um termo seguido de :- e uma série de termos separados por vírgulas que termina em um ponto (.). Um programa em Prolog é composto de uma série de fatos e regras: Este trecho de código declara os seguintes fatos: Aline e Maria falam russo; Beto e Maria falam inglês. http://estacio.webaula.com.br/cursos/go0138/aula10.html O trecho de código acima também de�ne uma regra: A relação FaleCom entre duas pessoas, que é true exatamente quando ambas falam a mesma língua, está representada pela variável L, e elas são pessoas diferentes; O operador \= especi�ca que Pessoa1 não pode ser a mesma pessoa (igual) que Pessoa2. Uma regra em Prolog pode ter sucesso ou fracasso em sua realização: Sucesso: Quando houver instanciações (atribuições não permanentes) de suas variáveis, todos os termos à direita do operador :- simultaneamente terão sucesso para aquelas atribuições; Fracasso: Quando a regra falhou. Sabemos então que um fato sempre tem sucesso, pois é verdadeiro. Já a regra tem sucesso para estas instanciações: Pessoa1 = Aline; Pessoa2 = Maria. A instanciação acima ocorre pela existência de uma da variável L (= russo), para o qual os três predicados a seguir são verdadeiros e têm sucesso simultâneo: Fale (Aline, L); Fale (Maria, L); Aline \= Maria. Esta mesma regra falha (sem sucesso) nas instanciações a seguir, já que elas não compartilham de uma comum da variável L: Person1 = Aline; Person 2 = Beto. Em Prolog, também podemos escrever consultas em seu prompt de execução: ?- fale(Who, russo) 🡪 que signi�ca quem fala russo? O programa Prolog tenta atender a uma consulta procurando um fato ou uma série de fatos/regras que diga respeito à consulta. Trata-se de uma atribuição de valores para as variáveis na consulta que faz um ou outro ter êxito. Fatos e regras Prolog são usualmente inseridos em um arquivo separado. É usado nele o comando consult para carregá-lo no interpretador, que a�rma cada um dos fatos e das regras de�nidos no programa. Após o carregamento do programa, podem ser feitas as consultas ao interpretador na forma de asserções com variáveis. Ele tentará responder a elas. Eis algumas diretrizes geraispara escrever programas Prolog: Identi�cadores que começam com uma letra maiúscula ou um caractere sublinha são tomados como variáveis, enquanto todos os outros são tratados como constantes; Não deve haver nenhum espaço entre o nome do predicado e o parêntesis esquerdo que abre sua lista de argumentos; Todos os fatos e as regras devem terminar com um ponto; Um arquivo de programa deve terminar com um �m de linha. Pensemos em um arquivo de programa Prolog denominado FALE com o seguinte código: O programa será carregado ao digitarmos no prompt do ambiente Prolog: ?- consult(FALE). Teremos como resposta do compilador: O Yes indica que Prolog carregou o arquivo com sucesso e pode seguir adiante. Considere agora a seguinte consulta em Prolog: ?-fale(Who, russo). A resposta será: Prolog procura fato a fato e vai mostrando o que encontra inserindo Who e, ao �nal, No, indicando que não há mais respostas. Para as perguntas mais complexas com várias combinações, Prolog usa árvores e outras estruturas para representar as soluções. Já as listas são as estruturas básicas de dados em Prolog: Suponhamos as seguintes listas em Prolog: Com elas, as seguintes querys em Prolog geram as respectivas respostas: Prolog dispõe de um conjunto de operadores e funções que permite, com as listas, construir as consultas. Ele possui recursos que nos permitem usá-la para: Manipulação simbólica e prova de teoremas; Processamento de linguagem natural; Semânticas formais de Clite. Atividade 1 Sobre linguagens de programação e paradigma orientado a objetos: I. Objeto e classe são a mesma coisa. II. A visibilidade de um atributo de�nido como público fere o princípio fundamental do encapsulamento. III. O uso do polimor�smo somente acontece quando temos uma herança em curso. IV. A linguagem Haskell é uma das linguagens orientadas a objeto mais usadas. Com base em sua análise, marque a opção que apresenta apenas as assertivas corretas. a) II e III b) II c) III d) I, II e III e) I, II, III e IV 2. Sobre as linguagens de programação e paradigma funcional: I - Nasceram da necessidade de implementação de código para suprir necessidades da programação voltada a soluções de inteligência arti�cial. II - Java é uma das LPs mais usadas do paradigma funcional. III - O paradigma recebe este nome, pois os códigos são uma combinação de funções para produzir outras mais poderosas. IV - Um LP funcional possui funções primitivas, facilidades para construir funções complexas e listas para representar dados. Com base em sua análise, marque a opção que apresenta apenas as assertivas corretas. a) I, III e IV b) II e IV c) III d) I e IV e) I e III 3. No que se refere exclusivamente às linguagens de programação e ao paradigma lógico, avalie as assertivas a seguir: I.O paradigma lógico declara os objetivos do programa, e não sua solução. II.Prolog é a maior representante das LPs lógicas. III.Um problema resolvido pelo paradigma lógico somente pode ter uma solução atendida. IV.Um programa escrito em LP de paradigma lógico usa expressões em lógica matemática. V.Os programas em Prolog podem ter constantes, variáveis, estruturas de decisão e repetição. Está correto apenas o que se a�rma em: a) I, II e V b) II e III c) II e IV d) I, II e IV e) I, II e V Notas ENCAPSULADOS1 Encapsular é separar os programas em partes, como atributos e implementação HERANÇA2 Capacidade de uma classe herdar as propriedades (atributos e métodos) de outra, aumento do reuso de código e minimização de tempo e custo de desenvolvimento. A herança pode ser simples (herda de apenas um ancestral) ou múltipla (mais de um). Ela é transitiva, ou seja, toda classe, em qualquer nível da hierarquia de herança, pode ser herdada. A transmissão das propriedades herdadas se dá até o último nível. POLIMORFISMO3 Uma vez que uma classe tenha sido herdada, métodos herdados podem ser rede�nidos (nova lógica de implementação interna) na classe que a herdou para servir aos interesses dela, aumentando o reuso e se valendo de técnicas para redução de tempo e custo de desenvolvimento, além do incremento do fator segurança (a classe que serviu de base para a herança já funcionava anteriormente). ESCRITA ou FALADA 4 Há projetos para identi�car padrões de comportamento pela fala ou escrita de uma pessoa (área de Psicologia). Referências BUZATO, L. E; RUBIRA, C. M. F. Construção de sistemas orientado a objetos con�áveis. Rio de Janeiro: UFRJ, 1998. SEBESTA, R. W. Conceitos de linguagem de programação. 11. ed. Porto Alegre: Bookman, 2018. TUCKER, A. B. Programação: princípios e paradigmas. 2. ed. Porto Alegre: AMGH, 2010. VAREJÃO, F. M. Linguagem de programação: conceitos e técnicas. Rio de Janeiro: Elsevier, 2004. WATT, D.A. Programming languages: concepts and paradigms. New York: Prentice-Hall, 1990. Explore mais Encapsulamento, polimor�smo e herança em Java; Como funciona a herança de construtor em Java; Paradigmas de linguagens de programação; Linguagens de programação funcionais: o que são e quais as vantagens. javascript:void(0); javascript:void(0); javascript:void(0); javascript:void(0);
Compartilhar