Java super关键字,super
关键字指的是直接父类的对象。在学习super
关键字之前,您必须具备 Java 中继承的知识,以便您能够理解本指南中给出的示例。
使用super
关键字
1)当父类和子类都具有相同名称的成员时访问父类的数据成员
2)显式调用父类的无参和参数化构造函数
3)访问父类的方法当子类重写该方法时的类。
现在让我们借助示例详细讨论它们:
如何使用super
关键字访问父类的变量
当子类中的变量已存在于父类中时,为了访问父类的变量,您需要使用super
关键字。
让我们举一个例子来理解这一点:在下面的程序中,我们在子类中声明了一个数据成员num
,父类中已经存在同名的成员。如果不使用super
关键字,则无法访问父类的num
变量。 。
//Parent class or Superclass or base class
class Superclass
{
int num = 100;
}
//Child class or subclass or derived class
class Subclass extends Superclass
{
/* The same variable num is declared in the Subclass
* which is already present in the Superclass
*/
int num = 110;
void printNumber(){
System.out.println(num);
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printNumber();
}
}
输出:
110
访问父类的num
变量:
通过调用这样的变量,如果类(父类和子类)具有相同的变量,我们可以访问父类的变量。
super.variable_name
让我们采用我们在上面看到的相同示例,这次在print
语句中我们传递super.num
而不是num
。
class Superclass
{
int num = 100;
}
class Subclass extends Superclass
{
int num = 110;
void printNumber(){
/* Note that instead of writing num we are
* writing super.num in the print statement
* this refers to the num variable of Superclass
*/
System.out.println(super.num);
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printNumber();
}
}
输出:
100
正如您通过使用super.num
所看到的,我们访问了父类的num
变量。
使用super
关键字来调用父类的构造函数
当我们创建子类的对象时,new
关键字调用子类的构造函数,它隐式调用父类的构造函数。因此,当我们创建子类的对象时执行的顺序是:首先执行父类构造函数,然后执行子类构造函数。这是因为编译器本身添加了super()
(这会调用父类的无参数构造函数)作为子类构造函数中的第一个语句。
让我们看一个例子来理解我上面解释的内容:
class Parentclass
{
Parentclass(){
System.out.println("Constructor of parent class");
}
}
class Subclass extends Parentclass
{
Subclass(){
/* Compile implicitly adds super() here as the
* first statement of this constructor.
*/
System.out.println("Constructor of child class");
}
Subclass(int num){
/* Even though it is a parameterized constructor.
* The compiler still adds the no-arg super() here
*/
System.out.println("arg constructor of child class");
}
void display(){
System.out.println("Hello!");
}
public static void main(String args[]){
/* Creating object using default constructor. This
* will invoke child class constructor, which will
* invoke parent class constructor
*/
Subclass obj= new Subclass();
//Calling sub class method
obj.display();
/* Creating second object using arg constructor
* it will invoke arg constructor of child class which will
* invoke no-arg constructor of parent class automatically
*/
Subclass obj2= new Subclass(10);
obj2.display();
}
}
输出:
Constructor of parent class
Constructor of child class
Hello!
Constructor of parent class
arg constructor of child class
Hello!
参数化的super()
调用来调用父类的参数化构造函数
我们可以在子类的构造函数中显式调用super()
,但它没有任何意义,因为它会是多余的。这就像明确地做一些其他方式隐含的事情。
但是当我们在父类中有一个带有参数的构造函数时,我们可以使用参数化的超类,如super(100);
从子类的构造函数中调用父类的参数化构造函数。
让我们看一个例子来理解这个:
class Parentclass
{
//no-arg constructor
Parentclass(){
System.out.println("no-arg constructor of parent class");
}
//arg or parameterized constructor
Parentclass(String str){
System.out.println("parameterized constructor of parent class");
}
}
class Subclass extends Parentclass
{
Subclass(){
/* super() must be added to the first statement of constructor
* otherwise you will get a compilation error. Another important
* point to note is that when we explicitly use super in constructor
* the compiler doesn't invoke the parent constructor automatically.
*/
super("Hahaha");
System.out.println("Constructor of child class");
}
void display(){
System.out.println("Hello");
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.display();
}
}
输出:
parameterized constructor of parent class
Constructor of child class
Hello
在这个例子中有几点需要注意:
1)super()
(或参数化的super
必须是构造函数中的第一个语句,否则你将得到编译错误:“构造函数调用必须是构造函数中的第一个语句”
2)当我们在构造函数中明确地放置super
时,java 编译器没有调用父类的默认无参构造函数。
如何在方法覆盖的情况下使用super
关键字
当子类声明父类中已存在的相同方法时,这称为方法覆。我们将在本系列的下一个教程中学习方法覆盖。现在您只需要记住这一点:当子类重写父类的方法时,从子类对象调用该方法总是调用该方法的子类版本。但是通过使用这样的super
关键字:super.method_name
可以调用父类的方法(被覆盖的方法)。在方法覆盖的情况下,使用这些术语:重写方法:父类的方法重写方法:子类的方法让我们举一个例子来理解这个概念:
class Parentclass
{
//Overridden method
void display(){
System.out.println("Parent class method");
}
}
class Subclass extends Parentclass
{
//Overriding method
void display(){
System.out.println("Child class method");
}
void printMsg(){
//This would call Overriding method
display();
//This would call Overridden method
super.display();
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printMsg();
}
}
输出:
Child class method
Parent class method
如果子类没有覆盖任何方法怎么办:不需要super
当子类没有覆盖父类方法时,我们不需要使用super
关键字来调用父类方法。这是因为在这种情况下我们只有每个方法的一个版本,子类可以访问父类方法,所以我们可以直接调用父类的方法而不使用super
。
class Parentclass
{
void display(){
System.out.println("Parent class method");
}
}
class Subclass extends Parentclass
{
void printMsg(){
/* This would call method of parent class,
* no need to use super keyword because no other
* method with the same name is present in this class
*/
display();
}
public static void main(String args[]){
Subclass obj= new Subclass();
obj.printMsg();
}
}
输出:
Parent class method