Quero melhorar meu programa com poo

oiii gente! eu to montando um programinha pra estudar, to usando herança, criei a superclasse Pessoa, e 3 subclasses: Aluno, Funcionário e Professor, e tb um executor pra mostrar as informações de cada um, queria se possível que me ajudassem a melhora-lo, dar novas funcionalidades pra ele, com métodos por exemplo, aqui ta o meu código por enquanto:

[code]public class Pessoa{

public String nome;
public String sobrenome;
public String estadocivil;
public String cidade;
public String estado;
public int idade;

}[/code]

[code]public class Aluno extends Pessoa{

public String matricula;
public String curso;
}[/quote]

[code]public class Funcionario extends Pessoa{

public String cargo;
public float salario;

}[/code]

[code]public class Professor extends Pessoa{

public String disciplina;
public float cargahoraria;

}[/code]

[code]public class Executor{
public static void main(String args[]){

//cria um objeto da classe Aluno
  //new aloca memoria para o objeto
Aluno aluno = new Aluno();

aluno.nome = "João";
aluno.sobrenome = "Silva";
aluno.idade = 22;
aluno.matricula = "630910098";
aluno.curso = "História";

//cria um objeto da classe Funcionario
Funcionario funcionario = new Funcionario();

funcionario.nome = "Amanda";
funcionario.sobrenome = "Gonçalves";
funcionario.idade = 19;
funcionario.salario = 4900;
funcionario.cargo = "Chefe";

//cria um objeto da classe Professor
Professor professor = new Professor();

professor.disciplina = "Linguagem de Programação 1";



//mostra dados do aluno
System.out.println("Nome: " + aluno.nome + "\n" +
		           "Sobrenome: " + aluno.sobrenome + "\n" +
                   "Idade: " + aluno.idade + "\n" +
                   "Matrícula: " + aluno.matricula + "\n" +
                   "Curso: " + aluno.curso + "\n");

//mostra dados do funcionario
System.out.println("Nome: " + funcionario.nome + "\n" +
                   "Sobrenome: " + funcionario.sobrenome + "\n" +
                   "Idade: " + funcionario.idade + "\n" +
                   "Salário: " + funcionario.salario + "\n" +
                   "Cargo: " + funcionario.cargo + "\n");   

//mostra dados do professor
System.out.println(“Disciplina: " + professor.disciplina +”\n");
}
}

[/code]

Obrigada!!

Troque as variaveis para private ou procted(que é melhor para a herança ),faça metodos getters e setters das variaveis, contrutores, e por fim mais opcional faça um metodo tipo imprimaDadosAlunos e insira nele, todas as saidas do sistema.

oii querido, fiz o que tu disse, da uma olhada, mas o meu executor ficou com problema, olha:

[code]public class Pessoa{

protected String nome;
protected String sobrenome;
protected String estadocivil;
protected String cidade;
protected String estado;
protected int idade;

//////////////get e set
protected String getNome() {
return nome;
}
protected void setNome(String nome) {
this.nome = nome;
}
protected String getSobrenome() {
return sobrenome;
}
protected void setSobrenome(String sobrenome) {
this.sobrenome = sobrenome;
}
protected String getEstadocivil() {
return estadocivil;
}
protected void setEstadocivil(String estadocivil) {
this.estadocivil = estadocivil;
}
protected String getCidade() {
return cidade;
}
protected void setCidade(String cidade) {
this.cidade = cidade;
}
protected String getEstado() {
return estado;
}
protected void setEstado(String estado) {
this.estado = estado;
}
protected int getIdade() {
return idade;
}
protected void setIdade(int idade) {
this.idade = idade;
}

///////////////////construtor
protected Pessoa(String nome, String sobrenome, String estadocivil,
String cidade, String estado, int idade) {
super();
this.nome = nome;
this.sobrenome = sobrenome;
this.estadocivil = estadocivil;
this.cidade = cidade;
this.estado = estado;
this.idade = idade;
}

}
[/code]

[code]public class Aluno extends Pessoa{

private String matricula;
private String curso;

//get e set
private String getMatricula() {
return matricula;
}
private void setMatricula(String matricula) {
this.matricula = matricula;
}
private String getCurso() {
return curso;
}
private void setCurso(String curso) {
this.curso = curso;
}
//construtor
private Aluno(String nome, String sobrenome, String estadocivil, String cidade,
String estado, int idade, String matricula, String curso) {
super(nome, sobrenome, estadocivil, cidade, estado, idade);
this.matricula = matricula;
this.curso = curso;
}

}
[/code]

[code]public class Funcionario extends Pessoa{

private String cargo;
private float salario;
//get e set
private String getCargo() {
return cargo;
}
private void setCargo(String cargo) {
this.cargo = cargo;
}
private float getSalario() {
return salario;
}
private void setSalario(float salario) {
this.salario = salario;
}
//construtor
private Funcionario(String nome, String sobrenome, String estadocivil,
String cidade, String estado, int idade, String cargo, float salario) {
super(nome, sobrenome, estadocivil, cidade, estado, idade);
this.cargo = cargo;
this.salario = salario;
}

}
[/code]

[code]public class Professor extends Pessoa{

private String disciplina;
private float cargahoraria;
//get e set
private String getDisciplina() {
return disciplina;
}
private void setDisciplina(String disciplina) {
this.disciplina = disciplina;
}
private float getCargahoraria() {
return cargahoraria;
}
private void setCargahoraria(float cargahoraria) {
this.cargahoraria = cargahoraria;
}

private Professor(String nome, String sobrenome, String estadocivil,
String cidade, String estado, int idade, String disciplina,
float cargahoraria) {
super(nome, sobrenome, estadocivil, cidade, estado, idade);
this.disciplina = disciplina;
this.cargahoraria = cargahoraria;
}

//construtor

}
[/code]

[code]public class Executor{
public static void main(String args[]){

//cria um objeto da classe Aluno
  //new aloca memoria para o objeto
Aluno aluno = new Aluno();

aluno.nome = "João";
aluno.sobrenome = "Silva";
aluno.idade = 22;
aluno.matricula = "630910098";
aluno.curso = "História";

//cria um objeto da classe Funcionario
Funcionario funcionario = new Funcionario();

funcionario.nome = "Amanda";
funcionario.sobrenome = "Gonçalves";
funcionario.idade = 19;
funcionario.salario = 4900;
funcionario.cargo = "Chefe";

//cria um objeto da classe Professor
Professor professor = new Professor();

professor.disciplina = "Linguagem de Programação 1";



//mostra dados do aluno
System.out.println("Nome: " + aluno.nome + "\n" +
		           "Sobrenome: " + aluno.sobrenome + "\n" +
                   "Idade: " + aluno.idade + "\n" +
                   "Matrícula: " + aluno.matricula + "\n" +
                   "Curso: " + aluno.curso + "\n");

//mostra dados do funcionario
System.out.println("Nome: " + funcionario.nome + "\n" +
                   "Sobrenome: " + funcionario.sobrenome + "\n" +
                   "Idade: " + funcionario.idade + "\n" +
                   "Salário: " + funcionario.salario + "\n" +
                   "Cargo: " + funcionario.cargo + "\n");   

//mostra dados do professor
System.out.println(“Disciplina: " + professor.disciplina +”\n");
}
}

[/code]

Uma dica interessante. Toda vez que você sentir a necessidade de inserir um comentário no seu código, tente transformar num método ou o que for melhor, ex :

//mostra dados do aluno

public void mostraDadosAluno(Dados dados){
}

assim você não precisaria do comentário e já notaria que você pode melhorar seu código criando o método mostraDados, que recebe uma Pessoa e fazendo uso do Polimorfismo que você mesmo inseriu ao dizer que Pessoa é interface de Aluno e Professor, vc teria métodos mais genéricos :

public void mostraDados(Pessoa pessoa) {
 System.out.println("Olá eu sou um : " pessoa.getClass());
 System.out.println("Meu nome é : " pessoa.getNome());
}

Ola Mariana!

Pense comigo:
Em algum momento na sua aplicação vc vai precisar lidar diretamente com uma instancia da classe pessoa?

Essa classe pessoa possui algum comportamento comummente interessante às demais subclasses?

Se as duas respostas foram NÃO então está na hora de abandonar a herança e usar a interface :idea:

Carlos,

Não jogo no time dos que defendem a herança, mas nesse caso não enxergo mal algum em seu uso, visando o polimorfismo (certo, a interface também daria isso) e principalmente a reutilização, evitando a repetição de código entre todas as pessoas. Acho que seria interessante Pessoa ser uma classe abstrata - ou seja, é apenas um conceito, que reune as características comuns e não pode ser instanciada - e as classes concretas herdariam dela.

Sei que muita gente condena herança, mas acho que há casos e casos… é isso é uma mera opinião minha. Há casos potenciais onde a tendência daquela árvore é crescer muito, dada a complexidade do conceito que representa e do montoado de operações que realiza, em que o uso de herança realmente é perigoso. Podemos ter uma árvore “genealógica” de classes imensa, todas amplamente acopladas e uma mudança no modelo quebraria tudo. Mudanças nas regras do jogo são comuns no mercado hj em dia, e como.

Porém em casos como esse, ou de pequenos componentes que não tem essa tendÊncia, não vejo a herança como o demônio que é apregoado. Pelo contrário, acho que tem-se uma modelagem clara, uma boa reutilização do código que é comum (e também centralização do mesmo - nesse caso, uma mudança no conceito geral seria facilmente refletido dado que a alteração seria feita na classe-pai), além do polimorfismo. Com interfaces temos o acoplamento mais baixo pois não temos código, apenas definições, temos polimorfismo, mas não temos a reutilização. Ainda que um método seja igual para as 1000 classes, as 1000 terão de implementá-lo. Porque não usar herança nesse caso? Composição aqui não faz muito sentido pra mim já que estamos falando da relação É UM e não TEM UM.

A própria API do Java tem muitos exemplos assim, onde o conceito é definido por uma interface, e dispõe-se de uma classe (geralmente abstrata) que implementa os métodos mais básicos (deixando os demais como abstratos). As especializadas herdam dessa classe (e automaticamente implementam a interface) e implementam suas particularidades. E mais: não tem essa de quebra de encapsulamento nesse caso, pois a assinatura está bem definida na interface e tudo que a classe especializada deve fazer é seguir a convenção, sobrescrevendo o método herdado.

Enfim… cada um com sua opinião e isso não é a verdade absoluta, até porque muitos gurus condenam a herança. Mas como sou um cara moderado, acho que há casos em que ela se encaixa bem.

Abraço

Boa noite galera,

Lendo as respostas me surgiram duas dúvidas:

1 - Porque protected é melhor para herança ?

2 - Estou tentando entender a diferença entre usar interface ou herança, nesse caso, por exemplo, da maneira como esta, temos a classe Pessoa com seus atributos e getters e setters.
As classes Aluno e Funcionario estendem Pessoa, então eles já recebem os atributos e metodos definidos nessa classe.
No caso de utilizar uma interface Pessoa, teriamos a definição dos metodos na interface Pessoa e sua implementação nas classes Aluno e Funcionario.
Nesse caso não teríamos uma repetição desnecessário de código ?
Ou seja, em Aluno teríamos a declaração dos atributos nome, sobrenome, idade, etc, bem como a implementação dos métodos e em Funcionario também ?

Por outro lado, fico pensando que com o uso da interface pessoa poderíamos ter algo como um método imprimeDados(Pessoa p) que poderia ser utilizado com Aluno e Funcionário…

Se alguém puder esclarecer as vantagens e desvantagens de cada opção fico muito grato.

[]s

[quote=Zeed01]Boa noite galera,

Lendo as respostas me surgiram duas dúvidas:

1 - Porque protected é melhor para herança ?

2 - Estou tentando entender a diferença entre usar interface ou herança, nesse caso, por exemplo, da maneira como esta, temos a classe Pessoa com seus atributos e getters e setters.
As classes Aluno e Funcionario estendem Pessoa, então eles já recebem os atributos e metodos definidos nessa classe.
No caso de utilizar uma interface Pessoa, teriamos a definição dos metodos na interface Pessoa e sua implementação nas classes Aluno e Funcionario.
Nesse caso não teríamos uma repetição desnecessário de código ?
Ou seja, em Aluno teríamos a declaração dos atributos nome, sobrenome, idade, etc, bem como a implementação dos métodos e em Funcionario também ?

Por outro lado, fico pensando que com o uso da interface pessoa poderíamos ter algo como um método imprimeDados(Pessoa p) que poderia ser utilizado com Aluno e Funcionário…

Se alguém puder esclarecer as vantagens e desvantagens de cada opção fico muito grato.

[]s[/quote]

Vc provavelmente fez estas perguntas pois a ajuda solicitada pela mariana deve ocasionado mais mais duvidas do que respostas.

1 - Para encapsular( pois as classes do cod. feito pela mariana não tinham) agora o melhor é definir todos atributos como private e os metodos getters/setters como publico.

2 - Interface (diminui o acoplamento e proporciona o polimorfismo) geralmente deve ser utilizada em classes que expressem comportamento e que estes se alterem para diferentes objetos do tipo informado, o que não é o caso de Pessoa, Funcionario.
Agora para o caso de uma classe como por exemplo Carro tem comportamentos distintos para diferentes tipos de carros seria interessante utilizar interface Carro.

imprimeDados(Pessoa p) nao ficaria nada legal na classe Pessoa pois objetos devem ser coesos fazer exatamente o que estao propostos a fazer ou representar.

Obs1: A herança tambem proporciona polimorfismo mas aumenta o acoplamento o que é ruim.
Obs2: Pessima pratica não encapsular objetos.
Obs3: Pense no objeto como um todo o que ele deve fazer, para descobrir se deve utilizar uma interface,classe abstrata, herança, etc…

Bom dia galera,

Rafael, acho que tivemos o mesmo entendimento, mas expressado de formas diferentes.

Acho que não fui bem claro, minha duvida era porque um colega afirmou que protected é melhor para herança do que private.
Na minha opinião os atributos deveriam ser private e os getters publicos na classe Pessoa.

O exemplo de metodo imprimePessoa também não era para ser criado na classe Pessoa, o que quis dizer é que em qualquer lugar onde ela fosse criar um metodo que poderia receber um Aluno ou um Funcionario (por exemplo, um metodo imprime) ela poderia cria-lo recebendo Pessoa, no caso de estar usando interface, claro.

[]s

Tid, sua resposta foi muito importante para o enriquecimento desse tópico!

Nesse caso não cabe interface, mas acho que ficou mais simples essa colocação em uma das perguntas que eu fiz no post anterior.

A herança não pode ser condenada, pois é uma ferramenta muito importante na orientação a objetos devido ao fato de poder compartilhar seus estados e comportamentos com suas subclasses. Tambem sou um cara moderado e acho que há casos em que a herança se encaixa bem, pra mim vai depender da resposta daquelas perguntas…

Acho que meu post gerou muitas duvidas não?? (rsrsrs)

1º- Disse para mudar o tipo das variaveis para private ou protected, para limitar o acesso as variaveis, porque ? alguem pegunta, para que nenhum usuario insira dados irregulares direto na variavel.Qual a diferença entre private e protected, private só existe na classe ou seja se vc tentar acessar uma variavel private de outra classe ou pacote vai dar erro.O protected é um meio termo enter public e private, vc pode acessar ela em outro pacote atraves da herança.

2º- Os metodos getters and setters devem ser public,serve para acesso desses artributos privados.

3º- Quando eu disse sobre o metodo imprimirDados() era para colocar nas classe mesmo é mais ou menos assim:

public class Aluno extends Pessoa{

private String matricula;
private String curso;

Aluno(String umNome,String umSobrenome…/todos os atributos da classe Pessoa/,String umaMatricula,String umCurso){

super(umNome,umSobrenome);
this.matricula=umaMatricula;
this.curso=umCurso;
}

public void setMatricula(String umaMatricula){
this.matricula=umaMatricula;
}

public void setCurso(String umCurso){
this.curso=umCurso;
}

public String getMatricula(){
return matricula;
}

public String getCurso(){
return curso;
}

void imprimiDados(){
super();//digamos que você tenha feito o mesmo na classe Pessoa,o super indica que você está herdando os atributos/metodos
//e com isto ele acaba imprimindo os dados da classe Pessoa
System.out.println(“Matricula”+getMatricula());
System.out.println(“Curso”+getCurso());
}

Bom é isto, caso eu tenha escrito alguma besteira por favor podem me corrigir.

Eu gosto de combinar os dois. É uma estratégia usada até mesmo no Java (TableModel interface, AbstractTableModel classe abstrata. Document, interface. AbstractDocument, classe abstrata).

Ou seja, crie a interface. Faça seu sistema retornar a interface, e aceitar parâmetros com o tipo da interface (seu JTextField aceita um Document, seu JTable um TableModel). Mas se uma implementação for muito padrão para todos que implementam aquela interface, então, já crie também uma classe abstrata, que implementa essa interface e tenha essa implementação padrão (você provavelmente vai criar um filho de AbstractTableModel para fazer seu tablemodel. Ou um filho de AbstractDocument para escrever seu document).

Isso tem a vantagem de que o seu usuário tem uma alternativa à classe Abstrata, caso a implementação dele fuja do padrão. Ele ainda poderá fazer proxies dinâmicos e mocks, coisas que geralmente só são possíveis (ou muito mais fáceis) com interfaces. Ou seja, você ainda ganha a vantagem do baixo acoplamento das interfaces, e também ganha a vantagem da implementação padrão da herança.

Não pode mesmo. É melhor preferir associações à herança, mas isso não significa que ela deixe de existir. Ela tem papel fundamental em diversos padrões de projeto, como o template method ou mesmo o abstract factory.

Quanto ao protected ser melhor para herança: De onde isso surgiu? Existem discussões infindáveis sobre esse assunto. Eu prefiro deixar atributos private e criar métodos de acesso protected, quando quero deixar só as subclasses atualizá-los.

Boa tarde galera,

Como sempre ViniGodoy e suas explicações claras, sensatas e muito bem embasadas !
Parabéns pela sua enorme contribuição no forum.

ViniGodoy
"Quanto ao protected ser melhor para herança: De onde isso surgiu? Existem discussões infindáveis sobre esse assunto. Eu prefiro deixar atributos private e criar métodos de acesso protected, quando quero deixar só as subclasses atualizá-los. "

Assino embaixo…

[]s

[EDIT]
P.S. - Vini… é impressão minha ou você tem fixação por TableModel ??? rs

Nem tanto… hehehhehehe…

:twisted: Só tenho fixação por destruir o DefaultTableModel. :evil:

Ainda sobre o assunto interfaces, vale ler essa entrevista com o Erich Gamma, criador do Eclipse, JUnit e um dos autores do livro padrões de projeto:
http://www.artima.com/lejava/articles/designprinciples.html

Justamente! Como havia dito e você ressaltou bem, há diversos exemplos desse tipo no Java (Collections, por exemplo). A interface define o tipo e temos uma classe abstrata que implementa o básico, deixando os métodos mais específicos para as classes concretas. Dessa forma, a classe abstrata nos fica como opção e não como obrigação! POdemos extende-la e reutilizar seu código ou simplesmente implementar a interface. Com as referências no código sempre apontando para a interface, o polimorfismo aparece no seu estado da graça e todos ficam felizes =)

obrigada pelas explicações queridos!
bjokas

mariana, os métodos get/sets devem ser públicos.

Na hora de atribuir os resultados, vc fazia:

Faça agora

Na hora de “imprimir” o resultado, vc fazia:

... + aluno.nome + ... Faça agora

Trabalhando polimorfismo:
Tanto em aluno, quanto em funcionário, sobreescreva o método toString() da classe Object (herdada por todas as classes) fazendo que ela retorne a String que deseja imprimir e substitua o System.out.println(…) atual por System.out.println(aluno) e System.out.println(funcionario)

Vc pode criar um método

void mostraDados(Pessoa pessoa) { System.out.println(pessoa); }e colocaria a chamada deste no lugar dos System.out originais.

Não vejo necessidade de uso de interfaces neste caso apesar de, conceitualmente valer a pena um pouco mais de estudo.