[Resolvido] Esconder método

10 respostas
Enio_Carvalho

Olá Pessoal.

Eu tenho uma classe A que contém os métodos
getB,
setB,
getC,
setC,
getD,
setD.

Tenho também uma classe filha E que herda da classe pai A.

Porém, os métodos getD e setD não são necessários para a classe E, na verdade só poluem a classe.

Tem como esconder estes métodos, para que não sejam exibidos ao usuário final?

10 Respostas

nel

Restringe o acesso destes métodos como default (Não declare nenhum tipo de acesso, private…public…).
Apenas lembrando, se a sua subclasse estiver no mesmo pacote que a superclasse estes métodos serão visualizados.

Abraços.

Rafael_Nunes

Marca eles como ‘private’
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

M

Não estenda a classe. Se existe algum atributo/método da superclasse que não deve haver na subclasse existe uma alta probabilidade de herança não ser adequada.

xjunior

bom amigo, vc pode fazer o seguinte, ao invés de fazer a herança assim, faça um adapter da classe principal, que por sua vez possuirá somente os métodos que vc necessita, e se vc precisar de todos os métodos, aí sim vc herda da classe mãe.

fguazzel

pra mim, se a classe pai é mais especializada que a filha, só pode ser uma coisa: Erro de projeto e a herança está invertida.

Enio_Carvalho

Rafael Nunes:
Marca eles como ‘private’
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Mas não consigo que na classe pai ele seja public e na filha seja private.

M

Enio Carvalho:
Rafael Nunes:
Marca eles como ‘private’
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Mas não consigo que na classe pai ele seja public e na filha seja private.


Isso não é permitido mesmo (você não pode diminuir a visibilidade de nenhum membro herdado). Qual é exatamente e seu caso? (quem estende quem? quais métodos há nessas classes?).

Enio_Carvalho

Vou explicar o caso concreto pra vocês:

A Classe pai a que me refiro é a seguinte:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * Provê a estrutura de fábrica de conexões.
 * 
 * @author Enio Carvalho
 * @version 1.0.0.1
 * 
 */
public abstract class ConnectionFactory implements IConnectionFactory {
	@Override
	public abstract String getDriver();

	@Override
	public abstract String getUrl();

	@Override
	public Connection getConnection() {
		try {
			Class.forName(getDriver());
			if (getUser() != null) {
				return DriverManager.getConnection(getUrl(), getUser(), getPwd());
			} else {
				return DriverManager.getConnection(getUrl());
			}

		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public abstract String getSgdbName();

	/**
	 * Armazena o usuário da conexão.
	 */
	private String user;

	/**
	 * Devolve o usuário da conexão.
	 * 
	 * @return retorna o usuario da conexão.
	 */
	public String getUser() {
		return user;
	}

	/**
	 * Atribui um usuário a conexão.
	 * 
	 * @param user
	 *            usuário de banco.
	 */
	public void setUser(String user) {
		this.user = user;
	}

	/**
	 * Armazena a senha da conexão.
	 */
	private String pwd;

	/**
	 * Devolve a senha da conexão.
	 * 
	 * @return retorna a senha da conexão.
	 */
	public String getPwd() {
		return pwd;
	}

	/**
	 * Atribui uma senha à conexão.
	 * 
	 * @param pwd
	 *            Senha descriptografada.
	 * @see #setUser
	 */
	void setPwd(String pwd) {
		this.pwd = pwd;
	}

}

A classe filha que me refiro é mais ou menos a seguinte:

public class SqliteConnectionFactory extends ConnectionFactory {

	@Override
	public String getDriver() {

		return "org.sqlite.JDBC";
	}

	@Override
	public String getSgdbName() {
		return "SQLite";
	}

	@Override
	public String getUrl() {
		return getDriver() + getDbFileName();
	}

	/**
	 * Seta o nome do arquivo que contém o database Sqlite.
	 * 
	 * @param dbFileName
	 *            Nome do arquivo que contém o database Sqlite.
	 */
	public void setDbFileName(String dbFileName) {
		this.dbFileName = dbFileName;
	}

	/**
	 * Devolve o nome do arquivo que contém o database Sqlite.
	 * 
	 * @return Retorna o nome do arquivo que contém o database Sqlite.
	 */
	public String getDbFileName() {
		return dbFileName;
	}

	/**
	 * Armazena o nome do arquivo que contém o database Sqlite.
	 */
	private String dbFileName;
	


}

Todos os SGDBs que conheço utilizam autentucação. Entretanto, o SGDB (isto se podemos chamá-lo assim) SQLite não utiliza usuário ou senha. Pra quem não conhece, ele é um arquivo que tem a maioria das funcionalidades de um SGDB, cujo acesso às tabelas é permitido a quem tem acesso ao arquivo.

, Acho que o mais apropriado é que quem estivesse utilizando a classe filha, não visse os métodos getUser, setUser, getPwd e setPwd.

O que acham?

Peço por favor a ajuda de vocês.

M

Pois é… nesse caso a herança está certa pois o conector para o SQLite é um conector. Acontece que o SQLite é uma exceção. Portanto você poderia lançar uma exceção caso alguma operação indevida fosse feita. Para isso sobreescreva os getters e setters do usuário e senha assim:

public class SqliteConnectionFactory extends ConnectionFactory {

    // outros métodos aqui....

    // nos getters retorna null:
    public String getUser() {
        return null;
    }

    public String getPwd() {
        return null;
    }

    // e nos setters lança uma exceção caso seja chamado:
    public String getUser() {
        throw new UnsupportedOperationException();
    }

    public String getPwd() {
        throw new UnsupportedOperationException();
    }

Captou a ideia?

Ah… outra coisa: as classes abstratas que estendem outras classes abstratas ou implementam uma interface não precisam explicitar métodos que elas não implementam.

Em outras palavras, você não precisa colocar nada disso na sua classe ConnectionFactory, pois como essa classe é abstrata subentende-se que esses métodos devem ser implementados por subclasses:

// tudo isso pode ser omitido:

	@Override
	public abstract String getDriver();

	@Override
	public abstract String getUrl();

	@Override
	public abstract String getSgdbName();
Enio_Carvalho

Valeu Marco Biscaro, vou seguir sua idéia de lançar uma exceção quando estes métodos forem setados.

Abraço!

Criado 12 de fevereiro de 2010
Ultima resposta 14 de fev. de 2010
Respostas 10
Participantes 6