Java 理解继承有点困难吗?(爪哇)

Java 理解继承有点困难吗?(爪哇),java,inheritance,Java,Inheritance,我一直试图用java教自己继承,但我真的很困惑,在线youtube视频/查看前面的问题似乎毫无帮助。我在这个网站上尝试了练习题:,但我在问题2、3和7上遇到了问题 在问题2中,既然对象a的构造函数是B(),为什么它不打印类B的i值而不是类a的i值?相反,它打印的是a级,我不知道为什么 在问题3中,程序打印1 2 3的原因是因为没有构造函数,它只是函数吗?我知道,当你从一个类继承时,你基本上就像它的所有函数都在子类中一样,所以你基本上只是假装C类说: 系统输出打印项次(1) 系统输出打印ln(2)

我一直试图用java教自己继承,但我真的很困惑,在线youtube视频/查看前面的问题似乎毫无帮助。我在这个网站上尝试了练习题:,但我在问题2、3和7上遇到了问题

在问题2中,既然对象a的构造函数是B(),为什么它不打印类B的i值而不是类a的i值?相反,它打印的是a级,我不知道为什么

在问题3中,程序打印1 2 3的原因是因为没有构造函数,它只是函数吗?我知道,当你从一个类继承时,你基本上就像它的所有函数都在子类中一样,所以你基本上只是假装C类说:

系统输出打印项次(1)

系统输出打印ln(2)

系统输出打印Ln(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);
    }
}
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();
    }
}
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();
    }
}
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();
    }
}
Q2)
Java语言的多态性行为与方法而不是成员变量一起工作:他们设计的语言在编译时绑定成员变量,在运行时绑定方法

Q3)
它被称为。子类的每个实例都隐式包含其超类的一个实例。因此,呼叫顺序从
A类
B类
开始,然后是
C类


Q7)
Q3的原因同样适用于这个问题

首先,我认为您应该看看Oracle的Java教程,主要是on和on教程


让我们从问题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);
    }
}
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
中,您编写
aaa=newb()
,即
a
的静态类型为
a
a
的运行时类型为
B
。当您现在访问成员时,静态类型决定选择哪个成员(
A
B
)。因此,选择
A
中的
i
。为什么呢?如果我们稍微修改一下示例,我们就会看到原因:

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
再次在
A
中隐藏成员
i
。但这一次,字段的类型不同。然而,无论何时访问
A
中的成员
i
,都需要
int
,而不是
字符串。这就是静态类型决定选择哪个成员的原因


问题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();
    }
}
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()
  • 类的初始值设定项在超类构造函数之后,但在自己的构造函数之前执行
我们可以从这三种说法中得出什么结论?如果我们初始化任何对象,首先必须执行超类构造函数。这将导致从您尝试初始化的类型到
对象
的构造函数级联。因此,我们按顺序查看输出:

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();
    }
}
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

你能把网站上的问题包括在你的问题中吗?(人们不太可能点击链接,如果链接坏了,这个问题就不需要回答了。)2)基本上是因为你不能覆盖字段。3) 这些是静态初始值设定项块,我不知道执行它们的确切条件,但顺序似乎正确,7)因为您仍然必须在
B
A
中设置字段,并且它们通过隐式
super()
调用,它是“插入的”在所有三个无参数构造函数中。@GBlodgett感谢您的建议!我更新了这个问题。@luk2302,所以任何时候一个类从另一个类继承,在它的构造函数中都有一个“super()”函数,你看不到吗?(基本上,只要你调用子类的构造函数,就会调用超类构造函数?如果你没有自己在那里写
super(…)
this(…)
,那么肯定会有一个“不可见的”
super()
,您总是需要调用父类的构造函数。这开始为我清除了很多问题,谢谢!假设我通过以下操作创建一个对象:a object=new C(),基本上,对象的函数被视为C的函数,因为它被类C重写,但它的变量是由?@vp123定义的。谢谢!我想我现在已经知道了。相反,如果我通过执行C object=new C()创建对象的实例;,它的变量和函数是由C定义的,但是它的构造函数中仍然有一个不可见的super(),所以如果类A和类B构造函数中有System.out.println(),它也会打印它们,对吗?@vp123,是的,有
super()
隐式调用。