Atualmente, tenho duas classes derivadas, A
e B
ambas têm um campo em comum e estou tentando determinar se deve subir na classe base.
Ela nunca é referenciada a partir da classe base e diz que, em algum momento no caminho, outra classe é derivada, C
que não possui um _field1
, então o principal dos "menos privilegiados" (ou algo) não seria violado se foi?
public abstract class Base
{
// Should _field1 be brought up to Base?
//protected int Field1 { get; set; }
}
public class A : Base
{
private int _field1;
}
public class B : Base
{
private int _field1;
}
public class C : Base
{
// Doesn't have/reference _field1
}
Base
,A
,B
,C
, e_field1
são. Esses são detalhes importantes que não devem ser deixados de fora; Eu acho que você deve editar a pergunta para falar sobre o que são.Respostas:
Tudo depende do problema exato que você está tentando resolver.
Considere um exemplo concreto: sua classe base abstrata é
Vehicle
e você tem atualmente as implementações concretasBicycle
eCar
. Você está pensando em mudarnumberOfWheels
deBicycle
eCar
para veículo. Você deveria fazer isso? Não! Porque nem todos os veículos têm rodas. Você já pode dizer que, se tentar adicionar umaBoat
classe, ela será interrompida.Agora, se sua classe base abstrata era
WheeledVehicle
, é lógico ter anumberOfWheels
variável membro lá.Você precisa aplicar a mesma lógica ao seu problema, porque, como você pode ver, não é uma resposta simples, sim ou não.
fonte
roll()
método, no ponto em que a ideia da subclasse parece presciente.Logicamente falando, além de colocar o campo replicado nas subclasses vs. em comum na classe base, existe uma terceira opção: introduzir uma nova subclasse na hierarquia que possua as propriedades comuns entre as duas. @ Peter sugere isso sem ir totalmente para lá.
Usando o exemplo de @ Pete, introduziríamos uma subclasse (possivelmente abstrata) para Veículo com Rodas que desce da classe base original - enquanto as duas subclasses descem dela. Assim, a classe base original não é poluída com rodas, mas a semelhança entre as rodas é SECA (não repetida entre as subclasses que possuem rodas).
Obviamente, isso pode ser um exagero para seus propósitos, mas isso é suportado pelo mecanismo de hierarquia de classes.
fonte
Vou bancar o advogado do diabo aqui.
Agora você não deve fazer nada .
É SECO? Não. Mas é melhor ter uma pequena duplicação do que uma abstração prematura da qual você não pode desistir facilmente mais tarde. O refator para mover uma propriedade para uma classe base comum é fácil. Indo para o outro lado não é. Espere e veja.
Ao tomar esse tipo de decisão, costumo usar uma "regra de 3": depois de repetir a mesma coisa em, por exemplo, três lugares diferentes, e só então, considero movê-la pela cadeia. NB você está apenas em 2.
fonte
Em geral, eu o moveria para a classe base. Não acho que exista um objetivo sim / não, porque há uma troca aqui - transportar campos não utilizados versus reduzir a complexidade.
Normalmente, prefiro classes base 'pesadas' que contêm qualquer coisa que possa ser compartilhada. Isso simplifica a serialização de arquivos, pois você não precisa de métodos de serialização descendentes em todas as classes derivadas. Mas se você não tiver esse problema ou um problema semelhante, ou talvez precise fazer tudo o que puder para reduzir o uso de memória, apenas os campos em que você precisa devem ficar bem.
Uma classe 'intermediária' que introduz os campos comuns será boa se você tiver um número muito limitado de campos. Mas esteja ciente de que a abordagem pode aumentar drasticamente a complexidade se você tiver dezenas de campos usados em combinações diferentes, levando a muitas classes intermediárias, cada uma introduzindo um conjunto específico de campos. Isso pode se tornar um problema de manutenção.
fonte