Por que as estruturas Windows Forms / Swing favorecem a herança em vez da Composition?


12

Hoje, um professor meu comentou que achou estranho que, embora a filosofia da SWT seja a de fazer seus próprios controles por composição, Swing parece favorecer a herança.

Quase não tenho contato com ambas as estruturas, mas pelo que me lembro no Windows Forms do C # geralmente se estende controles, assim como o Swing.

Sendo que geralmente as pessoas tendem a preferir composição a herança, por que o pessoal do Swing / Windows Forms não prefere composição ao invés de herança?


2
Muita coisa mudou nos 15-20 anos em que essas APIs existem! Motores de renderização não tem cola XML magia à tela ligam objetos contra instâncias de qualquer classe concreta arbitrária "de volta no dia";)

1
A maioria dos códigos Swing que eu vejo usa extensão por composição. Não tenho certeza de onde seu professor está recebendo os dados dele.

Eu mesmo já vi muito balanço na rede com herança em vez de composição - principalmente tutoriais. mas os formulários do Windows são realmente usados ​​com base quase exclusivamente em herança!
devorado elysium 25/05

Respostas:


7

JComponentexpõe muitas funcionalidades . Se JComponenthouvesse uma interface e componentes fossem implementados com composição, os componentes simples precisariam ter dezenas de invólucros de métodos triviais, por exemplo

class MyComponent implements JComponent {
    JPanel panel;
    public boolean contains(int x, int y) {
        return panel.contains(x, y);
    }
    ...
}

Há também um motivo de eficiência para preferir a herança à composição - substituir não custa nada (assumindo nenhuma superligação), enquanto a composição custa um extra INVOKEVIRTUAL. Não sei se isso influenciou o design do Swing, mas é uma grande preocupação para as classes de coleção.


2

O Swing Framework é realmente projetado de acordo com o Composite Design Pattern. Concedido que há muita herança lá, mas você normalmente compõe seus próprios formulários usando composição. Ou seja, um formulário é uma composição de contêineres e controles de nível intermediário.


"Ou seja, um formulário é uma composição de contêineres e controles de nível intermediário". Certo. Mas o que vejo normalmente é que quando as pessoas desejam criar sua própria janela (ou o que for chamado no Swing), elas herdarão de uma classe de janela em vez de usar a composição.
devorado elysium 25/05

Elysium devorado @ Isso é verdade. Mas, para criar a forma, eles usariam composição. Portanto, é um pouco de herança e muita composição.

@ devoured, acho que é um caso de pessoas que não percebem que o tutorial usado não segue as práticas recomendadas porque favorece a brevidade.
Peter Taylor

1

Com Java, é muito mais fácil acabar usando herança apenas porque tudo é virtual. Precisa corrigir um "recurso" no JTable / JFrame? Estenda-o, substitua os métodos do problema e use a Tabela / Quadro em qualquer lugar.

Eu acho que com coisas como o WPF, em que a ligação de dados é um recurso principal do design, facilita muito a composição, em vez da herança.


O que você quer dizer com "tudo é virtual "?
Jonas

em java, todo método é implicitamente virtual (pode ser substituído). No C #, você deve declarar explicitamente um método como virtuale, para substituí-lo, declara explicitamente como um override. Em Java, você pode substituir qualquer coisa que você pode ver, e você pode aumentar sua visibilidade em uma subclasse (você pode tornar os métodos protegidos público em uma subclasse!)
John Gardner

Observe que você não pode substituir um finalmétodo em Java, mesmo que a própria classe base não seja final.
2

isso é verdade @perp. mas em java você precisa se esforçar (adicionando final) para impedir o virtual. C # é o caminho oposto, você precisa se esforçar para ser virtual. E uma porcentagem muito pequena do tempo de execução padrão do java é marcada como final.
John Gardner

1

No Java Efetivo , Item 17, Bloch menciona que uma classe projetada para herança "deve documentar seu uso próprio de métodos substituíveis". Uma característica disso é a frase nesta implementação . Você verá isso em aulas como JTablee JInternalFrame. É uma medida de herança por design no Swing.


-2

A partir do C # 3.5, temos um conceito chamado de Métodos de extensão que permite o conceito de composição do que herança.

Nesse processo, implementamos uma funcionalidade estendida em uma classe existente apenas adicionando uma classe de extensão que renderiza o novo recurso à classe existente.

Você pode consultar aqui para mais detalhes


Não vejo a relevância de criar novas classes de controle WinForms. Você poderia elaborar?
Peter Peter

@ Peter: Isso não está relacionado apenas às classes de formulários do Windows. Isso também pode ser aplicado em nosso código. Você pode estender qualquer classe existente apenas adicionando uma classe estática e, em seguida, adicionando um novo método com o 1º argumento como esse, para que o objeto base possa ser vinculado. Depois de compilar o código, você obtém o método adicionado recentemente como um método da própria classe base. É isso que a composição afirma. espero que eu esteja certo ..
Saravanan

1
Eu sei o que são métodos de extensão, e eles são bastante úteis às vezes, mas essa pergunta é sobre diferentes abordagens para criar novas classes.
Peter Taylor

@ Peter: Então, só posso apontar para o uso de classes parciais, exceto para o meu entendimento C # não tem nenhum outro recurso notável. Se você souber de algum, entre em contato.
Saravanan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.