java - 对象初始化 - 构造函数与类类型和方法访问的关系

标签 java methods constructor initialization new-operator

我有以下代码:

package testapp;

class Calculation {

    public Calculation(){}

    public void addition(int x, int y) {   }

    public void Subtraction(int x, int y) {   }
}

class My_Calculation extends Calculation {

    public My_Calculation(){}

    public void multiplication(int x, int y) {   }
}

public class TestApp {

    public static void main(String[] args) {

        int a = 20, b = 10;

        My_Calculation demo = new My_Calculation();
        demo.addition(a, b);
        demo.Subtraction(a, b);
        demo.multiplication(a, b);
        System.out.println(demo.getClass().getName());

        Calculation d = new Calculation();
        d.Subtraction(b, b);
        d.addition(b, b);
        // no multiplication
        System.out.println(d.getClass().getName());

        Calculation d2 = new My_Calculation();
        d2.Subtraction(b, b);
        d2.addition(b, b);
        // no multiplication
        System.out.println(d2.getClass().getName());
    } 
}

输出是这样的:

demo = testapp.My_Calculation

d = testapp.Calculation

d2 = testapp.My_Calculation

下面的语句是引用变量名d2到对象类型计算的声明:

Calculation d2;

以下语句是调用 My_Calculation 构造函数的初始化。

Calculation d2 = new My_Calculation();

当我运行以下代码时,输​​出表明 d2 属于类类型 My_Calculation 但可以访问 Calculation 类 中的方法.

System.out.println(d2.getClass().getName());

输出:testapp.My_Calculation

访问:加法;减法

现在,我的理解告诉我,如果调用 My_Calculation 构造函数,我应该:

<强>1。仅访问乘法,或

<强>2。访问加法、减法和乘法。

但是,我实际上得到了相反的结果:只能访问加法和减法。因此,我认为这是违反直觉的。

有人可以向我解释这里发生了什么,让我对为什么类型:My_Calculation 的对象无法访问其自己的方法 但可以访问只有父类(super class)方法

最佳答案

这里:

Calculation d2 = new My_Calculation();

您创建了一个 My_Calculation 类型的对象,但是您将它分配给了一个用父类(super class)型声明的变量!而且编译器不够聪明,无法“看到”d2 实际上是子类型。因此,编译器 会阻止您调用在该子类型上定义的方法。因为对于编译器来说,d2 被认为是一个Calculation!

请注意,您可以转换 告诉编译器“我知道得更多”:

( (My_Calculation) d2) ).multiplication(...

这在编译时和运行时都有效!

你的误解从这里开始:

Calculation d2 = new My_Calculation();

你在作业的右侧所做的基本上会在下一行中“忘记”。然后编译器知道你有一些计算类型的d2!

最后:是的,在您的特定 示例中,编译器可以轻松确定d2真实 类型。但在很多情况下,这并不容易,甚至不可能。因此,Java 背后的人们决定忽略这种潜在的“知识”。

关于java - 对象初始化 - 构造函数与类类型和方法访问的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56348434/

相关文章:

c++ - 您可以将 "this"静态转换为基类构造函数中的派生类,然后稍后使用结果吗?

java - Jetty 9 HTTP客户端: How to get the request content?

javascript - 为在 Javascript/jQuery 中创建的类调用方法

python - 如何在 Python 中访问类成员变量?

Java for 循环[方法]

c++ - 类成员不是引用而是构造函数,参数通过引用传递

java - 与基类构造函数相比,什么时候调用 Java 隐式构造函数?

java - 如何减少 if 语句

java - 将可变数量的参数从一种方法中继到另一种方法(具有可变数量的参数)

java - Xstream 在输出中插入奇怪的标签