The problem I have with this model is that teacher & student are roles while person is a real entity. While this model will work in the short term, it will have problems if: a student becomes a teacher, or, if a teacher takes a course becoming a student (or also if a student graduates, and is no longer a student).
Student & Teacher are ephemeral roles (played by people) whereas Person is persistent entity.
Thus, an is-a relationship between Student and Person or between Teacher and Person is inappropriate.
Also, if I shouldn't use inheritance, should I use composition?
Yes, using composition will allow a Person's roles to come and go without having to create/destroy a new Person object. You just need to model that a Person object can have a relationships with role objects.
If the role captures extra information (e.g. Teacher of what subject/classes), having role objects refer to person objects might make sense, and if you need to quickly identify all the roles a person has, then as set of roles within the Person object also makes sense.
That model also captures Age which is a concept that is relative to now, which is constantly changing. This will also have problems over time — instead, capture a non-relative value like year born.
First of all, what does model domain mean?
A domain model has the purpose of being able to capture information in order to be able to later answer questions that you want to ask.
We model for the purpose of providing automation of some (usually highly repetitive) task in the domain. We are not trying to recreate the domain within the computer, but instead to automate some portion of the domain. Perhaps just record keeping, or perhaps automating some part of assigning classrooms to classes, teachers to classes, students to classes, timeslots to lectures. If just record keeping, still need to know what questions & answers you want those records to be able to give.
So, you want to identify what automation is intended, then identify what answers you want that to give, what decisions to make, then identify what questions to ask of the domain modeling, and what information has to be captured/modeled for these.
Then, we attempt to model just enough for that: don't over model for things that the automation won't help with (for example, we don't need a plethora of classes when objects and fields will do) and yet model sufficiently that the automation works properly.
We model so as to facilitate capturing information, so we can later ask (specific, known) questions of that information, get answers, and make decisions — all in support of some amount of the automatable portion of a domain. The overall automation design should determine what information to capture/model (and when and how), what questions to ask & when, what decisions to make & when.