One way to go about a multi-objective optimization problem like this is to find a solution that satisfies one objective, and then use local search to attempt to satisfy the remaining constraints.
For example, if you ignore the constraint that you would like to minimize the number of classes used, then you can treat this as a variant on the Stable Marriage Problem (or weighted bipartite graph matching problem) - this has the nice property that it can be solved in polynomial time. Your variant on the problem is most similar to the "hospitals/residents" problem (assigning many residents to a few hospitals based on preference).
This will leave you with several classes with only a few students in them, so you next perform a local search to satisfy the "minimize the number of classes" constraint (if you formulated the Stable Marriage algorithm correctly then you should have already satisfied the "no class exceeds 25 students" constraint) - from there you have two options:
Sort the classes from fewest to most students and close the classes with the fewest students, reassigning the evicted students to the remaining classes
Continue to take the students' preferences into account and sort the classes from least-preferred to most-preferred (so if you have 5 students in a class who assigned it a weight of 10 then you would first close a class with 10 students who assigned it a weight of 2).
You would then perform another local search to satisfy the teachers' hours constraints - you would perform the "teachers can't teach more than X hours" search after you perform the "minimize the number of classes" search, since the latter optimization will make it easier to perform the former optimization.
If the resulting algorithm is fast enough then you can randomize it and run it a few dozen times, saving the best result. For example, rather than closing the class with the fewest students first, randomly select a class to close (weight the selection so that it usually selects the smallest class - a completely random search won't perform well)
It's possible that you'll find that one of your constraints is causing a lot of conflicts, e.g. when satisfying the teachers' hours constraint you discover that you're having to rearrange a large percentage of the students. If this occurs then change the constraint ordering, so that satisfying the teachers' hours is done on the second or even the first pass rather than on the third pass.
The makeup-class-constraint might actually belong at the top of the constraint list (even though it's got a low priority), depending on its specifications. For example, you may have the requirement that the makeup class occur before any other class (so that e.g. a student with class on Tuesday can have the makeup class on Monday and get caught up prior to his regular class); even though the makeup class constraint has a low priority, it has the tightest requirements, and so it needs to get ordered first.