I just wanted you all to know that I did look in previous posts for this topic, but I never found what I was looking for design wise...
I was reading some stuff about the Factory Pattern and creating objects. I have this object... called school.
Well right now it is a class that other classes extend... HighSchool, MiddleSchool, PreSchool, etc...
We all schools have a principal, address, etc.. members. They all have the getters and setters to go along with those members. That tells me that I don't need a abstract class or an interface because 1) I want to be able to pass the School object around. I cannot do that if it is an abstract class. If the School object is an interface, I dont want to write a getPrincipal and setPrincipal for each subclass. But I do want certain methods that each subclass should provide the details for... Like enrollStudent method. What do I do in my SchoolClass? Create an empty enrollStudent? Now if I do that, I take a chance of someone not implementing their own enrollStudent method.
So far, nothing you have written convinces me that "high school" and "middle school" have to be distinct classes, versus being ordinary instances of a single School class. You given enrollStudent as an example of a method that sounds like you want to be abstract. Are you sure? I've enrolled kids in different schools and it's been the same procedure! Schools have different min and max ages or grade levels associated with them, but that can be accounted for without subclassing. Keep it simple!
To give an example: I was teaching a programming course and I let everyone write their own project. One student wanted to do a "dungeons and dragons" style game with heaps of characters: elves and trolls, etc... At first, he made them all different subclasses of GameCharacter. What's different, I asked? They had differerent images to render them. So let GameCharacter have-an image. They have different max values for things like strength and magic. So set those when you create an instance. In the end, there was no need for any subclass of GameCharacter.
So my question to you is (1) what code varies for these different schools and (2) what data varies? It may be the case this can be factored into a pattern like strategy (already methoded) which might minimize the subclassing effort. Or there may be no subclassing at all.
Also: when one has what looks like a hierarchy and is wondering if the base should be an abstract class or an interface, remember that you can do both, if need be: you could have a School interface and an AbstractSchool that implements it. Having a interface opens things up for many (advanced) techniques, like proxies, and having an abstract class lets you implement boilerplate code once and for all.