Java : 如果 A 扩展 B 和 B 扩展对象,是多重继承 [英] Java : If A extends B and B extends Object, is that multiple inheritance

查看:22
本文介绍了Java : 如果 A 扩展 B 和 B 扩展对象,是多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚接受了采访,有人问了我一个问题.

面试官 - Java 是否支持多重继承?

- 没有

Interviewer - Java 中的每个类都扩展类 Object(类 Object 除外),如果我们从外部扩展一个类,如

A 类扩展 B{//这里有一些代码}

那么你可以说A类继承了B类和Object类,就是多重继承.那你怎么能说Java不支持多重继承呢?

Me - 实际上 B 类扩展了 Object 类,所以当你在 A 类中扩展 B 类时,A 类间接扩展了 Object 类.这是多级继承,不是多重继承.

但我的回答并没有让他满意.

我的回答正确吗?或者我错在哪里?内部实际发生了什么?

解决方案

我的回答正确吗?

是的,主要是,当然在您描述的上下文中.这不是多重继承:

就是你说的,多层次的单继承.

这是多重继承:从两个或多个彼此没有任何是"关系的碱基继承;这将是从不相关的行,或从以前有分歧的行继承的(在 Java 中,因为 Object 始终是一个基础,所以应该是后者):

(图片来源:http://yuml.me 在邋遢"模式下)

<块引用>

内部实际发生了什么?

正如您所说:有多个级别.当编译器解析实例上的成员时:

obj.member

...它查看 obj 的类型(在本例中是一个类,比如 ClassB)是否有 member,要么是因为它是直接提供的,要么是通过继承获得的.在运行时,JVM 使用对象实际拥有的 member.

<小时>

我在上面说主要"的原因是 Java 有接口,从 Java 8 开始,它在接口上有默认方法".这让事情有点复杂,但在你描述的面试官所说的关于 ObjectClassAClassB.

在 Java 中,接口总是使某些事物与两种不同类型具有是"关系成为可能:它继承自的类类型,以及它实现的几种接口类型中的任何一种.没有默认方法的接口实际上不是多重继承(类必须提供实现),但它们确实使一个类可以从不相关的类型树中拥有多个是一个"关系.(我不是学者,学者可能会争辩说他们以学术方式提供多重继承.)

在 Java 8 中,接口可以提供它们定义的方法的默认实现,这甚至在实际层面也确实模糊了界限.让我们更深入地了解一下:

假设我们有 ClassA:

class ClassA {void doSomething() {//代码在这里}}

Interface1:

interface Interface1 {default void doSomethingElse() {//需要 Java 8//代码在这里}}

最后ClassB:

class ClassB 扩展 ClassA 实现 Interface1 {}

ClassBClassA 继承了 doSomething 的实现.但它Interface1获取doSomethingElse的默认"版本.我们没有在ClassB 中实现它,但是ClassB 不是抽象的:它确实有doSomethingElse.它从接口获取.我在那里使用了gets"而不是inherits"这个词,但这看起来很多就像继承默认方法一样.

这基本上是多重继承的light"(如light beer").它最终解决了真正的多重继承的棘手问题,例如:

  • super 的类型应该是什么?(Java 8 的答案:ClassA)
  • 您运行构造函数的顺序是什么?(Java 8 的答案:单谱系构造函数链,接口没有构造函数.)
  • 您是否运行多次继承的构造函数?(Java 8 的回答:您不能多次继承构造函数,接口没有它们.)
  • 如果继承多个具有相同签名的方法会怎样?(Java 8 的回答:如果其中一个来自基类,那就是使用的那个;基类的实现可以覆盖多个接口的默认方法.如果您在编译时有多个来自不同接口的具有相同签名的默认方法 -时间,这是一个编译时错误.如果在没有重新编译类的情况下更改了接口,并且这种情况在运行时出现,则是运行时 IncompatibleClassChangeError 异常,列出了冲突的默认方法.)

I just had an interview, and I was asked a question.

Interviewer - Does Java support multiple inheritance?

Me - No

Interviewer - Each class in Java extends class Object (except class Object) and if we externally extend one class like

Class A extends B{
  // some code here
}

then you can say that class A extend class B and class Object, which means it is multiple inheritance. So how can you say Java does not support multiple inheritance?

Me - Actually class B extends class Object, so when you extend class B in class A then class A extends class Object indirectly. This is multi-level inheritance, not multiple inheritance.

But my answer did not satisfy him.

Is my answer correct? Or where am I wrong? What actually happens internally?

解决方案

My answer is correct?

Yes, mostly, and certainly in the context you describe. This is not multiple inheritance:

It's what you said it is, single inheritance with multiple levels.

This is multiple inheritance: Inheriting from two or more bases that don't have any "is a" relationship with each other; that would be inheriting from unrelated lines, or from lines that had previously diverged (in Java, since Object is always a base, it would be the latter):

(Image credits: http://yuml.me in "scruffy" mode)

Internally What happens actually?

Just what you said: There are multiple levels. When the compiler is resolving a member on an instance:

obj.member

...it looks to see if the type of obj (which in this case is a class, say ClassB) has member, either because it provides it directly or it has it through inheritance. At runtime, the JVM uses the member the object actually has.


The reason I said "mostly" above is that Java has interfaces, and as of Java 8 it has "default methods" on interfaces. This complicates things a bit, but your answer about levels is correct in the context of what you described the interviewer saying about Object, ClassA, and ClassB.

Interfaces have always made it possible, in Java, for something to have an "is a" relationship with two different types: A class type it inherits from, and any of several interface types it implements. Interfaces without default methods aren't multiple inheritance in a practical way (the class has to provide the implementation), but they did make it possible for a class to have multiple "is a" relationships from unrelated type trees. (I'm not an academic, it's possible an academic would argue that they provide multiple inheritance in an academic way.)

With Java 8, interfaces can provide default implementations of the methods they define, which really blurs the lines even at the practical level. Let's look at that a bit more deeply:

Say we have ClassA:

class ClassA {
    void doSomething() {
        // Code here
    }
}

and Interface1:

interface Interface1 {
    default void doSomethingElse() { // Requires Java 8
        // Code here
    }
}

and finally ClassB:

class ClassB extends ClassA implements Interface1 {
}

ClassB inherits the implementation of doSomething from ClassA. But it also gets the "default" version of doSomethingElse from Interface1. We didn't implement it in ClassB, but ClassB isn't abstract: It really has doSomethingElse. It gets it from the interface. I used the word "gets" rather than "inherits" there, but this looks a lot like inheriting the default method.

This is basically multiple-inheritance "light" (as in "light beer"). It does an end-run around the thornier problems with true multiple inheritance, like:

  • What should the type of super be? (Java 8's answer: ClassA)
  • What order do you run constructors in? (Java 8's answer: Single-lineage constructor chaining, interfaces don't have constructors.)
  • Do you run constructors that you inherit more than once, more than once? (Java 8's answer: You can't inherit constructors more than once, interfaces don't have them.)
  • What happens if you inherit multiple methods with the same signature? (Java 8's answer: If one of them is from the base class, that's the one that's used; a base class's implementation can override the default method of multiple interfaces. If you have multiple default methods with the same signature from different interfaces at compile-time, it's a compile-time error. If an interface has been changed without the class being recompiled and the situation arises at runtime, it's a runtime IncompatibleClassChangeError exception listing the conflicting default methods.)

这篇关于Java : 如果 A 扩展 B 和 B 扩展对象,是多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆