Acquista un libro di software engineering.

Però non ti fossilizzare sull'uso del linguaggio C#, il linguaggio e' solo uno strumento, la progettazione OOP e' un argomento molto piu vasto.

Quando si usa in pratica l'ereditarietà?

Allora esempio scemo: in un anagrafica hai clienti e fornitori, sono sempre elementi anagrafici: ragione sociale eccetera, però col fornitore fai acquisti col cliente fai vendite , giusto?

allora crei una classe base anagrafico con metodi ragione sociale eccetera.

Poi crei due classi derivate CLiente e Fornitore, la prima col metodo Vendi(Prodotto p), e la seconda col metodo Acquista(Materiale m).

Ad un certo livello ti interessera' solo il numero di telefono e allora usi i metodi in comune della classe base, nel secondo caso ti interessera il metodo specifico.

Esempio:
hai una classe che visualizza i numeri di telefono di un anagrafico

Cliente Rossi = new Cliente("Rossi");
Rossi.Vendi(new Product("Automobile", 1)); //qua lo uso come cliente
Fornitore Bianchi = new Fornitore("Bianchi");
Bianchi.Acquista(new Product("Pneumatici", 4));

....

Visualizzatore.stampa(Rossi); //qua lo uso come anagrafico
Visualizzatore.stampa(Bianchi);

Non so se rendo l'idea
Ciao