📜  Java程序的输出|设置 2

📅  最后修改于: 2022-05-13 01:55:47.499000             🧑  作者: Mango

Java程序的输出|设置 2

预测以下Java程序的输出。

问题一:

Java
package main;
 
class Base {
    public void Print()
    {
        System.out.println("Base");
    }
}
 
class Derived extends Base {
    public void Print()
    {
        System.out.println("Derived");
    }
}
 
class Main {
    public static void DoPrint(Base o)
    {
        o.Print();
    }
    public static void main(String[] args)
    {
        Base x = new Base();
        Base y = new Derived();
        Derived z = new Derived();
        DoPrint(x);
        DoPrint(y);
        DoPrint(z);
    }
}


Java
package main;
 
// filename Main.java
class Point {
    protected int x, y;
 
    public Point(int _x, int _y)
    {
        x = _x;
        y = _y;
    }
}
 
public class Main {
    public static void main(String args[])
    {
        Point p = new Point();
        System.out.println("x = " + p.x + ", y = " + p.y);
    }
}


输出:

Base
Derived
Derived

预测第一行输出很容易。我们创建一个 Base 类型的对象并调用 DoPrint()。 DoPrint 调用 print函数,我们得到第一行。

DoPrint(y) 导致第二行输出。与 C++ 一样,在Java中允许将派生类引用分配给基类引用。因此,表达式 Base y = new Derived() 在Java中是有效的语句。在 DoPrint() 中,o 开始引用与 y 引用的对象相同的对象。此外,与 C++ 不同,函数在Java中默认是虚拟的。因此,当我们调用 o.print() 时,会调用 Derived 类的 print() 方法,因为Java中默认存在运行时多态性。

DoPrint(z) 导致第三行输出,我们传递一个 Derived 类型的引用,并再次调用 Derived 类的 print() 方法。这里要注意的一点是:与 C++ 不同,对象切片不会发生在Java中。因为非原始类型总是通过引用分配。

问题2:

Java

package main;
 
// filename Main.java
class Point {
    protected int x, y;
 
    public Point(int _x, int _y)
    {
        x = _x;
        y = _y;
    }
}
 
public class Main {
    public static void main(String args[])
    {
        Point p = new Point();
        System.out.println("x = " + p.x + ", y = " + p.y);
    }
}

输出:

Compiler Error

在上面的程序中,没有访问权限问题,因为Point和Main在同一个包中,一个类的受保护成员可以在同一个包的其他类中访问。代码的问题是: Point 中没有默认构造函数。

与 C++ 一样,如果我们编写自己的参数化构造函数,那么Java编译器不会创建默认构造函数。因此,Point 类有以下两个更改可以修复上述程序。

  1. 删除参数化构造函数。
  2. 添加一个没有任何参数的构造函数。