Tipos Genéricos / Classes Tipadas?

Não sei se deveria chamar esse exemplo de tipo genérico ou classe tipada. Vamos lá.

Tenho a Classe Fórum, que possui uma coleção da classe postagem:

[code]public class Forum {

private String mensagem;
private Usuario user;
private ArrayList<Postagem> postagens = new ArrayList<Postagem>();
private ArrayList<Listener> observers = new ArrayList<Listener>();

public <T> void addPostagem(String mensagem, Usuario user) {
    Postagem post = new Postagem(mensagem, user);
    postagens.add(post);
}

public ArrayList<Postagem> getPostagens() {
    return postagens;
}

}[/code]

A classe Postagem, que possui um atributo do tipo Usuario (associação):

[code]public class Postagem {

private Usuario user;
private String mensagem;

public Postagem(String mensagem, Usuario user) {
    this.mensagem = mensagem;
    this.user = user;
}

}[/code]

O que procede é o seguinte, além da classe usuário, tenho a classe UsuarioRegistrado e Anônimo e ambas herdam da calsse Usário e possuo a classe Administrador que herda da classe UsuárioRegistrado.

Quando instancio um Fórum do tipo ele não deveria aceitar mensagens de usuários anônimos, nem de usuários registrados, somente de administradores. Não é isso? O que acontece é que aceita de todo mundo, tenho q implementar a tipagem no método adiciona? Se sim, onde? Por que não aceita em lugar nenhum, só antes do void…mas aí ainda qualquer usuário consegue posta.

Obrigado, espero que tenha sido claro o suficiente sobre minha dúvida.

Fiz o exemplo completo, só para você ver como é que se trabalha com generics. Não se esqueça: variáveis de instância , dentro da medida do possivel, devem ter o tipo da interface (“java.util.List”), não o da classe concreta (“java.util.ArrayList”), a menos que você precise de algo que amarre você à implementação ArrayList.

EDIT - Não precisa usar filtro nenhum, é para tais coisas que existe Generics!

import java.util.*;

interface Listener{
}

class Usuario {
}
class UsuarioRegistrado extends Usuario {
}
class Anonimo extends Usuario {
}
class Administrador extends UsuarioRegistrado {
}

class Forum<T extends Usuario> {
     private List<Postagem> postagens = new ArrayList<Postagem>();  
     private List<Listener> observers = new ArrayList<Listener>();  
   
     public void addPostagem(Postagem<T> post) {  
         postagens.add(post);  
     }  
     public void addPostagem(String mensagem, T user) {  
         postagens.add(new Postagem<T>(mensagem, user));  
     }  
     
   
     public List<Postagem> getPostagens() {  
         return postagens;  
     }  
 }  

class Postagem<T extends Usuario> {  
   
    private Usuario user;  
    private String mensagem;  

    public Postagem(String mensagem, T user) {  
        this.mensagem = mensagem;  
        this.user = user;  
    }  
}  

class TesteForum {
    public static void main(String[] args) {
        Forum<Administrador> fa = new Forum<Administrador>();
        Administrador adm = new Administrador();
        Forum<Usuario> fu = new Forum<Usuario>();
        Usuario usr = new Anonimo();
        fa.addPostagem (new Postagem<Administrador>("Administrador postando em forum de administrador", adm));
        fa.addPostagem ("Administrador postando em forum de administrador", adm);
        fa.addPostagem (new Postagem<Usuario>("Usuario postando em forum de administrador", usr)); // vai dar erro de compilação
        fa.addPostagem ("Usuario postando em forum de administrador", usr); // vai dar erro de compilação
        fu.addPostagem (new Postagem<Usuario>("Usuario postando em forum de usuario", usr));
        fu.addPostagem ("Administrador quer postar como usuario", adm);
    }
}

Sim, se fizer vc quiser fazer o filtro, é isso ai

tipo

[code]public class Forum {

private String mensagem;   
private Usuario user;   
private ArrayList<Postagem> postagens = new ArrayList<Postagem>();   
private ArrayList<Listener> observers = new ArrayList<Listener>();   

public <T> void addPostagem(String mensagem, T user) {   
    Postagem post = new Postagem(mensagem, user);   
    postagens.add(post);   
}   

public ArrayList<Postagem> getPostagens() {   
    return postagens;   
}   

} [/code]

desta forma so vai ter Usuario para postar, e ele so vai aceitar o do mesmo tipo do forum

EDIT.: Thingol sempre mais rapido q eu… =[ ^^ … acho que o q faltava pra vc mesmo era só o <T extends Usuario>

Funcionou do jeito que eu queria aqui., vou fazer as implementações de projeto Observer e ver como que fica.

Alguém poderia me explicar que seria o “filtro” que vocês se referem? Minha net é bloqueada e não consigo pesquisar no google, consegui que o adm de rede liberasse o fórum apenas.

Obrigado,

Hum… é que ia ter gente que em vez de usar generics do jeito certo, ia querer checar o objeto quando ele é adicionado em tempo de execução (e é por isso que a gente falou em “filtro”). Mas não é preciso checar em tempo de execução; em tempo de compilação é suficiente.

lembre-se de 1 coisa… da forma que vc relatou estar distribuida suas calsses, forums para usuario anonimo só terão acesso liberado para estes, a não ser que vc faça o forum para Usuario no lugar de Anonimos

conforme vc relatou

Anonimo descende de Usuario
UsuarioRegistrado descende de Usuario
Administrador descende de UsuarioRegistrado … (Edit, tinha escrito errado)

sendo assim

Forum<Anonimo> exclui dele tanto usuarios registrados como adminis…

Adminis so tem acesso a Forum de Usuario, UsuarioRegistrado e de Administrador

então cuidado ^^