• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Nazgulled

OOP: Será que é possível fazer isto? Como?

15 mensagens neste tópico

Será que isto é possível? Dentro da class B, definir algum conteúdo na variável $txt da class A e depois fazer um echo da mesma dentro da própria classe A.

class A {
public $B;
public $txt;

public function __construct() {
	$this->B = new B();
	echo $this->txt; // Será este echo() possível com a definição de conteúdo em B()?
}
}

class B {
public function __construct() {
	// Como posso aceder aqui dentro a variavel $txt
	// declarada na classe A?
}
}

new A();

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim é possível...

<?php

class A extends B {
        public $txt;

        public function __construct() {

                parent::__construct();

                echo $this->txt;
        }
}

class B {
        public function __construct() {
                $this->txt = 'qualquer coisa';
        }
}

new A();

?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois... não a solução que eu estava a procura, deveria ter explicado melhor.

Precisava de uma solução sem "extends" e "global".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

então tens esta...

<?php

class A  {
        public $txt;

        public function __construct() {
                $B = new B( &$this );
                echo $this->txt;
        }
}

class B {
        public function __construct( $A ) {
                $A->txt = 'qualquer coisa';
        }
}

new A();

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sem extends não é OO :P

A solução será mesmo por composição, que foi o que kingless, quase, indicou. Para ser composição seria necessário que a classe B possuisse um atributo do tipo A.

Mas fiquei curioso, porque não queres usar extends?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

então tens esta...

<?php

class A  {
        public $txt;

        public function __construct() {
                $B = new B( &$this );
                echo $this->txt;
        }
}

class B {
        public function __construct( $A ) {
                $A->txt = 'qualquer coisa';
        }
}

new A();

Foi mais ou menos o que eu acabei por fazer e era algo que já tinha pensado, mas o que eu queria era mesmo algo diferente lol. Digamos que queria inventar um pouco para ter uma sintaxe bonita, mas o que eu queria, não existe :P, e essa é a única solução, não era bem o que queria, mas não tenho escolha. No entanto, não sei que versão do PHP estás a usar, mas na minha, não me permite passar por referência pelo que eu omiti o &. Podia definir isso no php.ini (segundo o warning), mas não quero, a maior parte dos servers não deve estar configurado assim, por isso, passo como valor que era o que tinha feito. E não estou a passar o $this, porque apesar de no exemplo mostrar ser isso que eu quero, não é bem, apenas queria algumas variáveis e não a classe toda. Mas valeu o esforço.

@Knitter

Porque neste exemplo eu tenho a classe A e B, mas no exemplo real, digamos que tenho a classe principal, A e depois uma série deles, B, C, D, etc... E o PHP não permite fazer "class A extends B extends C..." e eu preciso que a class A tenha certos objectos de outras classes importadas que sejam partilhados por outras classes. E fazer "class A extends B", "class B extends C", etc, apesar de não saber se funciona, nem se quer testei porque seria uma solução parva e o código ficava horrível.

E outra cosia, essa afirmação "sem extends não é OO", não tem sentido. Uma classe é um objecto, logo é OO, quer eu use extends ou não. O extends apenas me permite, como o próprio nome diz, estender uma classe com novos métodos e/ou propriedades. Não deixa de ser OO, desde que eu use classes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Então o teu problema era de herança multipla, ok, percebi, no entanto só conhecendo o caso real, ou pelo menos um com os mesmos problemas, poderia dar uma solução para o problema de herança multipla.

Quanto à parte de OO, estás usar objectos, tudo bem, mas OO não é definido pelo uso de POO, é definido pelo uso de Herança/Composição, Polimorfismo e Encapsulamento, e não estás a usar nenhum dos 3 principios de POO. Usas um objecto, mas estás a fazê-lo como se fosse um simples aglumerado de funções, por isso digo que não é POO, mas podes considerar isso apenas uma opinião :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Usas um objecto, mas estás a fazê-lo como se fosse um simples aglumerado de funções, por isso digo que não é POO, mas podes considerar isso apenas uma opinião :P

Não deixa de ser um objecto... e o código aqui representado, foi algo simples para definir o meu problema e ainda estou no inicio do que estou a fazer. Quem sabe se no futuro não vai ficar bastante diferente.

/djthyrax mode=on

*aglomerado

/djthyrax mode=off

(Firefox spell checker r0xs)

O problema em concreto é +- isto:

Tenho uma classe que é onde o programa começa e dentro dessa classe vou ter várias variáveis que vão representar determinados objectos, mas nenhum deles vai existir ao mesmo tempo que o outro, digamos que é mais ou menos como módulos onde só corre um de cada vez. O modulo a ser executado depende da acção do utilizador, login, logout, preferências, etc...

Tenho + duas classes à parte, template e xml, onde a primeira é a classe que eu publiquei na edição passada da revista e a de xml será algo para manipular ficheiros xml que ainda nem se quer comecei a fazer. Estes duas classes, serão usadas tanto pela classe base onde começa o programa, assim como cada um dos módulos. Ou seja, se eu estendesse a classe base e cada módulo à classe template, depois não ia puder estender a xml. Mas eu preciso das funções de ambas.

Poderia estender a classe base à template e depois a template à xml, mas isto é uma solução "parva" na minha opinião, e não a quero usar. E além do mais, template e xml, são 2 exemplos, mas quem sabe se não vou precisar de mais? Iria ficar um código bastante estúpido dessa forma.

Portanto, a única solução que eu vejo é mesmo a que já tinha pensado antes de criar este tópico, que foi a segunda opção apontada pelo kingless (passar os objectos definidos na classe base como argumentos para o construtor de cada um dos módulos, definir o valor passado numa variável privada para a class e usa-la lá-- é isto que eu tenho feito). Eu já tinha pensado nisto, mas criei na mesma este tópico porque estava mesmo à procura de uma solução diferente.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso é a explicação de como estás implementar, não a descrição do problema, não vou muito longe com isso :P

Mas se já tens uma solução, e achas que a solução serve, então força, dado que não tenho conhecimento do problema só estaria a complicar e poderia dar ideias erradas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Lol, não... o problema é mesmo o que eu descrevi. Eu descrevi o que que quero fazer. Não expliquei implementação nenhuma. Aliás, a implementação é só o último paragrafo, o resto é a descrição do que eu quero fazer.

Se calhar expliquei de forma confusa, mas não sei bem como explicar melhor... Basicamente tenho 2 classes que tem funções comuns usados em todo o lado (template, xml, no futuro poderão ser mais). Depois tenho mais diversas classes, onde cada uma delas representa a acção do utilizador, como já disse, login, logout, preferências, etc... Em cada uma dessas classes eu quero usar as funções existentes na classe template e xml. Logo, se não posso estender múltiplas classes, como faço? Ou seja, como é que a classe A pode "estender" métodos/propriedades da class B, C, D, etc... O problema é só esse. A única solução eu que vejo é a já descrita, mas se houver outra, gostava de saber.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usares interfaces não resolverá o teu problema? Em PHP5 uma classe pode implementar várias interfaces. Terias tipo uma interface para "template", uma para "xml", depois terias uma classe base que implementasse essas 2 interfaces, e depois cada módulo iria extender essa classe base... Não?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Usares interfaces não resolverá o teu problema? Em PHP5 uma classe pode implementar várias interfaces. Terias tipo uma interface para "template", uma para "xml", depois terias uma classe base que implementasse essas 2 interfaces, e depois cada módulo iria extender essa classe base... Não?

Podes dar-me um exemplo disso? o_O
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Qualquer coisa tipo isto:

interface ITemplate
{
//declaracao de metodos
}
interface IXML
{
//declaracao de metodos
}
class A implements ITemplate, IXML
{
//implementacao dos metodos
//isto seria a classe base
}
class B extends A
{
//metodos de especificos para cada modulo
}
class C extends A
{
//metodos de especificos para cada modulo
}
//and so on...

qualquer coisa assim deste género...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu sabia que o PHP tinha interfaces e já uso disso em C#/VB.NET mas nunca me dei ao trabalho de aprender em PHP, porque nunca entendi bem a sua utilidade. No entanto, nesse exemplo ha algo que me deixa confuso.

A class A, classe base, para alem de servir de "agregador" dos interfaces, para que poderia servir mais? E para que serve a class B e C? Para cada interface tenho de ter uma class? Fica um código + extenso assim e para que serve?

Acho melhor ler mais sobre isto...

EDIT:

Já tive a ler uns artigos sobre isto e não sei ser irá funcionar para o que eu quero... No exemplo acima:

1) A class A implementa o interface ITemplate e IXML depois dizes que a class B e a class C irão ser "estendidas" à class A, ou seja, todos os métodos em A vão poder ser usados em B e em C. Mas como ambos os interfaces estão implementados na class A e esta é "estendida" à class B e C, a declaração dos métodos em cada interface, vai existir tanto na class B e C. Porque estamos a "estender" a class A, uma class que implementa 2 (ou mais) interfaces.

2) Desta forma como poderia eu fazer modulos dinamicos? Ou seja, o utilizador escolhe apenas aqueles modulos que quer usar? Não vejo como isso seria possível sem editar o código manualmente e adicionar mais uma parâmetro ao "implements" para que passe a implementar um novo módulo. Ou será que me está a escapar alguma coisa?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Acho que não devias ter criado o outro tópico.. Deviamos continuar neste com os tópicos merged.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora