Using classes to add new types to a programming language is a very powerful technique that makes it easier (ideally simple) to write programs in domains the language does not natively support. It is perhaps the crowning achievement of object-oriented programming. However such achievements are not always easy to attain. To do it well requires close attention to the semantics of the situation you are modelling, especially where mutable types are used.