public class NewClass
{
public static class superclass
{
static void print()
{
System.out.println("print in superclass.");
}
}
public static class subclass extends superclass
{
static void print()
{
System.out.println("print in subclass.");
}
}
public static void main(String[] args)
{
superclass A = new superclass();
superclass B = new subclass(); //This line?
A.print();
B.print();
}
}
我在学习static binding from geeksforgeeks时遇到了这段代码。我无法理解这一行:
超类B =新的subclass();
不确定如何运行。基本上,我们是否要创建超类的对象并调用子类的构造函数?这对我来说没有多大意义,因为我一直都看过并且习惯于A obj = new obj();
类型的对象创建。
答案 0 :(得分:1)
在准备答案时,我发现必须以两种不同的含义来使用超类和子类。我将这些类重命名为Thing
和Car
,并在常规概念中使用单词“ superclass”和“ subclass”。
public class NewClass
{
public static class Thing
{
static void print()
{
System.out.println("print in superclass.");
}
}
public static class Car extends Thing
{
static void print()
{
System.out.println("print in subclass.");
}
}
public static void main(String[] args)
{
Thing A = new Thing();
Thing B = new Car(); //This line?
A.print();
B.print();
}
}
表达式new Car()
总是创建类型Car
的实例。总是。结果是{引用} Car
的实例。
现在,您可以将Car
实例的[引用]存储到允许Car
实例的任何类型的变量中。那就是:
Car
类型的变量,Car
的任何超类声明的变量(并且该变量与Thing B
声明匹配),Car
直接或间接实现的接口类型声明的变量。那么,代码行会发生什么
Thing B = new Car(); //This line?
它将创建一个新的Car
实例,因此当然会调用Car
构造函数(* 1)(* 2)。然后,它将对此实例的引用存储在变量B
中,该变量允许所有类型的Thing
实例,只要它们继承自Thing
并因此支持Thing
个对象。
那会发生什么
B.print();
它调用print()
引用的实例的B
方法。并且由于该实例是Car
实例,因此您得到的是Car.print()
结果,而不是Thing.print()
。
更多说明:
如果Car
在Thing
中找不到某些其他方法(例如drive()
方法),则编译器将不允许您在B
上调用它们,因为并非所有Thing
对象都有它们,只有某些专门的Thing
版本(即Car
版本)。
而且我建议您习惯Java命名约定,例如类名始终以大写字母开头,变量始终以小写字母开头。 Java专家已经习惯了这些约定,因此我们发现读取不遵循这些规则的代码确实令人困惑。
(* 1)在您的情况下,构造函数未明确定义,而是由Java编译器自动生成的。
(* 2)子类构造函数始终调用其超类的构造函数,以此类推,直到Object
构造器,以初始化该子类从其超类继承的实例的所有方面。