Java 有人能给我解释一下这个小代码吗?

Java 有人能给我解释一下这个小代码吗?,java,Java,在控制台的输出中,我得到: class Feline { public String type = "f"; public Feline() { System.out.println("feline"); } } public class Cougar extends Feline { public Cougar() { System.out.println("cougar"); } void go() {

在控制台的输出中,我得到:

class Feline {
    public String type = "f";

    public Feline() {
        System.out.println("feline");
    }
}

public class Cougar extends Feline {

    public Cougar() {
        System.out.println("cougar");
    }

    void go() {
        type = "c";
        System.out.println(this.type + super.type);
    }

    public static void main(String[] args) {
        new Cougar().go();
    }
}

如果我正在创建一个Cougar对象,而Cougar类的构造函数没有超级调用猫类构造函数,我不知道为什么会得到这个输出,我也不明白为什么调用go()方法时会得到“C C”。很抱歉,如果这是一个非常基本的问题,但我将感谢您的帮助。

Java对象是由内而外构造的:当您说
new Cougar()
时,首先为对象分配空间,然后通过调用猫构造函数在该空间中构造猫对象,最后运行你的Cougar构造函数

通过使用
super(..)
调用显式调用,可以指定运行哪个Cougar构造函数;如果有多个参数,并且您希望通过指定参数来选择一个参数,那么这一点特别有用。但是如果不调用,编译器将插入
super()
调用


至于“cc”,当
type=“c”时,未定义名为“type”的局部变量。这意味着它是一个成员变量,因此编译器将其解释为
this.type=“c”。但是只有一个成员叫做“类型”,那就是美洲狮。所以
this.type
super.type
都是相同的东西,都被设置为“c”,并且“c”被键入了两次。

您创建了两个类,其中
Feline
是一个超类,
Cougar
是一个子类。随着
Cougar
扩展
Feline
Cougar
Feline
继承
type
变量

现在,
Feline
有一个默认构造函数,其中打印了
Feline
字符串
Cougar
也有一个默认构造函数。按照行
newcougar().go()
main
方法中,您正在创建一个
Cougar
的新对象,该对象调用默认构造函数,并隐式调用调用
super()
super()
对象,该对象调用
Feline
类的构造函数

现在
new Cougar().go()
方法正在将类型设置为
“c”
,这意味着变量的值被更改为
super。type
this.type
是相同的副本。因此,当您调用此方法时,它将按如下方式打印:

猫科动物

美洲狮

抄送

在main()中,当您创建对象new Cougar()时,将调用构造函数public Cougar(),inturn将调用父构造函数public Feline()

因此,控制台上首先显示猫科动物的头(
Feline
),然后显示美洲狮的头(
Cougar

这在java中通常被称为
实例控制流

然后,由于go()方法,cc显示在输出中,因为此运算符和超级运算符的“type”变量都指向“c”

因此,输出为:
猫//因为父构造函数是在实例控制流中首先调用的。
cougar//因为子构造函数在父构造函数之后调用。

cc//因为此实例和超级实例的类型变量都指向“c”对象。

当您创建子对象时。它会自动调用父构造函数,因为父构造函数需要为子构造函数初始化

因此,当调用子类构造函数时,它会自动调用父类默认/非参数构造函数。猫科美洲狮

.go()正在更改this.type和super.type的值,这表示相同的值。因为类型变量是公共的,所以它也可以在子类中访问,并且子类中没有变量名为类型的变量

因此,完整的o/p是

猫美洲狮


根据您的代码:有一个父类叫做“猫”,子类叫做“美洲狮”。 当它执行时, 它首先转到父/超类(猫)构造函数并打印:猫

然后执行子类(Cougar)构造函数并打印:Cougar

然后执行main方法; 在main方法中,您指的是另一个名为“go”的方法, 然后在“go”方法中执行代码:

它将名为“type”的变量的值重写为:“C”

因此,当您要打印type的值时

this.type=C
super.type=C(因为重写)

是三行独立的输出吗?代码或输出有问题,是两行输出。像这样:猫叫声> C++调用猫< <代码> >构造函数是隐式的<代码>。类型< <代码> >代码>超级类型> /COD>两者都指相同的值。实际上这是不对的:“java对象是由内向外构造的”。对于Java,整个对象被创建为声明的类。然后(这是真的)构造函数从基类运行到最派生的类。但在运行这些构造函数的所有时间点上,类都是派生最多的类(与C++不同)。这意味着,当构造函数调用类的方法时,它们调用的是最派生类的方法。(在C++中,基类构造函数,调用虚拟类方法,调用基类的方法等等)。“Java对象是由内而外构造的”这句话可能不再是首选方式,但您可以在Campione和Walrath的“Java(TM)教程”第125页上找到它;不可否认,这是一本旧书。我同意我们在实际发生的事情上是一致的!我只是碰巧是C++的人,这就是全部-而且C++方式更有意义!(对我!还有其他C++的家伙!)
feline
cougar
cc