Métodos e encapsulamento

37 respostas
java
C

Utilizando o conceito de objectos e encapsulamento capture o nome , 4 notas do aluno e que ainda retorne a média e se o aluno passou ou reprovou, o aluno foi aprovado se tirar media maior ou igual a 6

package notaenome;

import java.util.Scanner;

public class NotaENome {

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    dadosAluno aluno = new dadosAluno();

    int i = 0;
    double nota = 0;
    String nome = "";
    System.out.println("Digite o nome do aluno");
    aluno.setNome(nome);
    System.out.println("Digite a nota do aluno");
    aluno.setNota(nota);
    
    while (i < 4) {
        System.out.println("Digite a nota do aluno");
        aluno.setNota(nota);
        i++;
    }

    System.out.println("A soma da nota é " + aluno.getNota());
}

}

package notaenome;

public class dadosAluno {

private String nome;
private double nota;


public dadosAluno() {

    nome = "";
    nota = 0;

}

public String getNome() {
    return nome;
}

public void setNome(String nome) {
    this.nome = nome;
}

public double getNota() {

    return nota;
}

public void setNota(double nota) {
    this.nota = nota;
}

private static double soma(double nota) {
    int contar;
    double soma = 0;
   
    for (contar = 0; contar <4;contar++) {
        soma = soma + nota;
    }
    return soma;
}
private static double media(double soma){
double medianota;
    medianota=soma/contar.length ;

return medianota;
}

}

37 Respostas

L

Primeiramente NÃO DUPLIQUE O TÓPICO por estar com pressa. Se quiser se expressar melhor edite-o ou espere alguém responder.

Agora vamos ao problema… onde que está sendo feito a soma na classe NotaENome.java?
Tem dois setters um fora e outro dentro do laço while. Esse fora não precisa existir.

Outra coisa, como está pegando os valores se a classe Scanner não está sendo usada?

Outra coisa, na classe dadosAluno.java (nomenclatura em Java nome de classe sempre começa com letra maiúscula, isso não impede de a classe compilar, mas é um padrão a ser seguido) no método media(double soma) de onde tá vindo essa variável contar? Acredito que tenha um erro aí porque ela foi declarada em escopo local.

Não quero soar arrogante, mas recomendo fortemente dar uma estudada porque parece que você não tem uma base. Assiste essas aulas. A didática é boa e caso vá surgindo dúvidas vai perguntando aqui.

L

Aqui está como seria uma das formas de fazer isso. Mas, cara estude realmente. Copiar e colar no começo é interessante pra poder ir entendendo o que foi feito. Outra coisa, não espere código pronto sempre que tiver uma dúvida.

Veja o que foi feito no exemplo abaixo e o que tá faltando no seu código.


public class NotaENome {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        DadosAluno aluno = new DadosAluno();
        System.out.println("Digite o nome do aluno: ");
        aluno.setNome(sc.nextLine());
        int count = 1;
        double soma = 0;
        System.out.println("\nAluno: " + aluno.getNome());
        while (count <= 4) {
            System.out.println("Digite a " + count + "º nota do aluno: ");
            aluno.setNota(sc.nextDouble());
            soma += aluno.getNota();
            count++;
        }
        double media = soma/4;
        System.out.println("A média do aluno " + aluno.getNome() + " é: " + media);
    }
}

public class DadosAluno {

    private String nome;
    private double nota;

    public DadosAluno() {
        nome = "";
        nota = 0;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public double getNota() {
        return nota;
    }

    public void setNota(double nota) {
        this.nota = nota;
    }
}
C

Lucas, obrigado pelas respostas dada. Estou estudando para que possa chegar ao nível aceitável. Por acaso só mesmo iniciante neste matéria. E pior ainda é pela primeira fez que uso o conceito de encapsulamento

T

Aproveito para deixar uma outra dica, a semântica é importante e, neste caso, a classe dado aluno, poderia se chamar “Aluno”, uma vez que, serve de modelo para todos os alunos. Fica mais claro, exemplo:

Aluno aluno=new Aluno();

aluno.setNota(2);

aluno.getNota();

A classe “DadosAluno” gera um entendimento de algo que resgata dados do aluno ou algo assim. Só exemplo, ok?

Abraço e bons estudos!

Só uma dicas

L

Somo nós. Me desculpa se sooei arrogante. Acompanha as aulas dessa playlist que te mandei e qualquer dúvida vai perguntando.

P

Seu código não esta encapsulado porque os atributos do objeto DadosAluno estão acessíveis.

L

Onde que tu tá vendo isso? Os atributos da classe que tu disse estão privados.

P

E?
Encapsulamento esta quebrado se você expos todos os atributos. Não importa se é via get ou atributo público.

J

Métodos getters/setters estão ai só pela burocracia da linguagem Java. Na prática não é um caso de encapsulamento mesmo.

D

O grande problema é que existem pouquíssimas referências que podemos utilizar que nos permitam uma visão diferente desse lugar comum do decoreba: bota private em tudo, gera getters/setters e está encapsulado.
Exemplo
Não me recordo de nenhum material que eu tenha visto na vida acadêmica ou posterior a ela que tenha abordado encapsulamento de maneira distinta da definição encontrada aí neste texto da devmedia.

J

Concordo. Outro grande problema que sempre vejo está relacionado ao uso de herança, e está neste mesmo link que voce passou!

P

getters/setters não tem lugar no design OO. Eles foram criados para serem usados pelas ferramentas visuais mas na prática isso nunca funcionou. Agora todo mundo usa como um sinal que seu código é OO. lol

Existem milhares de artigos na web sobre os problemas de getters e setters e porque eles violam o princípio do encapsulamento.

D

Sim, existem. Mas, o que eu me refiro é que, em geral, o que se ensina é diferente disso. Ensina-se a repetir que atributos privados e getters/setters garantem o encapsulamento para os campos.
Além disso, quando uma bibliografia ou site ou vídeo aborda o encapsulamento, inevitavelmente ruma para este mesmo lado.
Que é o mesmo que ocorre com herança/realização e o tão temido polimorfismo.

Tem um ótimo artigo, já antigo, no blog da caelum sobre o uso indiscriminado de get/set, só como exemplo.

P

Encapsulamento significa poder alterar a definição interna de um objeto sem que seja necessário alterar outras partes do programa, onde o objeto é usado.

Se você faz uma mudança relacionado a definição de um campo (tipo do atributo, por exemplo) que possui um getter/setter, vai precisar alterar seu programa em vários lugares onde o getter/setter é usado. Neste caso, não existe encapsulamento.

D

Hum, coesão e acoplamento são, apenas, sinônimos ou são termos utilizados para descrever coisas distintas disso?

Entendo que encapsulamento é algo como

Encapsulation is an Object Oriented Programming concept that binds together the data and functions that manipulate the data, and that keeps both safe from outside interference and misuse. Data encapsulation led to the important OOP concept of data hiding.

Tanto que, quando fazemos uso de uma interface, estamos, além do óbvio uso do conceito de realização (implementação), aplicando o encapsulamento num nivel maior, que abrange os objetos em si, como um todo e não as suas partes.
é neste aspecto que eu me refiro quando afirmo que todo o ensino é falho quando trata de conceitos de OO, principalmente encapsulamento, herança/realização e polimorfismo.
E, com certeza, por conta destas falhas que muitos não compreendem como refatorar e melhorar seu código.
Em tempo, a definição de encapsulamento eu tirei daqui

P

Não tem como declarar um atributo como propriedade no Java?

@property int nota;

Dessa maneira as ferramentas para criação de GUIs não precisariam se basear em métodos getter/setter para inferir a existência de um atributo.

P

Usar getter/setter viola o conceito de encapsulamento no sentido que não vai levar ao conceito de data hiding (ou data abstraction), que é expor apenas a interface e esconder os detalhes de implementação. Atributos não fazem parte da interface.

Podem começar retirando os getter/setter. Eles foram feitos para serem usados apenas por ferramentas de criação de GUIs e sua existência denuncia que o design não é OO.

D

Eu entendo isso, tanto que é o que estou colocando desde o começo.
Também entendo que isso não é um “benefício” apenas do Java. Em C# isso também é feito, por exemplo (de maneira diferente, mas, com a mesma razão).

Sugestão sobre como substituir os getters/setters?

Lembrando que não são apenas os geradores de GUI que fazem uso disso, boa parte dos frameworks (spring, hibernate, eclipselink, jsf, struts 2) fazem uso destes métodos (medonhos) em prol de seu funcionamento, tanto que muitos consideram tais métodos uma maneira padrão de desenvolver para java.
Não sei se o que escrevo a seguir ainda é assim, mas, era até alguns anos atrás:
O Spring framework não injeta uma instância de objeto numa variável se a mesma não possuir um setter e getter corretamente definidos. Usar o construtor? É uma opção.
Hibernate e EclipseLink idem. Precisam dos setters quando recuperam valores das tabelas e dos getters para fazer os inserts, updates, etc.

J

Não sei, mas no C# é direto na linguagem.

P

No exercício em questão, a classe principal poderia ter usado um map pra guardar os dados do aluno. A classe DadosAluno não serve pra absolutamente nada, apenas pra complicar.

Bem lembrado…

Mas só pra ficar claro, apenas estou dizendo que getter/setter viola encapsulamento. Não estou dizendo pra não usar getter/setter no JSF, ou injetar dependência apenas via construtor no Spring. Se esta usando frameworks que exigem getter/setter, não tem porque lutar contra eles. Melhor focar no que sua aplicação JSF ou Spring precisa fazer, afinal, os usuários/clientes da sua aplicação não ligam se ela segue princípios OO.

Encapsulamento é um princípio importante que vale a pena ser seguido, mas em software de larga escala, com maior complexidade, e não para as aplicações CRUD tipicamente criadas com esses frameworks.

D

O ponto é que, didaticamente, essa classe acaba se justificando para que “os alunos aprendam”. Não importa se é encapsulamento, herança, agregação, existe meio que um bloqueio que torna incapaz todo e qualquer ser que tente ir contra tal corrente de pensamento.
E isso se explica, afinal, qualquer sistema legado (vamos considerar só os legados) vai possuir um sem número de classes “anêmicas”, cuja principal (e única) razão de ser é manter os dados em memória enquanto determinado trecho do código é executado (algo como pegar no DAO com ORM, transportar até a controller, copiar para o helper e enviar para onde será utilizado).
É como se acostumou a fazer e a maioria faz no automático.
A justificativa é sempre “orientação a objetos”.

J

Esses casos não deixam de existir quando se modela orientado a banco, não acho isso errado, mas a linguagem que é engessada para este caso.

Em Kotlin tem o “data class”, que é o ideal para estes casos.

data class Aluno(val nome: String, val nota: BigDecimal)

P

Qual a necessidade de um tipo referencia nesse caso, em vez de um tipo valor (struct em c#, por exemplo)?

J

O problema é mais cultura do que necessidade. Vide uso de Hibernate sem necessidade por exemplo.

Na tribo do Go por exemplo é mais provavel que o pessoal use struct puro.

D

Mas eles existem justamente por conta de modelagem orientada a banco de dados, afinal, precisa-se representar os dados em memória e “despachar” para algum lugar.

D

Desconheço esse tipo (tenho um parco conhecimento de C#). De qualquer maneira, a alegação é essa: orientação a objetos.

J

Sim, mas a questao que no caso do Java fica muito verboso para atender isso.

Tambem trabalho orientado a banco, as classes sao diretamente as entidades do banco. A equipe usa property do C#, que quase nunca sao usados os recursos OO, mas é bem mais limpo do que getters/setters da linguagem Java.

Na época que eu trabalhava com OOP foi no saudoso Delphi com Object Pascal, criando componentes para VCL. Para dados do usuário nunca vi grandes vantagens em modelo OO.

D

No PHP, se eu bem me lembro, existia (ou ainda existe, não sei) um framework ORM que tinha um funcionamento fantástico, se não me engano, se chamava ActiveRecorder e teria sido inspirado em algo vindo do Ruby on Rails.
Basicamente, não havia classes de domínio, apenas a configuração do ORM.

P

Uma big corp que pagou milhões por uma aplicação CRUD com hibernate não pode simplesmente “deixar de usar” o sistema por pior que ele tenha ficado. Mas fora essas casos, alguém ainda usa Hibernate?

P

Bom, você ainda vai estar usando os objetos Scanner e System… :rofl:

A melhor maneira de aprender OO é criando front-ends porque a pessoa pode usar a biblioteca de componentes disponíveis, em pouco tempo ela estará criando seus próprio componentes. Muito melhor que esses exercícios de OO que pedem pra pessoa já sair modelando um problema nada a ver com OO usando OO.

D

Sério, não vejo sentido nisso.
Eu entendo que a questão do OO e o processo de aprendizado está errado.
Teoricamente, você deveria ser ensinado a pensar em OO e não inserir OO numa linguagem, forçando que o entendimento de qualquer conceito OO esteja associado à esta ou àquela linguagem.
Eu comecei com C++, apenas estruturado (ironia, não?). Passei para PHP (estruturado), depois, java.
Então, quis retornar ao PHP, estudar PHP OO e tive imensa dificuldade, uma vez que tudo o que eu entendia do conceito de OO estava associado com a maneira que o java trata OO, ou melhor, com a maneira como fui ensinado a associar a sintaxe java (e suas peculiares saídas pela tangente) com OO. Resultado: desisti de aprender PHP OO.

Dia desses, vi um vídeo em que alguém dizia (não me recordo quem) que uma das dificuldades em se aprender um novo idioma se deve ao fato de que cada idioma possui uma maneira diferente de pensar. Assim sendo, eu não consigo aprender russo, pensando como brasileiro que fala português. A construção das sentenças, a maneira de interagir muda.
Isso se aplica, também, à OO (e a N outras coisas, incluindo lógica de programação). Se você aprender isso atrelado a uma linguagem, tem grandes chances de estar falhando miseravelmente.

J

Padrão ActiveRecord, embora misture responsabilidades, para CRUDs simples é super prático em ferramentas que AR faça parte de toda stack, como você citou o caso do Rails. C# também já teve uma implementacao do AR com NHibernate, o Castle, mas não pegou.

D

Depois de conhecer o conceito, vi alguma coisa para java, mas, da mesma maneira, morreu antes mesmo de chegar à praia.

P

Pensador OO?

C- -?

Talvez uma das melhores decisões da sua vida.

Você sabe Java e PHP (estruturado). Não acho que perdeu nada de valor ao desistir da idéia de aprender PHP OO.

D

Sim, entender o conceito e poder aplicá-lo, independente da linguagem. Como deveria ocorrer com lógica de programação.

Não, era C++ sem objetos.

Filosofias à parte, eu acredito que tudo o nada do que se aprende é perdido e tenho tido bons resultados com essa maneira de pensar.

P

Hibernate sem XML?

Linguagens dinâmicas podem dispensar toda a complicação que frameworks Java tem que recorrer pra tornar a linguagem mais dinâmica, como usar XML.

D

Uso hibernate sem XML há, pelo menos, 6 anos. E, entendo, que o hibernate sacrifica algumas coisas em prol de outras. Não é esse o preço dos frameworks? Não é assim com o rails do ruby ou o próprio laravel do php?

O que me refiro ali é não existir a necessidade de criar as estruturas da classe para representar uma tabela (a entidade, seus campos privados e métodos de acesso), tendo, em um nível acima, todos os métodos necessários para o CRUD (como o active record funciona).
Isto, da maneira que se comporta é, inclusive, abordado por Robert Cecil Martin, no livro sobre clean code, quando o mesmo fala sobre estruturas de dado e objetos. Ele é bem sucinto ao comentar sobre active records e foca, infelizmente, no ponto negativo da coisa.

Criado 28 de janeiro de 2018
Ultima resposta 30 de jan. de 2018
Respostas 37
Participantes 6