lorena85 1 Denunciar post Postado Setembro 19, 2013 Ola galera, tudo bem? Já li vários e vários artigos de blogs e de fóruns também, abordando este assunto sobre class Abstract E tive uma conclusão: Na nossa Língua Portuguesa substantivo abstrato é quando se refere a algo imaginário, sentimental, que não pode ser tocado nem se pode formar uma imagem representativa. E na programação orientado a objeto quando falamos sobre a classes abstratas seria algo semelhante aos substantivos abstratos da linguá portuguesa. veja um exemplo abaixo Eletrodoméstico: Existe para classificar todos os tipo de equipamentos eletrônicos domésticos, mas não podemos pegar ou ver Eletrodoméstico Televisão : É um sistema eletrônico de reprodução de imagens e som de forma instantânea. que pode ser visto é pegar No caso acima eletrodoméstico seria a classe abstract e a classe televisão seria a classe filha de eletrodoméstico. Então podemos dizer que: em nosso mundo real, só existem objetos. As classes são abstratas, servem para classificar grupos de objetos. Por favor me corrijam, caso eu falei alguma balela tá! Desde já, obrigada! Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Setembro 19, 2013 É uma analogia bem interessante e apropriada. Igual já levantaram por aqui [inline]fruta[/inline] >> [inline]laranja[/inline] Acho que a maior dificuldade na implementação prática é saber diferenciar o que deve ir numa interface e quando você realmente precisa de uma classe abstrata. Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 Existe para classificar todos os tipo de equipamentos eletrônicos domésticos, mas não podemos pegar ou ver Eletrodoméstico No caso acima eletrodoméstico seria a classe abstract e a classe televisão seria a classe filha de eletrodoméstico. Agora, e para aplicar o conceito? Teoria no mundo da programação é uma coisa e "codar" é outra, mas você está indo bem. Na prática não é apenas classes "Abstratas" e classes "Concretas", é necessário que conheça os padrões de design e os princípios da programação orientada a objetos. Se não cuidar, vai acabar escrevendo uma classe "Concreta Televisão" que liga o dvd, isso seria uma fuga dos princípios. Você notou que quando uma TV tem seu botão de ligar estragado pelas crianças, agente leva no técnico, ele troca o botão e olha, não precisou mexer na TV por completo! Isto também é abstrato e não apenas "eletrodoméstico". Compartilhar este post Link para o post Compartilhar em outros sites
hinom 5 Denunciar post Postado Setembro 19, 2013 Isso quer dizer que isto também é abstrato e não apenas "eletrodoméstico". sim.. paradigma... Compartilhar este post Link para o post Compartilhar em outros sites
lorena85 1 Denunciar post Postado Setembro 19, 2013 Então tudo tem a sua hora e lugar certo de se colocar! é isso?? Você notou que quando uma TV tem seu botão de ligar estragado pelas crianças, agente leva no técnico, ele troca o botão e olha, não precisou mexer na TV por completo! Isso quer dizer que isto também é abstrato e não apenas "eletrodoméstico". Neste exemplo que a "TV" seria uma classe abstrata?? não entendi muito bem Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 Então tudo tem a sua hora e lugar certo de se colocar! é isso?? Neste exemplo que a "TV" seria uma classe abstrata?? não entendi muito bem Colocar a tv como classe abstrata seria jogar M. no ventilador, não, abstrato são os componentes, "abstração" é não deixar a TV conhecer o botão, a antena e outros. Tinha mais partes do corpo, mas a imagem ficaria com muitos KiloBytes se eu marcasse todas. Compartilhar este post Link para o post Compartilhar em outros sites
João Batista Neto 448 Denunciar post Postado Setembro 19, 2013 Leia na seguinte ordem: 1 - Abstração - http://thegodclass.tumblr.com/post/9665624509/abstracao 2 - Encapsulação - http://thegodclass.tumblr.com/post/9704477531/encapsulacao Compartilhar este post Link para o post Compartilhar em outros sites
lorena85 1 Denunciar post Postado Setembro 19, 2013 @Mystic com o exemplo da imagem que você me passou, tive o seguinte entendimento * Olho é abstrato, pois um olho ruim pode ser trocado por um olho de vidro * Coração é abstrato pois um coração ruim pode ser trocado por um coração bom * Figado é abstrato pois um figado ruim pode ser trocado por um figado bom * Pescoço é concreto, pois é impossível de trocar um pescoço por outro pescoço * Corpo é concreto, pois é a base de todos os nossos órgão, é impossível trocar o nosso corpo por outro corpo Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 Como eu disse antes, na teoria tudo é muito lindo, a aplicação é um pouco mais complexa. <?php interface CorDoOlho { /* abstract */ public function cor(); } /** * A pessoa é abstrata, pode ser qualquer um */ abstract class Pessoa /* ? */ { private $nome = null; private $atributos = array(); public function __construct($nome = 'Fulano') { $this->nome = $nome; } public function nome() { return $this->nome; } public function adicionarUmAtributo($nomeDoAtributo, $valor) { $this->atributos[$nomeDoAtributo] = $valor; } public function atributo($nomeDoAtributo) { return $this->atributos[$nomeDoAtributo]; } } /* * A cor é abstrata, mas o atributo cor não, ou seja a cor do olho da pessoa é genético */ class AtributoCor extends Pessoa implements CorDoOlho { public function cor() { print $this->nome() . ' possui olhos na cor ' . $this->atributo('cor dos olhos'); } } $pessoa = 'Lorena Ribeiro'; $olhoHumano = new AtributoCor($pessoa); $olhoHumano->adicionarUmAtributo('cor dos olhos', 'Verde'); $olhoHumano->cor(); // Vai imprimir: Lorena Ribeiro possui olhos na cor Verde Compartilhar este post Link para o post Compartilhar em outros sites
cristianoolv 93 Denunciar post Postado Setembro 19, 2013 kiss Compartilhar este post Link para o post Compartilhar em outros sites
Enrico Pereira 299 Denunciar post Postado Setembro 19, 2013 Herança é um relacionamento é um. Quando você diz que class X extends Y, você diz que X é um Y. class AtributoCor extends Pessoa implements CorDoOlho AtributoCor é uma Pessoa? Não, logo o uso de herança é errado nesse caso. Liskov Substitution Principle. Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 AtributoCor é uma Pessoa? Não, logo o uso de herança é errado nesse caso. Liskov Substitution Principle. Amigo, não complica a cabeça da Moça, não vou responder questionamentos que não sejam feitos por ela, se você quer ajudar, reponda para ela e não para mim. Imagine uma biblioteca, você vai compor os membros ou vai usar erroneamente class biblioteca extends part É possível pegarmos um olho na mão sem a pessoa, ou retirar de uma pessoa morta, mesmo sem isso, a cor do olho da pessoa é sempre concreto, ou você quer usar class Pessoa extends AtributoCor violando The Dependency Inversion Principle É para isso que existe Adapter Assim, tenho a liberdade de compor os membros da pessoa célula por célula. Compartilhar este post Link para o post Compartilhar em outros sites
cristianoolv 93 Denunciar post Postado Setembro 19, 2013 É possível pegarmos um olho na mão sem a pessoa, ou retirar de uma pessoa morta, mesmo sem isso, a cor do olho da pessoa é sempre concreto No caso a cor do olho deveria se um simples atributo, e não uma classe sem o menor sentido de existir. Existe para classificar todos os tipo de equipamentos eletrônicos domésticos, mas não podemos pegar ou ver Eletrodoméstico ~Podemos sim, ou voce nunca viu um liquidificador ? Acho que voce quiz dizer que tem um tal coisa é eletrodomentico mais eu não posso fazer um suco com tal coisa, já que eu não sei o que tal coisa faz, se for isso que quiz dizer, estara no caminho certo.Quanto a isso de olho que estão dizendo ai encima, simplismente ignore, não tem nada haver com classes abstratas. Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 @Enrico AtributoCor é uma Pessoa? Não, logo o uso de herança é errado nesse caso. É possível pegarmos um olho na mão sem a pessoa, ou retirar de uma pessoa morta, mesmo sem isso, a cor do olho da pessoa é sempre concreto, ou você quer usar class Pessoa extends AtributoCor violando The Dependency Inversion Principle O que você queria dizer era: <?php class LorenaRibeiro extends Pessoa { } No caso a cor do olho deveria se um simples atributo, e não uma classe sem o menor sentido de existir. Já está usando o verbo ditatorial dever? É uma democracia de opiniões ou você diz o certo e eu fico quieto? Amigo, cor(Abstrato) é uma coisa, "a cor do olho"(Concreto) é outra coisa. :closedeyes: Compartilhar este post Link para o post Compartilhar em outros sites
Evandro Oliveira 331 Denunciar post Postado Setembro 19, 2013 Agora, e para aplicar o conceito? Teoria no mundo da programação é uma coisa e "codar" é outra, mas você está indo bem. Na prática não é apenas classes "Abstratas" e classes "Concretas", é necessário que conheça os padrões de design e os princípios da programação orientada a objetos. Se não cuidar, vai acabar escrevendo uma classe "Concreta Televisão" que liga o dvd, isso seria uma fuga dos princípios. Você notou que quando uma TV tem seu botão de ligar estragado pelas crianças, agente leva no técnico, ele troca o botão e olha, não precisou mexer na TV por completo! Isto também é abstrato e não apenas "eletrodoméstico". Amigo, acho que voce está confundindo termos. Não apenas por este post, mas pela sequência deles, acredito que você esteja assumindo que - tudo que possa ser "trocado" é abstrato. E é bem o contrário. Voltando rapidamente à ilustração do corpo humano, é exatamente pelo fato de corações serem concretos que eles podem ser trocados. Componentes abstratos não podem ser instanciados. Se não houvesse construção de corações, não haveriam troca deles. O nome do conceito que tange intercambiamento - existe isso? - de componentes se chama, por motivos óbvios, composição. Olhos, coração, pulmões, rins, e etc compõem um corpo humano. Voltando ao exemplo da TV, o botão faz parte da TV, ele a compõe. É um componente dela. E pelo fato dele existir, quer dizer que ele foi construído/instanciado, fazendo-se assim, um elemento concreto. Então tudo tem a sua hora e lugar certo de se colocar! é isso?? Neste exemplo que a "TV" seria uma classe abstrata?? não entendi muito bem Nao, TV é concreto. Compartilhar este post Link para o post Compartilhar em outros sites
Enrico Pereira 299 Denunciar post Postado Setembro 19, 2013 Mystic, não há uma "ditadura". O grande ponto é que a orientação a objetos é um dos paradigmas de programação mais maduros que existem nos dias de hoje. Em consequência, há princípios, padrões e conceitos definidos. O ponto é que um atributo cor não é uma pessoa, logo AtributoCor não pode estender de Pessoa. Um exemplo prático de como isso é prejudicial, além da semântica, é claro: <?php // Deveria ser uma interface, mas coloquei uma classe abstrata // para que o contexto do tópico seja mantido abstract class Nutriment { abstract public function getName(); } class Banana extends Nutriment { public function getName() { return 'Banana'; } } class Pasta extends Nutriment { public function getName() { return 'Massa'; } } class Olive extends Nutriment { public function getName() { return 'Azeitona'; } } class Bomb extends Nutriment { public function getName() { return 'Bomba'; } } class Stomach { public function eat(Nutriment $nutriment) { echo 'Estou comendo uma ' . $nutriment->getName() . PHP_EOL; } } $stomach = new Stomach(); $stomach->eat(new Banana()); $stomach->eat(new Pasta()); $stomach->eat(new Olive()); $stomach->eat(new Bomb()); E o output foi: Estou comendo uma Banana Estou comendo uma Massa Estou comendo uma Azeitona Estou comendo uma Bomba A classe de estômago come algum alimento, que deve estender a classe de alimento. Banana, massa e azeitona estendem corretamente a classe de alimento, uma vez que elas são alimentos. Porém, a classe bomba estende de forma equivocada a classe alimento, uma vez que uma bomba não é um alimento. Com isso, podemos simplesmente fazer uma estupidez, como visto acima. Um exemplo corriqueiro do mundo real é classe de Usuário estendendo classe de banco de dados ou as famigeradas "models". Portanto, antes de usar herança, deve-se analisar se o tipo "é um", que a herança define, faz sentido. Exemplos: - Cassandra pode estender DataStorage, já que Cassandra é um DataStorage. - Apache pode estender Server, já que Apache é um Server. - App não deve estender Database, já que uma App não é um Database. E um exemplo mais complexo sobre o LSP, é o um quadrado não é um retângulo. O Adapter serve para fazer uma interface compatível para uma outra ferramenta, o propósito dele não é deixar você fazer um mau design e depois corrigí-lo. Um exemplo: você deseja usar um conector de Oracle com a Zend\Db. Supondo que a Zend\Db não tem um conector para Oracle, mas o Doctrine tem, porém a interface de conectores é imcompatível. A partir daí, você pode criar um adapter para tornar o conector de Oracle do Doctrine compatível com o Zend\Db. --- Voltando ao tópico, o desentendimento vem da falsa ideia que abstração significa classe abstrata. Apesar dos nomes serem bem similares, abstração não significa classes abstratas. Abstração nada mais é do que poder executar uma operação sem saber dos detalhes dos elementos, criando uma flexibilidade. Um exemplo prático da falta de abstração, gerando o acoplamento: <?php class Logger { private $file; public function __construct($file) { $this->file = $file; } public function emergency($message) { file_put_contents($this->file, '[EMERGENCY] ' . $message, FILE_APPEND); } public function alert($message) { file_put_contents($this->file, '[ALERT] ' . $message, FILE_APPEND); } public function critical($message) { file_put_contents($this->file, '[CRITICAL] ' . $message, FILE_APPEND); } public function error($message) { file_put_contents($this->file, '[ERROR] ' . $message, FILE_APPEND); } public function warning($message) { file_put_contents($this->file, '[WARNING] ' . $message, FILE_APPEND); } public function notice($message) { file_put_contents($this->file, '[NOTICE] ' . $message, FILE_APPEND); } public function info($message) { file_put_contents($this->file, '[INFO] ' . $message, FILE_APPEND); } public function debug($message) { file_put_contents($this->file, '[DEBUG] ' . $message, FILE_APPEND); } } class SignUp { private $logger; public function __construct() { $this->logger = new Logger(__DIR__ . '/logs.txt'); } public function showPage() { $this->logger->info('Um usuário abriu a página de cadastro.'); } public function register() { $this->logger->info('Um usuário se cadastrou no sistema'); } } $signUp = new SignUp(); $signUp->showPage(); $signUp->register(); Nesse caso, o sistema de log está muito acoplado, diminuindo a flexibilidade. Caso quiséssemos passar a fazer os logs através de email, por exemplo, teríamos que reescrever toda a classe Logger, adaptando-a para fazer os logs através de email. Em resumo, há uma explícita violação do OCP e o código é pouco reutilizável. Maaasss, se abstrairmos o código o cenário muda: <?php interface LoggerStorage { public function log($message); } class Logger { private $storage; public function __construct(LoggerStorage $storage) { $this->storage = $storage; } public function emergency($message) { $this->storage->log('[EMERGENCY] ' . $message); } public function alert($message) { $this->storage->log('[ALERT] ' . $message); } public function critical($message) { $this->storage->log('[CRITICAL] ' . $message); } public function error($message) { $this->storage->log('[ERROR] ' . $message); } public function warning($message) { $this->storage->log('[WARNING] ' . $message); } public function notice($message) { $this->storage->log('[NOTICE] ' . $message); } public function info($message) { $this->storage->log('[INFO] ' . $message); } public function debug($message) { $this->storage->log('[DEBUG] ' . $message); } } class SignUp { private $logger; public function __construct(Logger) { $this->logger = $logger; } public function showPage() { $this->logger->info('Um usuário abriu a página de cadastro.'); } public function register() { $this->logger->info('Um usuário se cadastrou no sistema'); } } E o sistema agora ficou abstrato. Com isso podemos ter a flexibilidade de escolher com o que faremos o log, sem alterar o sistema em nada: <?php class FileLoggerStorage implements LoggerStorage { private $file; public function __construct($file) { $this->file = $file; } public function log($message) { file_put_contents($this->file, $message, FILE_APPEND); } } class DebugLoggerStorage implements LoggerStorage { public function log($message) { echo $message . PHP_EOL; } } $loggerStorage = new DebugLoggerStorage(); // Aqui poderíamos usar qualquer storage, ou seja, não estamos dependentes de como o log será salvo \o/ $logger = new Logger($loggerStorage); $signUp = new SignUp($logger); $signUp->showPage(); $signUp->register(); Espero que tenha entendido o conceito ;). Compartilhar este post Link para o post Compartilhar em outros sites
Mystic 4 Denunciar post Postado Setembro 19, 2013 Voltando ao exemplo da TV, o botão faz parte da TV, ele a compõe. É um componente dela. E pelo fato dele existir, quer dizer que ele foi construído/instanciado, fazendo-se assim, um elemento concreto. Pronto, cada hora um "professor" diferente, você leu o que eu disse sobre abstração. Não é o que eu posso trocar e sim não deixar a TV conhecer o botão, ele deve ser desacoplado dela, como a própria fabricação não me deixa mentir, a TV depende deste botão para ligar, ou ela pode ser ligada com controle remoto? Você disse que TV é concreto, é claro que sim, está apenas repetindo o que eu disse. @Enrico Pereira um ser humano que usa um completo, desculpe, lixo desses, eu sei que você está apenas dando um exemplo do errado, só não me diga que você está querendo comparar aquilo (classe Logger) com o exemplo que dei. Pensa com calma nas coisas que posto e não fica querendo me fazer passar por uma prova de fogo só porque sou calouro no fórum, se você ler com calma e me responder com o seu ponto de vista, vai ter de mim um diálogo super claro. Ao invés de você falar, "poxa! Bacana, excelentes exemplos você postou, agora deixa eu lhe mostrar algo que não concordo", não, você simplesmente joga todo o balde de leite fora, desmerecendo tudo que escrevi, e outra coisa, eu estava dentro do escritório trabalhando igual um condenado e mesmo assim estava tentando ajudar, se atropelei qualquer coisa, é por eu não estava na piscina sentado ao sol com um notebook na mão. Eu te pergunto: Você está aqui para aprender ou para ensinar? Eu estou aqui para aprender! E sabe o que descubro cada hora da minha vida? Que eu não sei nada, mas já avancei quilômetros do nível que estava ontem. Tu é chato pá carai, kkk :yes:, estou brincando, bom começo de noite para você. Depois agente conversa mais, to cansado. Compartilhar este post Link para o post Compartilhar em outros sites
Enrico Pereira 299 Denunciar post Postado Setembro 19, 2013 Moderators, moderators, moderators..... Eu só quis explicar o porquê do problema de class AtributoCor extends Pessoa, sem desmerecer nada. Estou aqui para discutir apenas... O logger foi para mostrar que abstração != classe abstrata e não para o seu ponto de LSP. Compartilhar este post Link para o post Compartilhar em outros sites
lorena85 1 Denunciar post Postado Setembro 19, 2013 Agradeço a força de vocês. Só para reforçar um pouco mais o meu intendimento no assunto! exemplificando tudo, vou citar alguns exemplos, e queria que vocês me dissesse se está correto ou não e por que, tá bom? 1) Eu tinha falado no post anterior veja: podemos dizer que: em nosso mundo real, só existem objetos. As classes são abstratas, servem para classificar grupos de objetos. Essa minha afirmação está correta?? 2) Eletrodoméstico não pode ser instanciada, por que não existe um objeto Eletrodoméstico "em sim" sendo assim uma class abstract. Agora televisão pode ser instanciado pois é um objeto concreto de Eletrodoméstico, correto?? 3) Fruta não pode ser instanciada por que não existe um objeto fruta "em sim" sendo assim uma class abstract. Agora posso instanciar laranja que é um objeto concreto de fruta, correto?? Compartilhar este post Link para o post Compartilhar em outros sites
Cristianoferr 32 Denunciar post Postado Setembro 19, 2013 Não procede. Eu posso criar uma classe e setar o nome dela para "Laranja", sem precisar especificar uma classe Laranja. Também posso especificar uma classe Pessoa e instanciar para cada pessoa que eu quiser. Classes abstratas eu entendo como super-classes que não podem ser instanciadas por serem genéricas demais. Eu posso classificar "Fruta" como estendendo a superclasse "Alimento" e defino essa classe como abstrata mas com propriedades comuns a todos os seus sub-tipos. Ou seja, abstração depende do problema sendo tratado. Dependendo do cenário, "Laranja" pode ser algo abstrato, já que não especifica a variedade e procedência da Laranja. Coisa que para um produtor de laranjas seria algo muito importante. Acho que a confusão é achar que "Classes" são abstratas. Eu vejo classe mais como se fosse um "molde", que pode ser usado para criar inúmeros objetos "sólidos". Compartilhar este post Link para o post Compartilhar em outros sites