简体   繁体   English

在Java中将子类的对象创建为超类的实例

[英]Creating objects of a subclass as instances of the superclass in Java

say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me): 例如,我有以下代码(这是一个测验问题,因此我可以在IDE中运行它,但是我不清楚它的工作逻辑):

public class Test {

    public static void main(String[] args){
        A aInstance1 = new A();
        A aInstance2 = new B();
        A aInstance3 = new C();
        aInstance1.doSth();
        aInstance2.doSth();
        aInstance3.doSth();
    }
}

class A {
    public static void doSth(){
        System.out.println("Doing something in A");
    }
}
class B extends A {
    public static void doSth(){
        System.out.println("Doing something in B");
    }
}

class C extends B {
    public static void doSth(){
        System.out.println("Doing something in C");
    }
}

The output will be the following: 输出将如下所示:

Doing something in A 用A做某事

Doing something in A 用A做某事

Doing something in A 用A做某事

Thus, my first question is: what is the meaning of the declaration like 因此,我的第一个问题是:声明的含义是什么

A aInstance2 = new B();

ie, why to create an object of class B declaring it as an instance of class A? 即,为什么要创建一个将其声明为类A的实例的类B的对象? How the properties of aInstance2 as an object of class B change compared to the declaration 与声明相比,作为B类对象的aInstance2的属性如何变化

B aInstance2 = new B();

?

If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to 如果我从类A,B和C的doSth()方法的声明中删除了static一词,则输出更改为

Doing something in A 用A做某事

Doing something in B 用B做某事

Doing something in C 用C做某事

Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). 因此,当方法是静态的时,类A的doSth()方法不会被子类的方法覆盖,并且输出始终是由不同类的对象生成的“在A中做某事” ,而当它变成一个实例(非静态)方法,它会被覆盖(如果我在这里使用正确的术语)。 Why is it so? 为什么会这样呢?

Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ". 删除“静态”一词,就是在进行动态绑定,因为您几乎在说:“即使我知道该对象的类型为A,我也希望它的行为类似于B”。

Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A. 添加单词static意味着您正在将该方法作为类[引用类型]的一部分,并且每次调用:“ A dosmth()”时,他知道它仅适用于A,因此它显示了该类的方法的结果一种。

As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle. 至于您要怎么做?当我决定去参加面试时,我从学校中学到了这一功能,并进行了进一步研究;这是面试官想看一下您是否可以处理的事情之一。

If you don't mind I will post a link with information about Static and Dynamic Binding http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html 如果您不介意,我将发布一个链接,其中包含有关静态和动态绑定的信息,网址为http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html

Because static method is based on Reference type . 因为静态方法基于引用类型

aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();

So internally it converts into : 因此在内部它将转换为:

A.doSth();
A.doSth();
A.doSth();

Static methods are class methods while non-static ones are instance methods. 静态方法是类方法,而非静态方法是实例方法。 Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. 因此,在实例上调用静态方法时,实际上是在该实例的声明类型上调用它。 So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A. 因此,以下所有调用实际上都执行相同的调用: A.doSth()因为所有实例都声明为类型A。

aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();

When you remove the static keyword, doSth() method becomes an instance method. 当您删除static关键字时, doSth()方法将成为实例方法。 Instance methods are performed over objects instead of classes. 实例方法是在对象而不是类上执行的。 Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. 此外,当您在子类中重新声明实例方法时,该方法将被子类覆盖。 In your example, class B and C override doSth() . 在您的示例中,类B和C覆盖doSth() Thus, each class provides its own implementation. 因此,每个类都提供自己的实现。

Overriding depends on having an instance of a class. 覆盖取决于拥有类的实例。 A static method is not associated with any instance of a class so the concept is not applicable. 静态方法未与类的任何实例相关联,因此该概念不适用。

Making static methods works faster, because there's no need to wait until run-time to figure out which method to call. 使静态方法工作起来更快,因为不需要等到运行时就知道要调用哪个方法。

Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it. 用Java 重写只是意味着将根据对象的运行时类型而不是对象的编译时类型来调用特定方法。

Illustration - 插图-

  • When doSth() is static: 当doSth()为静态时:

     A aInstance1 = new A(); A aInstance2 = new B(); A aInstance3 = new C(); aInstance1.doSth(); aInstance2.doSth(); aInstance3.doSth(); 

In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding. 在上面的代码中,编译器将在编译时决定不加任何实例应调用A。

  • When doSth() is not static: 如果doSth()不是静态的:

     A aInstance1 = new A(); A aInstance2 = new B(); A aInstance3 = new C(); aInstance1.doSth(); aInstance2.doSth(); aInstance3.doSth(); 

In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances. 在上面的代码中,编译器将在运行时确定该方法不是静态的,并应由相应的实例覆盖。

静态方法处于class级别,并且作用于引用类型(==的LHS),与实例级别方法不同,实例级方法是根据实例类型(==的RHS)动态调度的

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

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