Right now, I am learning OOP, mainly in c#. I am interested in what are the main reasons to make a class that can't be instantiated. What would be the correct example of when to make an abstract class? I found myself using the abstract class in inheritance way too enthusiastically. Are there some rules when class is abstract in system and when class should not be abstract? For instance, I made doctor and patient classes which are similar in some way so I derived them both from abstract class Person (since both have name and surname). Was that wrong? Sorry if the question is stupid, I am very new at this.
相关问题
- how to define constructor for Python's new Nam
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- Keeping track of variable instances
Incidentally, another issue which hasn't yet been mentioned is that it is possible to add members to an abstract class, have existing implementations automatically support them, and allow consumers to use implementations which know about the new members and implementations which don't, interchangeably. While there are some plausible mechanisms by which a future .NET runtime could allow interfaces to work that way as well, at present they do not.
For example, if IEnumerable had been an abstract class (there are of course good many reasons why it isn't), something like a
Count
method could have been added when its usefulness became apparent; its default implementation ofCount
could behave much like theIEnumerable<T>.Count
extension method, but implementations which knew about the new method could implement it more efficiently (althoughIEnumerable<T>.Count
will try to take advantage of implementations ofICollection<T>.Count
orICollection.Count
, it first has to determine whether they exist; by contrast, any override would know that it has code to handleCount
directly).It would have been possible to add an
ICountableEnumerable<T>
interface which inherited fromIEnumerable<T>
but includedCount
, and existing code would continue to work just fine withIEnumerable<T>
as it always had, but any time anICountableEnumerable<T>
was passed through existing code, the recipient would have to recast it toICountableEnumerable<T>
to use theCount
method. Far less convenient than having a directly-dispatchedCount
method which could simply act directly onIEnumerable<T>
[theCount
extension method isn't horrible, but it's far less efficient than would be a directly-dispatched virtual method].If there were a means by which an interface could include static methods, and if the class loader, upon finding that a class
Boz
which claimed to implementIFoo
, was missing methodstring IFoo.Bar(int)
, would automatically add to that class:[assuming the interface contains that static method], then it would be possible to have interfaces add members without breaking existing implementations, provided that they also included static methods that could be called by default implementations. Unfortunately, I know of no plans to add any such functionality.
There are a couple of things no one has pointed out so far, so I would just like to point them out.
You can only inherit from one base class (which could be abstract) but you can implement many interfaces. So in this sense inheriting an abstract class is a closer relationship than implementing an interface.
So if you later on realize that you have a need for a class which implements two different abstract classes you are in deep shit :)
To answer your question "when to make an abstract class" I'd say never, avoid it if possible, it will never pay off in the long run, if the main class is not suitable as a ordinary class, it probably isn't really needed as abstract either, use an interface. If you ever get in the situation where you are duplicating code it might be suitable with an abstract class, but always have a look at interfaces and behavioral patterns first (ex the strategy pattern solves a lot of issues people wrongly use inheritance to solve, always prefer composition over inheritance). Use abstract classes as a last hand solution, not as a design.
To get a better understanding of OOP in general, I'd recommend you to have a look at Design Patterns: Elements of Reusable Object-Oriented Software (a book) which gives a good overview of OO-design and reusability of OO-components. OO-design is about so much more than inheritance :)