我一直在尝试使用java教自己继承,但我真的很困惑,看起来像在线youtube视频/看以前的问题根本没有帮助。我尝试了这个网站上的练习题:http://javaconceptoftheday.com/java-inheritance-practice-coding-questions/,但我遇到问题2,3和7的问题。
在问题2中,由于对象a的构造函数是B(),为什么不打印B类的i值而不是类a?相反,它打印出一个类,我不知道为什么。
在问题3中,是程序打印1 2 3的原因是因为没有构造函数而且它只是函数?我知道当你从一个类继承时,你基本上就好像它的所有函数都在子类中一样,所以你基本上只是假装C类说:
的System.out.println(1);
的System.out.println(2);
的System.out.println(3);
在问题7中,由于构造函数是一个C()构造函数,为什么它仍然遍历A类和B类的构造函数中的代码?
感谢您提供任何帮助,继承只是我在编程课程介绍中没有涉及的主题之一,所以我试图在秋季学期开始之前填写所有空白。
问题2的代码:
class A
{
int i = 10;
}
class B extends A
{
int i = 20;
}
public class MainClass
{
public static void main(String[] args)
{
A a = new B();
System.out.println(a.i);
}
}
问题3的代码:
class A
{
{
System.out.println(1);
}
}
class B extends A
{
{
System.out.println(2);
}
}
class C extends B
{
{
System.out.println(3);
}
}
public class MainClass
{
public static void main(String[] args)
{
C c = new C();
}
}
问题7的代码:
class A
{
public A()
{
System.out.println("Class A Constructor");
}
}
class B extends A
{
public B()
{
System.out.println("Class B Constructor");
}
}
class C extends B
{
public C()
{
System.out.println("Class C Constructor");
}
}
public class MainClass
{
public static void main(String[] args)
{
C c = new C();
}
}
答案 0 :(得分:1)
Q2)
Java语言的多态行为适用于方法而不是成员变量:它们设计语言在编译时绑定成员变量,在运行时绑定方法。
Q3)
它被称为 instance initialization block 。子类的每个实例都隐式包含其超类的实例。因此,呼叫顺序从class A
,B
开始,然后C
开始。
Q7)
Q3
同样适用于问题的原因
答案 1 :(得分:0)
首先,我认为你应该看看Oracle的Java教程,主要是Classes上的那个和Inheritance上的那个。
让我们从问题2开始:
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
由于A
和B
的成员名称相同,B
会隐藏A
中的成员。从本质上讲,B
的实例有两个成员i
:一个来自A
,另一个来自B
。在方法main
中,您编写A a = new B();
,即a
的静态类型为A
,a
的运行时类型为B
。当您现在访问成员时,静态类型会决定选择哪个成员(A
或B
)。因此,选择了i
中的A
。这是为什么?如果我们稍微修改一下这个例子,我们就会明白为什么:
class A {
int i = 100;
}
class B extends A {
String i = "Hello";
}
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
A a = new B();
int i = a.i;
System.out.println(i);
String s = ((B) a).i;
System.out.println(s);
}
}
在此示例中,B
再次隐藏了i
中的成员A
。但这一次,这些领域有不同的类型。然而,无论何时访问i
中的成员A
,您都需要int
,而不是String
。这就是静态类型决定选择哪个成员的原因。
问题3:
class A {
{
System.out.println(1);
}
}
class B extends A {
{
System.out.println(2);
}
}
class C extends B {
{
System.out.println(3);
}
}
public class MainClass {
public static void main(String[] args) {
C c = new C();
}
}
为此,我们需要了解三件事:
this(...)
也不是super(...)
,那么它是隐式的super();
。我们可以从这三个陈述中得出什么结论?如果我们初始化任何对象,我们必须首先执行超类构造函数。这会导致您尝试初始化为Object
的类型的构造函数级联。因此,我们按顺序看到输出:
1
2
3
问题7:
class A {
public A() {
System.out.println("Class A Constructor");
}
}
class B extends A {
public B() {
System.out.println("Class B Constructor");
}
}
class C extends B {
public C() {
System.out.println("Class C Constructor");
}
}
public class MainClass {
public static void main(String[] args) {
C c = new C();
}
}
这个问题的答案已经通过我对最后一个问题的回答得到了回答:如果构造函数的第一个语句既不是this(...)
也不是super(...)
,那么它隐含super()
。因此,从C
的构造函数中我们调用B
的构造函数,并从B
的构造函数中调用A
的构造函数。所以我们再次按顺序获取输出:
Class A Constructor
Class B Constructor
Class C Constructor