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 类有以下两个更改可以修复上述程序。
- 删除参数化构造函数。
- 添加一个没有任何参数的构造函数。