Minha mãe fez sua tese de faculdade em Fortran e agora (mais de uma década depois) precisa aprender c ++ para simulações de fluidos. Ela é capaz de entender toda a programação processual, mas, por mais que eu tente explicar os objetos, ela não fica. (Eu trabalho muito com Java, então sei como os objetos funcionam). Acho que posso estar explicando isso de maneira muito alta, por isso não faz sentido para alguém que nunca trabalhou com eles e cresceu na era da programação puramente processual.
Existe alguma maneira simples de explicar a ela que a ajude a entender?
object-oriented
fortran
Eric Pauley
fonte
fonte
Respostas:
Resposta curta: não.
Resposta longa: não há "caminho simples" porque o POO está longe de ser simples. A programação processual é sobre "variáveis" e "se for o caso". Tudo o resto é açúcar sintático, mas essas quatro coisas são do que se trata a programação procedural. Depois de obtê-los, nada pode impedi-lo.
OOP é uma maneira de organizar variáveis e partes de código. Quantos padrões existem para definir OOP? 25? 30? Mesmo os professores que aprenderam OOP em diferentes idiomas e formações não concordam com sua própria definição, então ... como pode ser simples?
Não sei como você chegou a isso, mas como sua mãe tem uma experiência semelhante à minha, posso lhe contar como cheguei a isso.
Eu estava programando em C em um projeto muito grande. Era 1988. Muitos programadores organizavam módulos e bibliotecas, com a dificuldade de evitar interferências em outros trabalhos e manter uma boa segregação de tarefas.
Chegamos a uma "solução" que consistia em colocar todos os dados globais inter-relacionados em estruturas, colocando nessas estruturas alguns indicadores de função nos quais eram necessários retornos de chamada. Generalizamos dessa maneira o que chamamos
io_mask
(tipo de caixas de diálogo em modo de texto) egraphic_manager
etc. etc.Em 1996, foi muito fácil descobrir que essas estruturas eram nomeadas "classes" e esses ponteiros de função substituídos por função membro e funções virtuais, ou com links para outros objetos (chamados comportamentos) por outros programadores que renovaram o projeto antigo.
Comecei a entender o POO quando comecei a sentir a necessidade: comportamentos segregados, polimorfismos e em tempo de execução.
Hoje eu trabalho com a POO, mas não penso nisso como uma doutrina para servir: apenas um "idioma comum" (conjunto de ...) que vamos falar juntos sem a necessidade de fornecer explicações e descrições longas o tempo todo . De fato, mais uma "convenção" do que qualquer outra coisa. Afinal, tudo OOP faz -again- "if then goto": apenas faz "multicamadas". Daí abstração e expressões idiomáticas sobre expressões idiomáticas.
Ignore-os. Até que ela não sinta a necessidade deles, nem tente explicar: ela os sentirá como uma maneira complicada de fazer coisas simples. E ela está certa ... até o que ela faz é, de fato, simples.
Ninguém pensará em "organizar uma mesa" se houver apenas quatro coisas em cima. Faz sentido quando as coisas no topo começam a interferir umas nas outras. Essa é a hora da OOP entrar.
Você não precisa de OOP para trabalhar com C ++. A biblioteca padrão C ++ inteira não foi projetada em termos de OOP (embora possa cooperar com ela), e C ++ não é Java.
Em toda a minha experiência, os piores professores de C ++ e programadores de C ++ são os que vêm de Java, ensinando todo seu preconceito sobre tudo não é OOP, desnaturando uma linguagem como C ++ que não é (apenas) para OOP.
Deixe-me sugerir um bom livro para quem deseja abordar C ++: C ++ acelerado : ele o levará a idiomas C ++ sem pretender seguir uma doutrina predefinida.
fonte
Um velho amigo afirmou que eu tinha a definição mais curta que ele conhecia da programação OO, e descobri que ela funciona para algumas pessoas (e não para outras):
A programação orientada a objetos são dados com uma opinião. Você não move a cadeira, pede que ela se mova. Você não classifica a lista, solicita que ela se classifique (talvez com uma dica). Etc.
A idéia é fazer a pessoa pensar de maneira diferente sobre como as coisas são feitas dentro de seu programa.
fonte
Diga a ela para pensar em objetos como objetos no mundo real. Por exemplo, o mundo inteiro pode ser uma mistura de programação orientada a objetos (em C ++) com algum tipo de programação funcional (provavelmente feita na linguagem de Deus, Lisp).
Pegue um objeto, por exemplo, o cortador de grama, ele tem certos atributos e pode fazer uma certa coisa. (objeto e classe)
Em seguida, conte-lhe sobre um cortador de grama melhor, que é uma extensão do cortador de grama que você já possui. Diga a ela que é melhor, mas ainda se baseia no mesmo mecanismo (herança).
Então conte a ela sobre você. Diga a ela que às vezes você pode se tornar um especialista em cortar grama, mas na verdade você é um programador e faz isso para ganhar a vida. É como você agindo como duas entidades diferentes ao mesmo tempo. Isso é polimorfismo.
Quando conseguir isso, conte-lhe como implementar essas coisas na linguagem que ela precisa aprender (C ++).
Então diga a ela, se ela precisar escrever uma simulação deste mundo no mundo dos computadores, ela precisará aprender como fazê-lo.
Quando ela sabe como converter seus pensamentos do mundo real em código de programa. ela teria aprendido a programar em linguagem de programação orientada a objetos.
fonte
Eu fui de assembler e COBOL para Ruby.
O que me ajudou inicialmente foi realmente ignorar o conceito de classes criando instâncias.
Basta começar com o código. Tenha uma classe, mas apenas métodos de nível de classe. Dentro dos métodos, muitas coisas são sobre parâmetros, variáveis, condicionais, matrizes, strings, booleanos etc. Essas coisas devem ser familiares.
Portanto, neste ponto, a classe pode ser vista apenas servindo ao propósito como um local para colocar todos os seus métodos relacionados. Chame de contêiner ou biblioteca; será mais familiar para ela.
Obviamente, o código precisa ser segmentado para ser gerenciável, para que você tenha um desses em cada área. Por exemplo, para gerenciar um conjunto de programas utilitários em um PC, você pode ter uma classe de calculadora na qual pode colocar todo o código de uma calculadora em um só lugar. Se você tiver apenas 1 calculadora no seu PC, os métodos em nível de classe serão suficientes.
Isso é um começo.
ok, considere agora o fato de que você deseja abrir várias calculadoras e alterar a aparência de cada uma e a localização da tela. Então agora você não pode simplesmente ter um método de calculadora como 'screen_location' porque você tem vários deles e cada instância tem sua própria localização ... cada instância ... ok, então precisamos de instâncias.
Nota: meus termos são de ruby e não de c ++, portanto, você pode precisar traduzir.
fonte
Eu explicaria isso em duas etapas, ou talvez quatro, dependendo de quanto você gostaria de dividir seus conceitos.
Etapa 1: apresente-a às estruturas. É um passo relativamente pequeno dos tipos de dados Fortran para as estruturas. Etapa 1a: verifique se ela entendeu a alocação dinâmica de memória e os ponteiros.
Etapa 2: adicione procedimentos associados apenas a essas estruturas. Etapa 2a: adicione herança com base na construção de estruturas maiores que "envolvem" estruturas menores.
Para um programador de Fortran, o fator "uau" será que é muito para o compilador acompanhar. Sim. É para isso que servem os compiladores ...
fonte
Se ela fez sua tese há uma década, provavelmente utilizou Fortan 90 ou 95; nesse caso, o assunto é falar sobre isso em relação aos tipos de dados derivados. Se foi há muito tempo que ela usou o Fortran 77, apresente-a aos tipos de dados derivados no Fortran 90 e depois fale sobre isso ...
Eu não entraria em polimorfismo e herança até que ela entendesse o encapsulamento, pois eles podem ser vistos como casos especiais e extensões do encapsulamento. Eu provavelmente a iniciaria em uma linguagem que permite funções livres ou classes estáticas.
fonte
Depois que ela entender as estruturas, acho que o próximo ponto-chave será reconhecer que a programação orientada a objetos serve como um meio de restringir o conjunto de métodos aos quais uma coisa pode ser passada, ao conjunto de métodos que realmente podem ser aplicados a isso. coisa.
Na programação não orientada a objetos, se alguém estiver usando tipos de dados separados para uma Árvore e uma LinkedList, será necessário usar métodos diferentes para adicionar um nó a cada um. Línguas não-orientados a objetos, em geral, o grito se tentou nomear ambos os métodos
AddItem
, uma vez que qualquer nome dado só pode referir-se a um método, levando um para criar nomes de métodos comoAddTreeItem
,AddLinkedListItem
,RemoveTreeItem
, etc. Com efeito, tal abordagem funciona, mas é um pouco feio. Conceitualmente, os métodosAddTreeItem
eRemoveTreeItem
parecem pertencer um ao outro, mas os nomes não são assim. Pode-se reescrever os nomes comoTreeAddItem
,TreeRemoveItem
,LinkedListAddItem
, etc., mas isso colocaria muito "ruído redundante" no início de cada chamada de método. A grande maioria das chamadas de método em um programa típico terá três informações essenciais: (1) qual seção do código fonte contém o método; (2) qual dos métodos na seção está sendo usado; (3) em que parte dos dados está sendo usada? Em muitos casos, o tipo de dados em que serão acionados será suficiente para identificar a qual seção de código o método pertence, portanto, a parte (1) acima é redundante. É mais fácil identificar visualmente o material no início de uma declaração do que o material em outros lugares; portanto, um estilo de codificação / nomeaçãoTreeAddItem(myTree, whatever)
acaba colocando a informação menos útil em primeiro lugar.Por outro lado, usando programação orientada a objetos, seria possível nomear métodos como
Tree.AddItem
etc., e uma instrução comomyTree.AddItem(whatever)
faria com que um compilador dissesse, essencialmente, "Hmm ...myTree
é do tipoTree
, portanto esse código deve ser chamadoTree.AddItem()
. Não é necessário especifique oTree.
quando chamando,AddItem
pois o compilador conhece o tipomyTree
.. Conceitualmente, uma instrução likemyTree.AddItem(whatever)
é equivalente aTree.AddItem(myTree, whatever)
, e algumas linguagens orientadas a objetos podem permitir ambas as formas como equivalentes; na verdade, a maioria das linguagens omite o primeiro parâmetro da especificação da função e, em vez disso, possui métodos que são definidos em uma classe comoTree
assumir implicitamente um parâmetro do tipoTree
, e atribuir-lhe um nome comothis
,self
ouMe
.As linguagens de programação orientadas a objetos geralmente incluem uma variedade de recursos adicionais, como herança, funções virtuais etc. que são muito úteis em muitos aplicativos, mas mesmo sem esses recursos, a capacidade de agrupar funções de acordo com as coisas em que operam é muito útil.
fonte
A programação orientada a objetos - no sentido orientado a classe relevante aqui - é sobre o acoplamento de uma representação de dados ao código que a manipula. Faz sentido se as seguintes coisas fizerem sentido:
Acoplamento: definindo uma operação ao lado da representação de dados na qual trabalha
Associação tardia: escolhendo uma combinação de representação e comportamento de dados em tempo de execução
Encapsulamento: garantir que os dados sejam válidos por construção e não serão invalidados posteriormente
Isso é tudo. Como qualquer tecnologia, no fundo é simplesmente uma conveniência, da qual muitos desenvolvimentos se seguiram mais tarde. Depois de entender o básico, o resto segue a tempo.
fonte
Eu sugeriria baixar o BlueJ, brincar com ele por 20 minutos e depois fazê-la brincar por 20 minutos.
A maneira como visualiza classes, interfaces e herança é tão óbvia e intuitiva que realmente lhe dá uma compreensão instantânea ao implementar algo - qualquer coisa.
Até mostra diretamente a diferença entre uma classe e um objeto
Ele não fornecerá insights profundos sobre os padrões de design do OO, mas fornecerá uma visão fantástica dos conceitos.
fonte
Gostaria de acrescentar minha contribuição como um lembrete da distinção entre paradigmas de programação e linguagens de programação que implementam esses paradigmas.
Portanto, na minha opinião, a melhor maneira de explicar a orientação a objetos com C ++ para um usuário do F77 seria proceder de maneira gradual:
Primeiro, introduza o usuário no conceito de orientação a objetos em um ambiente familiar, mostrando-lhe como desenvolver estruturas semelhantes a objetos no Fortran 77 - por exemplo, dê uma olhada em artigos como B. Patton "Fortran 77 orientado a objetos (um profissional view) "SIGPLAN Fortran Forum 12, 2 (1993), pp. 23-24, e suas referências.
Em seguida, estabeleça uma correspondência entre essas estruturas e classes e métodos C ++.
Por fim, discuta os recursos adicionais que o C ++ pode fornecer para facilitar a programação do OO.
fonte
Quando eu estava migrando para uma linguagem orientada a objetos do meu treinamento inicial em Pascal, o '.' A questão foi o maior obstáculo para mim também. Levei anos para superar isso.
Na verdade, é realmente pouco intuitivo que uma variável pertença a outra variável, especialmente quando você está acostumado a pensar nelas como ponteiros. A pedra de tropeço para mim foi:
O momento aha para mim foi quando percebi que o ponteiro de nível superior era basicamente apenas um espaço para nome.
Eu sugiro que ela escreva um monte de código que exige que ela coloque um namespace em suas funções, idealmente sem usar a notação de ponto para começar. Faça com que ela tente reescrevê-lo usando a notação de pontos.
Ao fazer esse exercício, a deve superar a inicial "Que bruxaria é essa?" Obstáculo.
fonte
Um insight importante que me ajudou a explicar antes é o fato de que você pode ter várias instâncias de uma classe. Tente explicar isso em termos de "desenhos" ou "moldes" e "cópias" e veja se isso leva a algum lugar.
fonte