Classe Pai acessar atributo classe Filha

Bom dia,

Minha pergunta parece estranha, mas acredito que deve haver uma maneira de fazer isto…
Certo, a pergunta é: Como posso alterar um atributo da classe Filho através da classe Pai?

Algo assim:

[code]public class Pai {
protected void setAbc(int a) {
// Aqui deve alterar o valor do atributo abc da classe filho
}
}

public class Filho extends Pai {
public int abc; // Alterar este ao chamar o método da Pai
}[/code]

Fica ai para o pessoal bom do forum :slight_smile:

Isso eh uma pessima ideia. Pq vc quer fazer isso?

Polimorfismo e casting de objetos

Isso eh uma pessima ideia. Pq vc quer fazer isso? [2]

Seria algo assim…

Tenho uma classe chamada ModelBean() (a qual seria a pai)

Que é algo assim:

[code]public class ModelBean {
public void setAlgo(int algo) {
// SETA SEMPRE O ATRIBUTO DA CLASSE FILHO,
// SEM PRECISAR CRIAR DENOVO NA CLASSE FILHO
}
}

public class TesteBean extends ModelBean {
public int algo;

// Faço na classe pai, para mim não fazer em todos os meus beans...

}

//ai fica simples assim:

new TesteBean().setAlgo(123);[/code]

Pois bem, parece meio sem noção no inicio, mas pode ser que você imaginem outra forma…

Poderia exemplificar?

public abstract class Pai { protected void setAbc(int a) { // Aqui deve alterar o valor do atributo abc da classe filho this.setNewValue(a); } abstract protected void setNewValue(int newValue); }

[code]public class Filho extends Pai {
private int abc; // Alterar este ao chamar o método da Pai

protected void setNewValue(int newValue) {
this.abc = newValue;
    System.out.println("Meu valor foi alterado para > "+newValue);
}    

}[/code]

public class Teste { public static void main(String[] args) { Filho f = new Filho(); f.setAbc(50); } }

Agora conta pra nós por que vc quer fazer isso?

flws

fantomas:
Não seria o meu caso hehe…

Pois eu deveria em todos meu beans implementar novamente o método setNewValue, o qual não desejo…

Certo, irei explicar agora para vocês…
Antes de mais nada quero fazer isso no PHP…

Pois bem, agora meu exemplo no PHP:

[code]class ModelBean {

public function setar_toscao($nm, $vl) {
    $this->$nm = $vl; //Claro que trato isso, mas a grosso modo é isso,
                      //mas o $this, deve se referir a classe Filha e não ao da pai
}

}

class TesteBean extends ModelBean {

public $abc;

}

// Usando
$testeBean = new TesteBean();
$testeBean->setar_toscao(“abc”, “valor qualquer”);[/code]

Entenderam? Isso a grossoooo modo, claro que tem uma série de coisas para deixar certo o código, mas o que interessa no momento é acessar ali e ser feliz!

Se entendi bem o que vc quer, a única coisa que chega perto disso é a reflexão (reflection); onde vc pode alterar atributos e executar metodos de um objeto de forma dinamica.

Dá uma lida no assunto e vê se te atende.

flws

Para que declarar o atributo na classe filha então ?

Declare apenas na classe Pai e acesse-o através do método get.

Ja não resolve ?

[]'s

Se nem todas as classes terão o atributo, como que a classe pai vai saber que pode ou não fazer o set?

Claramente, há algum erro gravíssimo na sua modelagem. A idéia está cheirando mal.

[quote=ViniGodoy]Se nem todas as classes terão o atributo, como que a classe pai vai saber que pode ou não fazer o set?

Claramente, há algum erro gravíssimo na sua modelagem. A idéia está cheirando mal.[/quote]

Ali ficou gambi, mas seria passada pelo atributo $nm (nome do atributo), e o valor que irá receber $vl…

Da uma olhada aqui… http://br2.php.net/manual/pt_BR/language.oop5.overloading.php

Ali fiz gambi, o certo era fazer ali, mas fiz só para exemplificar

[quote=fantomas]Se entendi bem o que vc quer, a única coisa que chega perto disso é a reflexão (reflection); onde vc pode alterar atributos e executar metodos de um objeto de forma dinamica.

Dá uma lida no assunto e vê se te atende.

flws
[/quote]

Vou dar uma bizu nisso! :slight_smile:

ViniGodoy aqui está agora certo a parada… usar dessa forma, mas só estes metodos na classe pai…

[code]class Teste
{

private $a = "";
private $b = "";

public function __set($nm, $vl){
	if( isset($this->$nm) ) {
		$this->$nm = $vl;
	} else {
		trigger_error("O atributo \"$$nm\" não existe.", E_USER_NOTICE);
	}
}

public function __get($nm){
	if( isset($this->$nm) ) {
		return $this->$nm;
	} else {
		trigger_error("O atributo \"$$nm\" não existe.", E_USER_NOTICE);
	}
}

}

$teste = new Teste;
$teste->a = “Valor”;
$teste->b = “Outro”;
$teste->outroAtributo = “Aqui vai gerar erro, pois não existe”;
echo $teste->a;
echo $teste->b;
echo $teste->outroAtributo // Aqui vai gerar erro, pois não existe[/code]

[quote=thiagofesta]Seria algo assim…

Tenho uma classe chamada ModelBean() (a qual seria a pai)

Que é algo assim:

[code]public class ModelBean {
public void setAlgo(int algo) {
// SETA SEMPRE O ATRIBUTO DA CLASSE FILHO,
// SEM PRECISAR CRIAR DENOVO NA CLASSE FILHO
}
}

public class TesteBean extends ModelBean {
public int algo;

// Faço na classe pai, para mim não fazer em todos os meus beans...

}

//ai fica simples assim:

new TesteBean().setAlgo(123);[/code]

Pois bem, parece meio sem noção no inicio, mas pode ser que você imaginem outra forma…[/quote]

Repare que setalgo está sendo invocado em TestaBean. Isso significa que vc precisa colocar a logica em TestaBean


public class ModelBean {
    public void setAlgo(int algo) {
        // faz o que quiser, não importa 
    }
}

public class TesteBean extends ModelBean {
    private int algo; // privado 

   // sobreescreve o metodo para alterar o comportamento
   public void setAlgo(int algo) {
        super.fazAlgo(algo); // faz o que uma classe desta deve fazer normalmente
        this.algo = algo; // faz alguma logica suplementar 
    }
}

Isto é um exemplo do uso de polimorfismo. O seu método “setAlgo” é polimorfico

sergiotaborda:
Isso eu sei hehe…
Mas como disse nos outros tópicos…
Andei dando uma lida, e achei uma parada chamada de Late Static Bindings… acho que isso resolve meu problema

[size=18]Late Binding[/size]

Normalmente quando um programa é escrito em uma linguagem não orientada a objetos, a chamados dos métodos(function e procedures) é determinada exatamente pela tipo da variável, em Java isto não é verdade, por que a invocação é determinado pela classe do Objeto, também conhecido como Late Binding . No código abaixo comprova o que digo na chamado do método p.mudaIdade().

[code]
class Pessoa extends Object{
private String nome;
static int idade = 40;

public void aMethod(String nome){
    this.nome = nome; 
}
public void mudaIdade(int i){
    this.idade = i;
}

}

class Funcionario extends Pessoa{
static int idade = 20;

public void mudaIdade(int i){
    this.idade = i;
    System.out.println("Funcionario");
}

}

public class LateBinding{
public static void main(String[] args){
Pessoa p = new Funcionario();
/* aqui a JVM irá chamar o método sobrescito de Funcionário, apesar do objeto ter sido declarado como do tipo Pessoa *
p.mudaIdade(15);
System.out.println(p.idade);
System.out.println(Funcionario.idade);
System.out.println(Pessoa.idade);
}
}[/code]
Observe que foi declarado um objeto da classe Pessoa p, no entanto foi instanciando um Funcionário que é uma Pessoa, isto é válido na OOP, por que um Parent(Pai) pode comportar-se como um Child (Filho), acessando somente o que ele conhecesse.A possibilidade de redefinição de variáveis e métodos sem subclasses, em conjunto com a posssibilidade de associação dinâmica de nomes a métodos, constitui uma característica fundamental, talvez a mais distinta da programação orientada a objetos (OOP). Em outras palavras o método a ser executado, é determinado dinamicamente, conforme o tipo do objeto armazenado em “p”. O mecanismo de assossiação evita que a cada chamada de métodos da classe Pessoa, seja necessário tratar o tipo do objeto alvo, para que o método adequado possa ser chamado. Como conseqüência, o programa se torna mais claro e conciso, e mais fácil de ser modificado.É comum dizer, em programação que esse trecho de código apresenta uma boa reusabilidade.
Referência: Heller Philip , Simon Roberto - Complete Java 2 Certification Study Guide