Consider the following designpublic class Person{    public virtual string Name { get; }    public Person (string name)    {        this.Name = name;    }}public class Karl : Person{    public override string Name    {        get        {            return Karl;        }    }}public class John : Person{    public override string Name    {        get        {            return John;        }    }}Do you think there is something wrong here? To me Karl and John classes should be just instances instead of classes as they are exactly the same as :Person karl = new Person(Karl);Person john = new Person(John);Why would I create new classes when instances are enough? The classes does not add anything to the instance.
Is creating subclasses for specific instances a bad practice?
programming practices;inheritance;class design;anti patterns
There is no need to have specific subclasses for every person.You're right, those should be instances instead.Goal of subclasses: to extend parent classesSubclasses are used to extend the functionality provided by the parent class. For example, you may have:A parent class Battery which can Power() something and can have a Voltage property,And a subclass RechargeableBattery, which can inherits Power() and Voltage, but can also be Recharge()d.Notice that you can pass an instance of RechargeableBattery class as a parameter to any method which accepts a Battery as an argument. This is called Liskov substitution principle, one of the five SOLID principles. Similarly, in real life, if my MP3 player accepts two AA batteries, I can substitute them by two rechargeable AA batteries.Note that it is sometimes difficult to determine whether you need to use a field or a subclass to represent a difference between something. For example, if you have to handle AA, AAA and 9-Volt batteries, would you create three subclasses or use an enum? Replace Subclass with Fields in Refactoring by Martin Fowler, page 232, may give you some ideas and how to move from one to another.In your example, Karl and John don't extend anything, nor do they provide any additional value: you can have the exactly same functionality using Person class directly. Having more lines of code with no additional value is never good. An example of a business caseWhat could possibly be a business case where it would actually make sense to create a subclass for a specific person?Let's say we build an application which manages persons working in a company. The application manages permissions too, so Helen, the accountant, cannot access SVN repository, but Thomas and Mary, two programmers, cannot access accounting-related documents.Jimmy, the big boss (founder and CEO of the company) have very specific privileges no one has. He can, for example, shut down the entire system, or fire a person. You get the idea.The poorest model for such application is to have classes such as:          because code duplication will arise very quickly. Even in the very basic example of four employees, you will duplicate code between Thomas and Mary classes. This will push you to create a common parent class Programmer. Since you may have multiple accountants as well, you will probably create Accountant class as well.          Now, you notice that having the class Helen is not very useful, as well as keeping Thomas and Mary: most of your code works at the upper level anywayat the level of accountants, programmers and Jimmy. The SVN server doesn't care if it's Thomas or Mary who needs to access the logit only needs to know whether it's a programmer or an accountant.if (person is Programmer){    this.AccessGranted = true;}So you end up removing the classes you don't use:          But I can keep Jimmy as-is, since there would always be only one CEO, one big bossJimmy, you think. Moreover, Jimmy is used a lot in your code, which actually looks more like this, and not as in the previous example:if (person is Jimmy){    this.GiveUnrestrictedAccess(); // Because Jimmy should do whatever he wants.}else if (person is Programmer){    this.AccessGranted = true;}The problem with that approach is that Jimmy can still be hit by a bus, and there would be a new CEO. Or the board of directors may decide that Mary is so great that she should be a new CEO, and Jimmy would be demoted to a position of a salesperson, so now, you need to walk through all your code and change everything.