简体   繁体   English

有人可以解释一下这个小代码吗?

[英]Can someone explain me this little code?

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

In the output of the console I get this: 在控制台的输出中,我得到以下信息:

feline
cougar
cc

I am not sure why I get this output if I am creating a Cougar object and the constructor of the cougar class does not make a super call to the feline class constructor, also I don't understand why I get "CC" when calling the go() method. 我不确定为什么要创建Cougar对象并且cougar类的构造函数没有对feline类构造函数进行超级调用,为什么会得到此输出,我也不明白为什么在调用该类时会得到“ CC” go()方法。 Sorry if it's a very basic question but I will appreciate your help. 抱歉,这是一个非常基本的问题,但我会感谢您的帮助。

Java objects are constructed from the inside out: When you say new Cougar() , first space is allocated for the object, then a Feline object is constructed in that space by calling a Feline constructor, then finally your Cougar constructor is run. Java对象是由内而外构造的:当您说new Cougar() ,首先为该对象分配了空间,然后通过调用Feline构造函数在该空间中构造了Feline对象,最后运行了Cougar构造函数。

You can specify which Cougar constructor is run by calling it explicitly with a super(..) call; 您可以通过super(..)调用显式调用它来指定运行哪个 Cougar构造函数。 that's particularly useful if there are several and you want to pick one by specifying arguments. 如果有多个,并且您想通过指定参数来选择一个,则该功能特别有用。 But if you don't invoke one, the compiler will insert the super() call. 但是,如果您不调用一个,编译器将插入super()调用。

As to the 'cc', when type = "c"; 至于'cc',当type = "c"; was encountered, there was no local variable named "type" defined. 遇到,没有定义名为“ type”的局部变量。 That means it's a member variable, so the compiler interprets that as this.type = "c"; 这意味着它是一个成员变量,因此编译器将其解释为this.type = "c"; . But there's only one member called "type", and that's in Cougar. 但是只有一个成员称为“类型”,而这个成员在Cougar中。 So this.type and super.type are both the same thing, have been set to "c", and "c" is typed twice. 因此this.typesuper.type都是同一件事,已被设置为“ c”,并且“ c”被键入两次。

You have created two classes where Feline is a super class and Cougar is a child class. 您创建了两个类,其中Feline是超类,而Cougar是子类。 As Cougar extends Feline , Cougar inherits type variable from Feline . Cougar扩展FelineCougar继承了Feline type变量。

Now, Feline has a default constructor where feline string is printed. 现在, Feline具有默认的构造函数,其中会打印feline字符串。 Cougar also has a default constructor. Cougar还具有默认构造函数。 As per the line new Cougar().go(); 按照这一行new Cougar().go(); in the main method, you are creating a new object of Cougar which calls the default constructor and implicitly, it calls super() that calls the constructor of Feline class. main方法中,您正在创建一个Cougar的新对象,该对象将调用默认构造函数,并隐式地调用super()来调用Feline类的构造函数。

Now new Cougar().go() method is setting the type to "c" which means the value of the variable is changed as super.type and this.type are the same copy. 现在, new Cougar().go()方法将类型设置为"c" ,这意味着将变量的值更改为super.typethis.type是同一副本。 So when you call this method, it prints this way: 因此,当您调用此方法时,它的打印方式如下:

feline 猫科动物

cougar 美洲狮

cc 抄送

In the main(), when you are creating the object new Cougar() then the constructor public Cougar() is called which inturn calls parent constructor public Feline() 在main()中,当您创建对象new Cougar()时,将调用构造函数public Cougar(),从而依次调用父构造函数public Feline()

hence first sout of Feline() feline is displayed on console and then sout of Cougar() cougar is displayed on console. 因此,首先在控制台上显示Feline()的feline ,然后在控制台上显示Cougar()的cougar

This is popularly known as Instance Control flow in java. 在Java中,这通常称为“ Instance Control flow

Then cc is displayed in the output because of go() method, as "type" variable of both this operator and super operator points to "c". 然后,由于go()方法,cc在输出中显示,因为此运算符和超级运算符的“ type”变量都指向“ c”。

Hence, the output is: 因此,输出为:
feline //because parent constructor is called first in Instance Control Flow. 猫科动物//因为在实例控制流中首先调用了父构造函数。
cougar //because child constructor is called after parent constructor. cougar //因为在父构造函数之后调用了子构造函数。
cc // since type variable of both this instance and super instance points to "c" object. cc //因为此实例和超级实例的类型变量都指向“ c”对象。

When you are creating child object. 创建子对象时。 It automatically call the parent constructor because parent need to initialized for child. 它会自动调用父级构造函数,因为父级需要为子级初始化。

So, when child class constructor is called it automatically call the parent default/non parameter constructor.ie o/p feline cougar 因此,当子类构造函数被调用时,它会自动调用父默认/非参数构造函数。即o / p feline cougar

and .go() is changing the value of this.type and super.type and this is representing same value. .go()更改this.type和super.type的值,并且表示相同的值。 because type variable is visibility is public, It also accessible in child class and there is no variable in child class with variable name of type. 因为类型变量是可见性是公共的,所以它也可以在子类中访问,并且在子类中没有类型为变量名的变量。

So, The complete o/p is 因此,完整的o / p为

feline cougar cc 猫美洲狮cc

According to your code: There is a parent class called "Feline" and child class called "Cougar". 根据您的代码:有一个称为“猫科动物”的父类和一个名为“ Cougar”的子类。 when it execute, It first go to the parent/super class(Feline) constructor and print : feline. 当它执行时,它首先转到父/父类(Feline)构造函数并打印:feline。

Then it executes the child class (Cougar) constructor and print : cougar. 然后,它执行子类(Cougar)的构造函数并打印:cougar。

After that it executes the main method; 之后,它执行main方法; In your main method you are referring to another method called "go", then executes the code inside "go" method: 在您的主要方法中,您引用的是另一个称为“ go”的方法,然后在“ go”方法中执行代码:

Inside that it overriding the value of variable called "type" to : "C". 在其中,它将名为“ type”的变量的值覆盖为:“ C”。

So when you are going to print the value of type, 因此,当您要打印类型的值时,

this.type = C and super.type = C (because of the overriding) this.type = C和super.type = C(由于覆盖)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM