Java中的多重继承,类内嵌类

5
我们知道在Java中,不存在多重继承。以下是一个例子来说明这一点。
Class A 

{

      has some features

     Class B extends Class C 
        {

              I can access A + C's features, B is child of two parents?
         }

}

B是C,B不是A。你可以在其他地方将B用作C,但不能将其用作A。 - Peter Lawrey
是的,所以B能够继承两个类的属性/特征? - Randon
2
这被称为委托,是继承的一种替代方式。比如你继承了父亲的姓氏,但你可以请求你最好的朋友帮助你,但这并不意味着你也拥有你最好的朋友的姓氏。 - Peter Lawrey
1
+1 -- 我能理解为什么这会让学习Java的人感到困惑 - user541686
非静态内部类使用委托模拟多重继承。它“感觉”像 MI,在某些情况下非常有用。 - Matthias
3个回答

3

B是A的内部类,但并不是A的子类。

更确切地说,B是一个非静态嵌套类(这使得它成为内部类)。嵌套类是其封闭类的成员。内部类允许访问嵌套它们的类的所有成员。封闭类成员上声明的私有访问限定符不会阻止内部类访问该成员。

通过子类进行继承和通过内部类访问成员之间的区别在于,成员的继承允许成员被屏蔽(对于属性)和重写(对于方法)。内部类不能遮盖封闭类属性,但可以访问它们。

为了进一步简化这个概念,考虑以下代码示例:

class C
{
    void c()
    {}
}

public class A {

    void a(){}

        class B extends C
        {
            // a new member of B
            void b()
            {
            }

            //does not override A.a()
            void a()
            {
                a(); //invokes A.a() as B has access to it.
                super.a(); //illegal                
            }

            //overrides C.c()
            @Override
            void c()
            {
                super.c(); //invokes C.c()
            }
        }
}

注意,您无法从嵌套类中调用super.a()。这就是继承成员和仅访问它之间的区别。 进一步阅读

是的,所以B可以继承两个类的属性/特征? - Randon
@Randon,我已经添加了一段关于继承与仅访问类成员不同的内容。 - Vineet Reynolds

2

B不是两个父类的子类,它是C的“子类”,但可以访问A的属性,它是A的一部分,但不是它的子类。
您可以运行以下代码以确保:

class Main {
    public void bar() {
        Object o = new B();
        System.out.println("is B subclass of Main:" + (o instanceof  Main));
        System.out.println("is B subclass of C:" + (o instanceof  C));
    }
    public class C { }
    public class B extends C { }
    public static void main(String[] argv) {
        Main a = new Main();
        a.bar();
    }
}

对于第一个问题,它将打印false,因为o(即B)不是Main的实例;但对于第二个问题,它将打印true,因为B是C的实例。


编辑:我修改了代码以使其更易读(至少在我看来是这样)。

是的,所以B能够继承两个类的属性/特征吗? - Randon
@Randon:它可以访问它们,但它并不是从A继承而来。看一下我刚提供的代码,这证明了C不是A的子类。 - amit

0
“多重继承”是指一个类有不止一个直接“父类”。
在你的例子中,A 包围 B,B 是 C 的父类,但这并不意味着 A 是 C 的父类。
如果这是多重继承,那么 A 和 B 都将是 C 的父类(C extends A, B),但在 Java 中无法实现这一点。
(顺便说一下:在 Java 中,如果没有明确指定父类,则会默认使用 java.lang.Object。这就是为什么每个方法都有一个 toString() 方法的原因)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接