Background: I am still a C# novice and this is my first big project with inheritance. The following story is a simplified example of my current situation:
Suppose I have a class called LivingOrganism. Every living creature can use this class as base and inherit the functionality that is common to all living organisms.
When I was working on some of these derived classes, I found out that bananas and humans are very similar. Although it doesn't make much sense and they look nothing alike, they apparently have most of their "functionality" in common.
Duplication in code is bad, so I wrote a new class to reduce maintenance costs. This class is called: BananaHuman. My Human class and Banana class inherit from BananaHuman.
Problem:
I have no problem with my BananaHuman (i.e. I understand what it means and why it exists). But eventually, other people (even those who don't (fully) understand inheritance) will have to use my LivingCreatures.dll. And they won't understand why intellisense suggests BananaHuman when they type 'B'.
And consider the following piece of code:
//Valid and makes sense.
foreach(LivingOrganism foo in cityOfNeyYork) { /*embedded statement*/ }
But imagine how weird/confusing it would look if we substitute Living Organism with BananaHuman.
I can't make BananaHuman private, protected or protected internal (Elements defined in a namespace cannot be explicitly declared that way). I also can't make it internal, because Human and Banana have to be public. If I try this, I get an error message saying there is an inconsistent accessibility issue.
I feel like I am missing the obvious, but what can/should I do? I am left with a couple of options/questions:
Is it possible to "hide" BananaHuman to avoid confusion?
Should I rewrite BananaHuman to something very long and technical such as DnaRelatedOrganismsType[X], where "X" describes their unique relation?
Should I just delete BananaHuman, let Human and Banana inherit from LivingOrganism and do the extra maintenance when something needs changing?
Is there another solution I am completely missing?
I searched around and couldn't quite find a "fixed pattern" for this situation. I found this question with a similar title, but I don't know if the answers are applicable because it appears that he is asking something completely different.
Any help is greatly appreciated!
You can use the EditorBrowsableAttribute and apply it to your class. This will make you class disappear from Intellisense if people are using your .dll. If you have your project referenced instead of the dll it will still be visible.
Use like:
[EditorBrowsable(EditorBrowsableState.Never)]
public class BananaHuman
{
//....
}
So if you would give me your .dll I wouldn't see BananaHuman pop up in Intellisense. But if I would inspect the Banana or Human class I would still see it inherited from BananaHuman because that IS the case. The EditorBrowsable attribute just makes it disappear from Intellisense, what is what you want.
The existing answer is a great technical solution to the specific problem of hiding the BananaHuman from intellisense. But since the OP also asks about changing the design, I think it's also within the scope of the question to give a quick answer about why the existence of BananaHuman is a code smell and it should probably be a candidate for refactoring.
You may have heard of the SOLID acronym for five important design principles. BananaHuman runs counter to two of them: the Single Responsibility Principle (SRP) and the Open/Closed Principle (OCP).
Bananas and humans may share a lot of DNA, but just like code, they should also be expected to evolve, and probably evolve separately from each other. That same DNA may not always be exactly shared. The SRP states that a class should only have one responsibility or- equivilently- should only have one reason to change. But BananaHuman will always automatically have at least two possible reasons to change- a change in the specifications for Banana or a change in specifications for Human.
Why is this the case specifically for BananaHuman, but not for all general base classes? Because a base class should represent one single well-defined concept, just like any other class. So for example Mammal would only have to change if the features making up the concept of a mammal change. If one particular mammal evolved to lose its hair, it's that animal's class that would change, not the base Mammal class. BananaHuman, on the other hand, is by definition "the features common to both a banana and a human", so it will always be coupled to at least two rather than one concepts. Likewise, there may be several things in common between a banana and a human which don't have much else to do with each other. Shoving these all into a single class reduces cohesion and piles more responsibilities into one place.
The OCP states that a software entity (such as an interface, class or method) should be open to extension but closed to modification when requirements are added or change. For example if you added another living organism sharing the same traits as Banana and Human, you'd have to change the name. Or if it only shared some of the traits, you'd have to shuffle around the base classes, potentially even running into multiple inheritance problems if this came up multiple times. I'm sure there are plenty of other situations which would lead to OCP violations too.
So what should you do?
Well, if you read the above and thought that the characterization of BananaHuman was unfair, and that actually it does map to a very well defined concept just like Mammal does then... rename it to what it actually is! That's all you need to do, and you're probably good to go. It doesn't matter if the name is long (though ideally concise is better, and you should make sure length doesn't indicate you're jamming multiple things together into one series of words).
If that's not the answer, then look into the idea of composition over inheritance. For example, if you have multiple living organisms which all have lungs, instead of creating a LivingOrganismWithLungs class, create a Lungs class, and have every living organism with lungs contain an instance. If you can separate out the common features into their own classes like this then you have a much nicer solution.
If those are both really not possible (rare, but it can happen) then BananaHuman may be the best option left. It would have to be up to your judgement to evaluate the SRP and OCP problems versus the Don't Repeat Yourself (DRY) violation.
Related
What is considered general best practice:
Reference via the super type?
public class BirdFeeder{
public Feed(Bird bird){...}
}
Or via a Interface
public class BirdFeeder{
public Feed(IBird iBird){...}
}
Personally I prefer interfaces but I'm not quite sure why, to me they just feel 'cleaner'. I would like a better understanding of why I would choose one over another.
Thanks
You are correct about the interfaces, they offer you more flexibility in designing your inheritance hierarchy.
Suppose that you have a hierarchy that starts with a base class Bird, and continues down to various species of birds. Now suppose that you would like to add a mechanical bird to the hierarchy of birds, but you would rather derive it from the Robot base class. If your feeder takes Bird arguments, your mechanical bird would need a special feeder. If the feeder take an IBird, however, there would be no problem sending a RoboBird to it, as long as it implements the IBird interface correctly.
If by "super type", and your comparison to interfaces, I'm guessing you want to focus on base abstract classes. (though you can use non-abstract base classes, but generally even an abstract class with no abstract members tends to communicate to the developer that it's intended to be implemented/inherited and doesn't stand on its own as a type)
There is no overall "best practice" when it comes to base/abstract classes vs interfaces. They both have their places in design practices. Really, the best practice comes about from the design you're implementing.
Probably the biggest difference when it comes to you design considerations is that base/abstract classes can only be inherited whereas interfaces can be implemented on any sort of class.
(EDIT: pilotcam came up with a far better example, see his comment to the question)
From your bird example, say for example you wanted to handle different birds like Parrots, Albatross, and Penguin and they all inherit from Bird. But then your application also handles Dinosaur types. You get to implementing Archaeopteryx. Does it inherit from Dinosaur or from Bird? Now if instead Bird was an interface, you could simply have class Archaeopteryx : Dinsoaur, IBird. This example is a bit contrived (there's a better one I'm sure), but hopefully it's good enough.
Of course, base/abstract classes are nice too. For example, by combining access modifiers, you could take advantage of perhaps implementing an internal method to which your API accesses implementations but outside consumers of the class cannot.
There really are a slew of reasons to use one over the other, and neither one is really "better" to code against. It really depends on your application design, and arguably the metaphor you're coding against; what those objects are representing. Is your object actually a bird, or does it only behave like a bird? Does your API care? What will be better to maintain for your work?
Here's some more reading:
Interface vs Abstract Class (general OO) (take note of all the "linked" similar questions to this one)
Use an abstract class for when you want to implement a set of behaviours in descendant components.
An interface when you want to implement a set of behaviours over a number of classes that have no useful common ancestor.
There are a lot of situations, when you could use either. In general I've found that I can rework a design that uses interfaces, get the new stuff and not get locked into a set of horrible compromises. I'd rather define an interface and then have an abstract class implement it for it's descendants than have no interface. It's a trivial amount of extra work at the start that can huge benefits later.
I'm currently working on an asp.net site, done by someone else, and it's rediculously over complicated for what it does......Well I think so! Pretty much every class inherits from another class then another and another and so on and on....... You have to go about 8/10 levels on average to get the the base class, sometimes more! And these classes have other classes inside which follow the same pattern of Uber Inheritence.
This leaves me lost in code many many times resulting in God knows how many tabs open on visual studio.
Is this good/normal practice or is it bad practice? I feel it's bad practice as something so simple is made over complicated with an over usage of inheritance resulting in un-extensible code...............but I could be wrong :)
Thanks!
Yes, over-using inheritance can lead to a spaghetti warehouse. Inheritance is a tool to allow for encapsulation and abstraction. Abusing it causes too much abstraction and then the purpose of the code becomes unusable. I've seen this pattern abused in imperative constructs as well where a method is passed from method to method to method before an action is actually applied.
private bool getData()
{
return getOtherData();
}
private bool getOtherData()
{
return getSomeExtraData();
}
private bool getSomeExtraData()
{
return SeeHowTediousThisIs();
}
It all works, but it's just an exceptionally bad architecture for maintenance. I find this often occurs with consultants/contractors attempting to introduce complexity (re: job security).
There is a design guideline of 'favour composition over inheritance' 8-10 levels on inheritance breaks that somewhat.
http://en.wikipedia.org/wiki/Composition_over_inheritance
Inheritance as a means to reusing code is a pretty bad choice indeed. Consider that every class in .NET-based languages have a single slot of inheritance where code can go. Hence, for each class it should be chosen wisely whether it should inherit from something else or not.
Classically one says that inheritance describes a "is-a" relationship, where by going up the inheritance chain we reach higher levels of abstraction.
The first question should always be whether a "can-act-as" relationship isn't sufficient. In this case, describing the relationship via interfaces is often a better choice. Secondly, when adding abstractions, the question must be whether a non-negligible amount of code can work with those abstractions in order to satisfy the features you are seeking.
If there is hardly any code using those abstractions, then they are most likely worthless by themselves. Again, the cost of abstraction is usually lower with interfaces than with base classes.
So, in summary
A "can-act-as" relationship is usually enough - You then don't need to go for a "is-a" relationship
The inheritance slot is precious - It can be used only once.
There are many more ways for code reuse than inheriting from a class
Base classes and interfaces are abstractions: Make sure that your code can indeed make use of them. If your interface is implemented by only one class, your abstraction is possibly worthless and easily introduced when it becomes necessary.
If there is a need for abstraction, the penalty is lower on interfaces than on base classes.
Sounds like inheritance-overkill, very rarely should need to go beyond 2-3 levels, and that would be for a complex business model.
What sort of classes are these? Controls? Business Objects? Are they documented (UML) anywhere so that you can get a good overview of the model?
8-10 levels deep is a lot, I would hazard a guess that these classes were coded before (or never) designed.
Most certainly I've been digging through inheritance hell lately. we quite literally have code that looks like this
Public Class A
' Do Stuff, methods, members, etc.
Public var As Object
Public Sub New()
member = New Object
End Sub
End Class
' yes it's empty
Public Class B : Inherits A
End Class
' yes it's empty
Public Class C : Inherits A
Public Sub New()
MyBase.New()
member.SomeMethod()
End Sub
End Class
Then there's the Base class that contains a list of objects that MUST be inherited in order to add objects to that list.
In short, yes inheritance can most certainly be abused, just like everything. Most help for me was to find a good UML modeling tool that will reverse engineer the language you're using.
NOTE: This is not the popular interface naming question about
using or not using "I" at the beginning.
I encounter often the problem to name
an interface, which indicates a belonging or property of a class.
(Please see following list)
Let's brainstorm, what kinds of interfaces are there?
Indicate the "kind" of a class
DataStructure, Number, Thing
Indicate the "profession" of a class
Comparator, Executor, Listener
Indicate a possible action performed with a class
Comparable, Executable, Closeable
The above are all clear to anyone, but let's get to my problem:
Indicate a belonging or property of a class
HasListener, LinksToRoot, BelongsToParent, KnowsSibling, ContainsChildren,
Named, WithDescription, ...?
So, the last point is my problem. My english is not perfect,
but even I feel strange about such names.
They sound to me less successfully chosen then other, less meaningful.
But I often end up choosing right this kind of names.
It is even a greater discomfort in C# where interfaces are expected
to start with an 'I':
IHasListener, IKnowsSibling, ...
Sound to me like LOLSPEAK "I can haz a kitteh, tawtally being full of
cuteness, OMG!##!"
So, how should I name an interface which indicates a belonging or
property of a class?
The problem is the way you choose to describe the "belonging of a property".
Most of your examples you gave can be mapped to the other categories you mentioned.
Just a few, for example:
HasListener => implements Listenable
ContainsChildren => implements Parent
WithDescription => implements Descriptable
Try to stick with more conventional naming schemes, preferably ones that describe your object in the best, more readable manner.
Also, make sure you are not over-interfacing your classes with useless interfaces. Make it very concise and to-the-point, otherwise you'll developers reading your code will get lost very fast.
In some of the problem cases that you outline, I think there may be an answer by looking "from the other side":
HasListener -> Speaker
LinksToRoot, HasParent -> Child (or perhaps Node)
ContainsChildren -> Parent
Of course, different cases will be more or less obvious.
I think you can take some of what you're doing and turn them into "profession"-type interfaces:
HasListener -> ListenerContainer
WithDescription -> DescriptionContainer (Describable might also work, depending on what exactly a "description" is in this context)
A lot of your other interfaces seem to have something to do with a tree structure. I would suggest naming them according to their function in the tree.
ContainsChildren -> Parent or Collection
BelongsToParent -> Child
As for the other ones, I'd need to know more about what specifically these interfaces are for. Some of them, like Named, are probably named just fine.
Those sounds like terrible interface names to me, I agree. The "HasListener" sounds more like a method call that should return a boolean than an interface name.
Interfaces should not exist to hold/store properties of a class. They should be used to outline a relationship that all classes that implement it should follow. I personally stick with the "is a" relationship. If there is a direct relationship, i.e. a cat "is a(n)" animal, then I will create an interface for it and name it Animal giving it a reasonable name.
I would be really interested in knowing what the "HasListener" interface outlines. What exactly does it do? Why can't it be named MyProjectListeners(replacing MyProject with the project name) that describes what listeners defined for this project must adhere to?
HasListener is ok, as well as Listenable. I don't have anything against those.
But IHasListener is terrible: first because we don't really need the I prefix to tell that it is an interface (look at the class signature!) and second because it sounds like "I doesn't speak English".
The only interface in Java that I created with the I prefix was IRule. :)
I actually quite like the "IHasListener" approach.
In the .NET Framework, you'll find this in interfaces such as:
IRaiseListChangedEvents
IHasXmlNode
Names like "Listenable" suggest that the implementation does the listening, not that it contains a listener. IHasListener clearly says what it does.
I know that multiple inheritance is not allowed in Java and C#. Many books just say, multiple inheritance is not allowed. But it can be implemented by using interfaces. Nothing is discussed about why it is not allowed. Can anybody tell me precisely why it is not allowed?
The short answer is: because the language designers decided not to.
Basically, it seemed that both the .NET and Java designers did not allow multiple inheritance because they reasoned that adding MI added too much complexity to the languages while providing too little benefit.
For a more fun and in-depth read, there are some articles available on the web with interviews of some of the language designers. For example, for .NET, Chris Brumme (who worked at MS on the CLR) has explained the reasons why they decided not to:
Different languages actually have different expectations for how MI
works. For example, how conflicts are
resolved and whether duplicate bases
are merged or redundant. Before we can
implement MI in the CLR, we have to do
a survey of all the languages, figure
out the common concepts, and decide
how to express them in a
language-neutral manner. We would also
have to decide whether MI belongs in
the CLS and what this would mean for
languages that don't want this concept
(presumably VB.NET, for example). Of
course, that's the business we are in
as a common language runtime, but we
haven't got around to doing it for MI
yet.
The number of places where MI is truly appropriate is actually quite
small. In many cases, multiple
interface inheritance can get the job
done instead. In other cases, you may
be able to use encapsulation and
delegation. If we were to add a
slightly different construct, like
mixins, would that actually be more
powerful?
Multiple implementation inheritance injects a lot of complexity into the
implementation. This complexity
impacts casting, layout, dispatch,
field access, serialization, identity
comparisons, verifiability,
reflection, generics, and probably
lots of other places.
You can read the full article here.
For Java, you can read this article:
The reasons for omitting multiple
inheritance from the Java language
mostly stem from the "simple, object
oriented, and familiar" goal. As a
simple language, Java's creators
wanted a language that most developers
could grasp without extensive
training. To that end, they worked to
make the language as similar to C++ as
possible (familiar) without carrying
over C++'s unnecessary complexity
(simple).
In the designers' opinion, multiple
inheritance causes more problems and
confusion than it solves. So they cut
multiple inheritance from the language
(just as they cut operator
overloading). The designers' extensive
C++ experience taught them that
multiple inheritance just wasn't worth
the headache.
Multiple inheritance of implementation is what is not allowed.
The problem is that the compiler/runtime cannot figure out what to do if you have a Cowboy and an Artist class, both with implementations for the draw() method, and then you try to create a new CowboyArtist type. What happens when you call the draw() method? Is someone lying dead in the street, or do you have a lovely watercolor?
I believe it's called the double diamond inheritance problem.
Reason:
Java is very popular and easy to code, because of its simplicity.
So what ever java developers feel difficult and complicated to understand for programmers, they tried to avoid it. One such kind of property is multiple inheritance.
They avoided pointers
They avoided multiple inheritance.
Problem with multiple inheritance: Diamond problem.
Example:
Assume that class A is having a method fun(). class B and class C derives from class A.
And both the classes B and C, overrides method fun().
Now assume that class D inherits both class B, and C. (just Assumption)
Create object for class D.
D d = new D();
and try to access d.fun(); => will it call class B's fun() or class C's fun()?
This is the ambiguity existing in diamond problem.
It is not impossible to solve this problem, but it creates more confusion and complexities to the programmer while reading it.
It causes more problem than it tries to solve.
Note: But any way you can always implement multiple inheritance indirectly by using interfaces.
Because Java has a greatly different design philosophy from C++. (I'm not going to discuss C# here.)
In designing C++, Stroustrup wanted to include useful features, regardless of how they could be misused. It's possible to screw up big-time with multiple inheritance, operator overloading, templates, and various other features, but it's also possible to do some very good things with them.
The Java design philosophy is to emphasize safety in language constructs. The result is that there are things that are a lot more awkward to do, but you can be a lot more confident that the code you're looking at means what you think it does.
Further, Java was to a large extent a reaction from C++ and Smalltalk, the best known OO languages. There are plenty of other OO languages (Common Lisp was actually the first one to be standardized), with different OO systems that handle MI better.
Not to mention that it's entirely possible to do MI in Java, using interfaces, composition, and delegation. It's more explicit than in C++, and therefore is clumsier to use but will get you something you're more likely to understand at first glance.
There is no right answer here. There are different answers, and which one is better for a given situation depends on applications and individual preference.
The main (although by no means the only) reason people steer away from MI is the so called "diamond problem" leading to ambiguity in your implementation. This wikipedia article discusses it and explains better than I could. MI can also lead to more complex code, and a lot of OO designers claim that you do't need MI, and if you do use it your model is probably wrong. I'm not sure I agree with this last point, but keeping things simple is always a good plan.
In C++ multiple inheritance was a major headache when used improperly. To avoid those popular design issues multiple interfaces "inheritance" was forced instead in modern languages (java, C#).
Multiple Inheritance is
hard to understand
hard to debug (for example, if you mix classes from multiple frameworks that have identically-named methods deep down, quite unexpected synergies can occur)
easy to mis-use
not really that useful
hard to implement, especially if you want it done correctly and efficiently
Therefore, it can be considered a wise choice to not include Multiple Inheritance into the Java language.
Another reason is that single-inheritance makes casting trivial, emitting no assembler instructions (other than checking for the compatibility of the types where required). If you had multiple-inheritance, you'd need to figure out where in the child class a certain parent starts. So performance is certainly a perk (although not the only one).
Back in the old days ('70s) when Computer Science was more Science and less mass production the programmers had time to think about good design and good implementation and as a result the products (programms) had high quality ( eg. TCP/IP design and implementation ).
Nowadays, when everybody is programming, and the managers are changing the specs before deadlines, subtle issues like the one descriped in the wikipedia link from Steve Haigh post are difficult to track; therefore, the "multiple inheritance" is limited by compiler design. If you like it, you can still use C++ .... and have all the freedom you want :)
I take the statement that "Multiple inheritance is not allowed in Java" with a pinch of salt.
Multiple Inheritance is defined when a "Type" inherits from more than one "Types". And interfaces are also classified as types as they have behavior. So Java does have multiple inheritance. Just that it is safer.
Dynamic loading of classes makes the implementation of multiple inheritance difficult.
In java actually they avoided the complexity of multiple inheritance instead by using single inheritance and interface.
Complexity of multiple inheritance is very high in a situation like below explained
diamond problem of multiple inheritance.
We have two classes B and C inheriting from A. Assume that B and C are overriding an inherited method and they provide their own implementation. Now D inherits from both B and C doing multiple inheritance. D should inherit that overridden method, jvm can't able to decide which overridden method will be used?
In c++ virtual functions are used to handle and we have to do explicitly.
This can be avoided by using interfaces, there are no method bodies. Interfaces cannot be instantiated—they can only be implemented by classes or extended by other interfaces.
Actually multiple inheritance will arise a the complexity if the inherited classes have same function. ie the compiler will have a confusion which one has to chose (diamond problem). So in Java that complexity removed and gave interface to get the functionality like multiple inheritance gave. We can use interface
Java has concept, i.e. polymorphism. There are 2 types of polymorphism in java. There are method overloading and method overriding. Among them, method overriding happens with super- and subclass relationship. If we are creating an object of a subclass and invoking the method of superclass, and if subclass extends more than one class, which super class method should be called?
Or , while calling superclass constructor by super(), which super class constructor will get called?
This decisions are impossible by current java API features. so multiple inheritance is not allowed in java.
Multiple Inheritance is not allowed in Java directly , but through interfaces it is allowed.
Reason :
Multiple Inheritance : Introduces more complexity and ambiguity.
Interfaces : Interfaces are completely abstract classes in Java that provide you with a uniform way to properly delineate the structure or inner workings of your program from its publicly available interface, with the consequence being a greater amount of flexibility and reusable code as well as more control over how you create and interact with other classes.
More precisely, they are a special construct in Java with the additional characteristic that allow you to perform a kind of multiple inheritance i.e. classes that can be upcast to more than one class.
Lets take simple example.
Suppose there are 2 superclasses classes A and B with same method names but different functionalities. Through following code with (extends) keyword multiple inheritance is not possible.
public class A
{
void display()
{
System.out.println("Hello 'A' ");
}
}
public class B
{
void display()
{
System.out.println("Hello 'B' ");
}
}
public class C extends A, B // which is not possible in java
{
public static void main(String args[])
{
C object = new C();
object.display(); // Here there is confusion,which display() to call, method from A class or B class
}
}
But through interfaces, with (implements) keyword multiple inheritance is possible.
interface A
{
// display()
}
interface B
{
//display()
}
class C implements A,B
{
//main()
C object = new C();
(A)object.display(); // call A's display
(B)object.display(); //call B's display
}
}
Can anybody tell me precisely why it is not allowed?
You can find answer from this documentation link
One reason why the Java programming language does not permit you to extend more than one class is to avoid the issues of multiple inheritance of state, which is the ability to inherit fields from multiple classes
If multiple inheritance is allowed and when you create an object by instantiating that class, that object will inherit fields from all of the class's super classes. It will cause two issues.
What if methods or constructors from different super classes instantiate the same field?
Which method or constructor will take precedence?
Even though multiple inheritance of state is now allowed, still you can implement
Multiple inheritance of type: Ability of a class to implement more than one interface.
Multiple inheritance of implementation (through default methods in interfaces) : Ability to inherit method definitions from multiple classes
Refer to this related SE question for additional info:
Multiple Inheritance Ambiguity with Interface
In C++ a class can inherit (directly or indirectly) from more than one class, which is referred to as
multiple inheritance.
C# and Java, however, limit classes to single inheritance each class inherits
from a single parent class.
Multiple inheritance is a useful way to create classes that combine aspects of two disparate class
hierarchies, something that often happens when using different class frameworks within a single
application.
If two frameworks define their own base classes for exceptions, for example, you can
use multiple inheritance to create exception classes that can be used with either framework.
The problem with multiple inheritance is that it can lead to ambiguity. The classic example is when
a class inherits from two other classes, each of which inherits from the same class:
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
In this example, the flag data member is defined by class A. But class D descends from class B
and class C, which both derive from A, so in essence two copies of flag are available because two
instances of A are in D’s class hierarchy. Which one do you want to set? The compiler will complain
that the reference to flag in D is ambiguous. One fix is to explicitly disambiguate the reference:
B::flag = nflag;
Another fix is to declare B and C as virtual base classes, which means that only one copy of A can
exist in the hierarchy, eliminating any ambiguity.
Other complexities exist with multiple inheritance, such as the order in which the base classes are
initialized when a derived object is constructed, or the way members can be inadvertently hidden
from derived classes. To avoid these complexities, some languages restrict themselves to the simpler single inheritance model.
Although this does simplify inheritance considerably, it also limits its usefulness
because only classes with a common ancestor can share behaviors. Interfaces mitigate this
restriction somewhat by allowing classes in different hierarchies to expose common interfaces even
if they’re not implemented by sharing code.
Imagine this Example:
I have a class Shape1
It has CalcualteArea method:
Class Shape1
{
public void CalculateArea()
{
//
}
}
There is another class Shape2 that one also has same method
Class Shape2
{
public void CalculateArea()
{
}
}
Now I have a child class Circle, it derives from both Shape1 and Shape2;
public class Circle: Shape1, Shape2
{
}
Now when I create object for Circle, and call the method, system does not know which calculate area method to be called. Both has same signatures. So compiler will get confuse. That's why multiple inheritances are not allowed.
But there can be multiple interfaces because interfaces do not have method definition. Even both the interfaces have same method, both of them do not have any implementation and always method in the child class will be executed.
I was just wondering, since the sealed keyword's existence indicates that it's the class author's decision as to whether other classes are allowed to inherit from it, why aren't classes sealed by default, with some keyword to mark them explicitly as extensible?
I know it's somewhat different, but access modifiers work this way. With the default being restrictive and fuller access only being granted with the insertion of a keyword.
There's a large chance that I haven't thought this through properly, though, so please be humane!
I'd say it was just a mistake. I know many people (including myself) who believe that classes should indeed be sealed by default. There are at least a couple of people in the C# design team in that camp. The pendulum has swung somewhat away from inheritance since C# was first designed. (It has its place, of course, but I find myself using it relatively rarely.)
For what it's worth, that's not the only mistake along the lines of being too close to Java: personally I'd rather Equals and GetHashCode weren't in object, and that you needed specific Monitor instances for locking too...
In my opinion there should be no default syntax, that way you always write explicitly what you want. This forces the coder to understand/think more.
If you want a class to be inheritable then you write
public extensible class MyClass
otherwise
public sealed class MyClass
BTW I think the same should go with access modifiers, disallow default access modifiers.
Inheritance is a foundational principle of OO, so arguably, disallowing it by default wouldn't be intuitive.
You could probably make just as many arguments in favor of sealed-by-default as you could against it. If it were the other way around, someone would be posting the opposite question.
I can't recall having heard a rationale for the decision to have classes not sealed by default. However, there are certainly quite a few people who believe that C# should have been spec'ed to have sealed be the default:
http://codebetter.com/blogs/patricksmacchia/archive/2008/01/05/rambling-on-the-sealed-keyword.aspx
sealed classes prevent inheritance and therefore are an OO abombination. see this rant for details ;-)
80% of the features of Word go unused. 80% of classes don't get inherited from. In both cases, once in a while, someone comes along and wants to use or reuse a feature. Why should the original designer prohibit reuse? Let the reuser decide what they want to reuse.
Merely deriving from an unsealed class doesn't change the class's behavior. The worst that can happen is that a new version of the base class will add a member with the same name as the deriving class (in which case there will just be a compiler warning saying you should use the new or override modifier) or the base class is sealed (which is a design no-no if the class has already been released into the wild). Arbitrary sublassing still complies with the Liskov Substitution Principle.
The reason that members are not overridable by default in C# is that because overriding a method can change the base class's behaviour in a way that the base class's author didn't anticipate. By making it explicitly abstract or virtual, it's saying that the author is aware that that it can change or is otherwise beyond their control and the author should have taken this into account.
For the same reason why objects are not private by default
or
to be consistent with the object analogue, which is objects are not private by default
Just guessing, coz at the end of the day it's a language's design decision and what the creators say is the canon material.