views:

288

answers:

5

Guys before you start down voting me please read this question and please understand that I do not try to start anything unpleasant here.

The only reason for this question is that I'm becoming more and more aware of that in order to be more employable I have to know either Java and/or C#.

Ok here is the question:

I know that multiple inheritance is forbidden in J and C#. But if I do something like this (because I would like to have a class which inherits from two classes B and A):

//code in Java
public class B
{
    public void methodFromB()
    {
    }
}

public class A extends B
{
    public void  methodFromA()
    {
    }
}

public class C extends A
{
    public void methodFromC()
    {
    }
}

So in fact as far as I understand this, I do inherit from both of them (A and B and yes I do understand that formal explanation for this is that the object A is a specialized B but none the less if I want to do it I will but it just doesn't look pretty)

But instead of doing this in one declaration I have to first create one class inherit from another class and then derive from it?

Funny thing though. Having declared those classes as above (in NetBeans) I see that after creating an instance of class C (in main) I cannot invoke methodFromC on it which is the method defined in this class.

What is the reason for that?

Thanks.

+7  A: 

Even though you are creating an instance of C, whether C's methods are visible depends upon the compile-time type that you are using. For example,

C c = new C();
c.methodFromC();  // fine

Is valid, but

A a = new C();
a.methodFromC();  // compiler error

is not, since the compile time type is an A, which does not have methodFromC declared.

Note that since both C and A are subclasses of B, calling methodFromB would be fine in both cases.

mdma
@mdma but in NetBeans I cannot (it does not shows that it's available) c.methodFromC(); Why?
There is nothing we can do
@mdma any update on why I can't invoke c.methodFromC()?
There is nothing we can do
With the code you have now posted, I don't see why there is a problem. Have you tried actually typing in the method to see if the code compiles? Auto-complete and compiling are not always the same thing! Otherwise, double check access modifiers (make everything public) and double check you are using a lowercase c, i.e. `c.methodOnC()`. If the C. is uppercase t will not work, since that would imply a static method.
mdma
@mdma yes, it does compile even though it says that it cannot find the symbol. Thanks.
There is nothing we can do
+5  A: 

I agree with mdma. Also note that this is NOT multiple inheritance, this is chained inheritance. Multiple inheritance is when a class inherits from more than one class at the same time:

class A {}
class B {}

class C extends A, B {}

Which is forbidden if you're not coding in C++

vulkanino
+1  A: 

An alternative in C# (and may exist in Java, but I'm not a Java person so I don't know) is interfaces.

public interface C
{
    int SomeMethodInC();
}

public class A
{
}

public class B : A, C
{
}

... in other class....
B someB = new B();
i someInt = someB.SomeMethodInC();

It looks like multiple inheritance, but it isn't. Interface C defines the signature for someMethodInC, but not the implementation. Class B will have to implement someMethodInC.

In C#, you can inherit from only one class, but you can inherit multiple interfaces. (Same in Java, I think.)

In C#, you can also attach implementations to interfaces by using extension methods.

public static class CExtensions
{
    public static int SomeExtensionToC(this C someC, int someInt)
    {
       return someInt * 2;
    }
}
... in code ...
B objB = new B();
y = objB.SomeExtensionToC(x);

Both the method and implemention of SomeExtensionToC will be available to any class that inherits interface C. Note that both the class and method are static, and that the first parameter includes the keyword "this" in reference to an object implementing C. Some parts of the .NET framework (LINQ, as an example) are implemented as extension methods to IEnumerable<T>.

Almost like multiple inheritance, without the bad parts. And the extension methods are still considered part of the interface, so can be considered as part of the "contract" inherent in interface C.

Cylon Cat
To confirm, yes Interfaces do also exist in Java with very similar syntax and implementation.http://stackoverflow.com/questions/3355408/explaining-interfaces-to-students/3361740#3361740Dynamic languages offer other ways to achieve multiple inheritance.
JulesLt
A: 

Your definition of multiple inheritance is not correct.

At the OO level, multiple inheritance is well and clearly defined.

And both C++ and Java support multiple inheritance.

The problem is that most programmers have absolutely zero OO/OOA/OOD notions and all they know are OOP implementation details. Hence their wrong belief that "inheritance" is synonym to "implementation inheritance".

However this is completely wrong.

Because Java support multiple (interface) inheritance, which happens to be the real and only form of inheritance that exists at the Object-Oriented-Analysis / Object-Oriented-Design level.

Show me any OOD resulting from an OOA and that is using multiple inheritance and I can translate it cleanly to OOP in Java using multiple interface inheritance (as an added bonus in Java the "diamond" problem doesn't exist).

NoozNooz42
However note that by altough correct and provable my answer is unlikely to be well accepted on a site like SO, which is entirely focus on implementation details and frequented by programmers who are for the most part totally unaware of the bigger picture. They've been learning OO, say, while learning Java and have been told in the process by countless totally wrong sources that Java only support single inheritance. Don't expect these kind of people to see the light and change their minds :)
NoozNooz42
Extending interfaces in no way constitutes multiple inheritance. No implementation details are ever derived from an interface, it's merely a specification of what a class should contain (and implement). But if you're of a different opinion, feel free to elucidate.
mikek
@mikek: of course extending from several interface constitutes MI (on a funny sidenote, Java didn't get this wrong: you can write *interface A extends B,C*. And I specifically explained why in my answer "multiple interface inheritance" is "multiple inheritance". You're seriously confusing "code reuse" and "inheritance". Note that anything you think can't be done and hence ain't MI when extending from multiple Java interfaces can actually be done simply using delegation. Once again: show me **ANY** OOA/OOD using MI that cannot be trivially ported to Java using multiple interface inheritance...
NoozNooz42
+1  A: 

That is not multiple inheritance. And you are right C# does not support true multiple inheritance. For what it is worth the canonical pattern for simulating multiple inheritance in C# is below.

public interface IA
{
  void DoA();
}

public interface IB
{
  void DoB();
}

public class A : IA
{
  public void DoA() { Console.WriteLine("A"); }
}

public class B : IB
{
  public void DoB() { Console.WriteLine("B"); }
}

public class MultipleInheritanceExample : IA, IB
{
  private IA m_A = new A();
  private IB m_B = new B();

  public void DoA() { m_A.DoA(); }
  public void DoB() { m_B.DoB(); }

}

It is definitely not as elegant as pure mulitple inheritance, but gets the job done, albiet with more work. You get most of the benefits of multiple inheritance including the most important one, polymorphism. However, you do not inherit the implementation. You have to reimplement all members inherited from all base classes. This is done by mapping those member calls onto concrete instances of each base class.

In C# you can take advantage of extension methods to mitigate the problem of not inheriting the implementation.

public static class IAExtensions
{
  public static void Foo(this IA target)
  {
    target.DoA();
  }
} 

This, of course, has its own problems. It is not actually causing any kind of inheritance which means the IA interface does not actually have the Foo method. That means only the code which imports the IAExtensions class can use methods from it. In other words, there is no polymorphism here.

You can use of these mechanisms together to cludge together something, that for the most part, resembles and functions like multiple inheritance, but it is not as elegant. Personally, I find the workarounds that C# developers are adopting to mimic mulitple inheritance more offensive than if pure multiple inheritance were used. But, it is unlikely that C# will get mulitple inheritance any time soon or perhaps ever.

Brian Gideon