Total de visualizações de página

quarta-feira, 14 de março de 2012

A Diferencia Sintaxe e Semantica entre JAVA e C#?

Nesse post, irei contar um pouco sobre a diferença de sintaxe e semântica das linguagens JAVA e C#.

Mas você sabe o que é sintaxe?
E o processo de analisar uma sequência de entrada (lida de um arquivo de computador ou do teclado, por exemplo) para determinar sua estrutura gramatical segundo uma determinada gramática formal.

E Semântica?
E o processo onde se verifica os erros semânticos, (por exemplo, uma multiplicação entre tipos de dados diferentes) no código fonte e coleta as informações necessárias para a próxima fase da compilação.


Vamos observar as imagens a seguir:
Criação de uma Classe em JAVA.
Figura 1


Criação de uma classe em C#
Figura 2


As duas implementações possuem a mesma funcionalidade, porém em diferente linguagem.

Vamos aprofundar mais nas diferenças entre as duas linguagens.

Namespaces e Packages 

Figura 3

As classes em JAVA é realizada através de pacotes(packages) e em C# é por namespaces.
Em java um pacote representa fisicamente uma pasta, já em C# um namespace não está relacionado a uma pasta.
É possível ter uma pasta com um nome e dentro desta pasta, classes que pertençam a um namespace com outro nome, ou ainda, em uma pasta é possível existirem classes com namespaces diferentes. 

Prós e Contras
Para quem está iniciando em uma das linguagens, sem conhecer a outra, o aprendizado é fácil e natural, mas, para quem vem da linguagem Java para C#, confusões conceituais podem ocorrer, principalmente em relação ao fato de uma classe não necessariamente estar relacionada de forma direta a uma pasta, como ocorre em Java. Note que, caso você esteja fazendo uso de IDEs, a composição do nome de um namespace pode ser afetada caso a classe esteja sendo criada dentro de uma pasta, ou seja, o IDE pode compor o nome do namespace da classe a ser criada com o nome da pasta onde a criação esteja ocorrendo. Mas lembre-se que, ao contrário de Java, isso não é obrigatório em C#.
Assim como em Java que tem sua classe devidamente nomeada com o uso dos nomes dos pacotes a que ela pertence, uma classe em C# tem seu nome devidamente qualificado quando é referenciada com o caminho completo, que inclui o namespace da mesma. Em Java temos, por exemplo,javax.swing.JButton e em C# temos System.Windows.Forms.Button.
Particularmente acredito que o modelo do Java traga mais benefícios, onde existe uma regra sintática ligada diretamente à estrutura de pacotes. Deixar para o desenvolvedor a responsabilidade de atribuir os namespaces aos respectivos folders pode trazer prejuízos na produtividade e erros semânticos em toda a estrutura.
Importação de classes utilizadas na implementação
Figura 4
Importação de classes utilizadas na implementação
Quando se implementa uma classe, seja qual for a responsabilidade dela, fatalmente ela incorrerá na situação de utilizar outras classes. Há uma grande possibilidade de que as classes que sejam utilizadas nesta implementação pertençam a um mesmo contexto, sendo, desta forma, visíveis. Porém, na maioria das vezes, se faz uso de classes que foram desenvolvidas por outros, ou, ainda, que façam parte da API (Application Program Interface) da linguagem eleita para implementar a solução.
Quando isso ocorre, é preciso que a classe em implementação tenha conhecimento da(s) classe(s) que utiliza, pois, para seu problema, não é preciso, por exemplo, saber como um JFrame é criado, gerenciado ou apresentado, é preciso saber apenas os serviços oferecidos por ele e não como eles são implementados (Encapsulamento). Mas, é preciso que a classe responsável por estes “detalhes” seja visível durante a compilação, pois, se na classe existir uma chamada a MessageBox, e não exista referência a este tipo, o compilador acusará problemas.
Esta situação é resolvida através de importações de “bibliotecas”. Qualquer linguagem oferece (precisa oferecer) este recurso. Em Java, as bibliotecas (classes) são importadas através da instrução import, que se situa abaixo da declaração do pacote ao qual a classe pertence. O C# também, obviamente, oferece este recurso, porém, de outra forma. As classes em C# são importadas através da instruçãousing e se encontram antes da declaração do namespace, pois em C#, a classe é delimitada pelonamespace a que pertence. Veja nas Figuras 1 e 2 que os imports e usings estão localizados bem no início das classes.
Figura 5
 Processo de compilação e geração de bytecodes
Figura 5, logo acima, exibe a situação onde a implementação da classe Janela.java faz uso das classes JFrameJTextFieldJButton e JLabel. No processo de compilação, que gerará o arquivo “executável”, apesar da classe implementada usar outras quatro, apenas um arquivo é gerado, no caso do Java e deste exemplo, o arquivo Janela.class. O que diferencia este processo no C#, é que ao invés de bytecodes, são gerados assemblies. Os assemblies gerados podem ser aplicações (exe) oubibliotecas (dll).
Outro detalhe que diferencia esta funcionalidade entre as linguagens é que, em Java, é comum (mas não recomendado) ver situações como: import javax.swing.*;. Esta instrução importaria durante a compilação todas as classes utilizadas na classe em compilação que pertençam ao pacotejavax.swing. Em C#, um namespace importado seria análogo ao exemplo citado de Java (import javax.swing.*;). Em Java, importa-se classes, como javax.swing.JFrame e em C# não se importa uma classe, e sim o namespace daquela classe.
Prós e Contras
A situação oferecida pelo Java, de importar de forma explícita uma classe, e não seu pacote, apesar de isso ser possível, facilita em muito a identificação de a qual pacote uma classe pertence. Esta situação não ocorre em C#, mas a documentação oferecida (MSDN) é rica e auxilia em muito esta identificação, mas obviamente, na leitura de um código, na seção de importação não fica claro quais classes são utilizadas de cada namespace.
Outro detalhe que deve ser verificado, em C#, é que a instrução using não é exclusiva para a importação de bibliotecas (assemblies). Existe outro uso (muito bom) para ela, mas que está fora do escopo deste artigo. Já em Java, o import é exclusivo para a importação de classes.
Declaração das Classes
Figura 6
 Declaração de Classes
Uma classe, tanto em C# como em Java, representa um tipo de dado. Este tipo de dado é composto por atributos, que representam suas características, e métodos, que representam o comportamento da classe (ou serviços oferecidos por ela). E, como qualquer tipo de dado, presume-se que tipificará, neste caso, objetos a serem utilizados por outras classes.
Em Java, um arquivo pode ter várias classes, porém apenas uma delas pode ser pública, as demais terão seu acesso livre à todas as classes do mesmo pacote. Em C#, um arquivo pode ter várias classes também, porém, não existe a limitação de quantidade de classes públicas e as classes que não possuírem uma modificador de acesso, são por default internal.
Uma característica oferecida por C# e que não existe em Java é o conceito de partial class (classes parciais). Uma classe parcial pode ser visualizada como uma classe que possui sua implementação distribuída em mais de um arquivo. Essa característica pode ser facilmente visualizada em aplicações Windows Forms, criadas pelo Visual Studio, onde a interface (formulário) é alocada a um arquivo e o comportamento implementado para a mesma, em outro arquivo. O uso de classes parciais está fora do escopo deste artigo.
Em Java é possível alocar várias classes a um mesmo package, porém, como dito anteriormente, em arquivos separados se forem públicas. Em C#, uma classe pode ser declarada dentro de umnamespace, em um único arquivo, Desta forma, dentro deste namespace, várias classes públicas também podem ser criadas.
Uma atenção especial deve ser dada à visibilidade das classes. Em C#, além dos já conhecidos modificadores de acesso (ou escopo) – public, private e protected – existem ainda os internal e protected internal. O internal permite acesso apenas por serviços implementados no mesmo projeto (assembly), já com o protected internal (assim como o private em Java) não tem uso permitido para a declaração de classes. O detalhamento sobre visibilidade e tempo de vida de objetos está fora do escopo deste artigo.
Uma classe, sem modificador de escopo em Java, tem como padrão o acesso por pacote, porém, em C# o padrão é o internal. O C#, assim como o Java, permite que classes sejam declaradas dentro de classes.
Prós e Contras
A possibilidade de criar várias classes públicas em um único arquivo pode parecer benéfica, porém, minha opinião é que este recurso pode complicar a vida de um desenvolvedor. Eu prefiro e recomendo que uma classe seja sempre declarada em um arquivo específico para ela.
Outra situação que deve ser vista e padronizada é de, em C#, o namespace a que uma classe pertence não estar ligado fisicamente com a pasta onde o mesmo é armazenado. Isso dá liberdade ao desenvolvedor, mas pode trazer problemas futuros se não existir uma boa disciplina para garantir esta organização.
É preciso definir um padrão para este ponto. Eu particularmente, em C#, adotei o padrão do Java. Uma classe por arquivo (porém faço uso de classes parciais em alguns casos) e mantenho cada classe em seu respectivo namespace.
Atributos e Propriedades
Figura 7
 Declaração de Atributos e Propriedades
É comum verificar iniciantes, sejam profissionais ou alunos, uma dificuldade conceitual em relação a atributos e propriedades. Este conceito errado vem dos princípios da Orientação a Objetos. Um atributo é uma característica de um determinado objeto, porém, não existe regra ou obrigatoriedade para que este atributo seja visível/acessível externamente. Para que um atributo tenha esta característica (ser visível a outros objetos/classes), é preciso transformá-lo em propriedade. Uma propriedade é uma característica de um objeto, a qual pode ser acessada externamente, normalmente por outra classe/objeto.
Em Java, um atributo é declarado propriedade quando o mesmo possui métodos acessores públicos definidos para ele, ou seja, os métodos get e set. Desta forma, um atributo de um objeto em Java só pode ser acessado através de chamadas a métodos, que retornem valores (get) e que recebem valores (set), atualizando o estado do objeto.
Em C# a transformação de um atributo para propriedade é diferente, segue o padrão Delphi, ou seja, os valores são obtidos e atribuídos através de um operador de igualdade (=). A Figura 7, acima, apresenta as declarações privadas para os atributos e publicas para as propriedades, semelhante ao Java. Porém, veja que uma propriedade em C#, possui (não obrigatoriamente) os métodos get e set, onde existe então a implementação para atribuição e retorno do valor do atributo.
Figura 8
 Utilizando os acessores
Prós e Contras
A convenção trabalhada em Java cumpre de maneira explícita o uso de mensagens (métodos), quer seja para um serviço específico de uma classe, quer seja para atribuição simples de um atributo. C# aplica o mesmo conceito, porém fazendo uso explícito de propriedades, o que é mais intuitivo. Atribuição e obtenção de valores precisa ser uma operação simples. É mais natural. Métodos (mensagens) são (e devem ser) utilizados para resolverem problemas específicos, o velho conceito doDividir para Conquistar. A regra para consistência do atributo continua existindo em C#, da mesma forma que em Java, basta para isso, colocar esta regra no método get e set da propriedade.
Construtores
Figura 9
 Declaração de Construtores
Como pode ser verificado pelo apresentado na Figura 9, não existem diferenças na implementação de construtores. C# traz também o já famoso e útil this, que apenas para relembrar, é uma referência ao objeto atual da classe onde o mesmo é utilizado, quer seja para atributos, métodos ou até mesmo referenciando o uso em sobrecargas de construtores.


Referências:
http://pt.wikipedia.org/wiki/An%C3%A1lise_sint%C3%A1tica_(computa%C3%A7%C3%A3o)
http://pt.wikipedia.org/wiki/An%C3%A1lise_sem%C3%A2ntica
http://www.linhadecodigo.com.br/artigo/1620/java-e-csharpnetum-breve-e-introdutorio-estudo-comparativo-de-suas-sintaxes-e-convencoes.aspx

Nenhum comentário:

Postar um comentário