自学内容网 自学内容网

Java学习教程,从入门到精通,Java中super关键字的语法知识点及案例(31)

Java中super关键字的语法知识点及案例

1. 定义

super是Java中的一个关键字,主要用于引用当前对象的父类或超类。通过super,可以在子类中访问父类的成员变量、方法和构造函数。

2. 主要用途
  • 访问父类的成员变量:当子类与父类有同名的成员变量时,可以使用super关键字来明确访问父类的成员变量。
  • 调用父类的构造方法:在子类的构造方法中,可以使用super关键字来调用父类的构造方法,以初始化父类的成员变量或执行父类构造函数的逻辑。
  • 调用父类的方法:在子类中,可以通过super关键字调用父类的方法,特别是在子类重写了父类的方法时,仍然可以通过super来调用父类的方法。
3. 使用场景与注意事项
  • 构造方法中的使用:super()只能出现在子类构造方法的第一行,用于调用父类的构造方法。如果子类构造方法中没有显式调用super()或this(),系统会默认调用父类的无参数构造方法。
  • 不能用于静态方法:super关键字不能用于静态方法中。
  • this()和super()不能共存:在构造方法中,this()和super()不能同时出现,它们都是只能出现在构造方法的第一行。
4. 案例代码

案例一:访问父类的成员变量

class Parent {
    int x = 10;
}

class Child extends Parent {
    int x = 20;
    void display() {
        System.out.println(super.x); // 访问父类的x变量,输出10
        System.out.println(this.x);  // 访问子类的x变量,输出20
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.display();
    }
}

案例二:调用父类的构造方法

class Parent {
    int x;
    Parent(int x) {
        this.x = x;
    }
}

class Child extends Parent {
    int y;
    Child(int x, int y) {
        super(x); // 调用父类构造函数,将x赋值
        this.y = y;
    }

    @Override
    public String toString() {
        return "Child{" + "y=" + y + ", x=" + x + '}';
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child(10, 20);
        System.out.println(child.toString());
    }
}

案例三:调用父类的方法

class Parent {
    void print() {
        System.out.println("Parent's print method");
    }
}

class Child extends Parent {
    @Override
    void print() {
        super.print(); // 调用父类的print方法
        System.out.println("Child's print method");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.print();
    }
}

案例四:子类与父类有同名的成员变量

class Animal {
    String name = "Animal";
}

class Dog extends Animal {
    String name = "Dog";

    void printNames() {
        System.out.println(super.name); // 输出父类Animal的name
        System.out.println(this.name);  // 输出子类Dog的name
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.printNames();
    }
}

案例五:子类构造方法调用父类构造方法并初始化成员变量

class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + " is eating");
    }
}

class Dog extends Animal {
    String breed;

    public Dog(String name, String breed) {
        super(name); // 调用父类Animal的构造方法
        this.breed = breed;
    }

    public void bark() {
        System.out.println(name + " is barking");
    }

    @Override
    public void eat() {
        super.eat(); // 调用父类Animal的eat方法
        System.out.println(name + " is eating bones");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Rex", "Labrador");
        dog.eat(); // 调用子类Dog的eat方法
        dog.bark(); // 调用子类Dog的bark方法
    }
}

通过以上案例代码,可以更清晰地理解super关键字在Java中的使用方法和场景。

当然可以,以下是一些额外的关于super关键字的例子,这些例子将展示super在不同情境下的应用。

例子一:在多重继承链中使用super

虽然Java不支持多重继承(即一个类不能同时继承多个类),但可以通过继承的传递性(一个类继承自另一个已经继承自其他类的类)来模拟多重继承的效果。在这种情况下,super可以用来引用直接父类或更远的祖先类。

class Grandparent {
    void display() {
        System.out.println("Grandparent display()");
    }
}

class Parent extends Grandparent {
    @Override
    void display() {
        System.out.println("Parent display()");
    }
}

class Child extends Parent {
    @Override
    void display() {
        super.display(); // 调用直接父类Parent的display()
        // 如果想调用Grandparent的display(),可以使用以下方式(但不直接通过super)
        // ((Grandparent)this).display(); // 强制类型转换,不推荐这样做,因为它破坏了封装性
        // 一个更好的做法是在Parent类中调用Grandparent的display()
    }

    void callGrandparentDisplay() {
        // 在这里,我们假设Parent类已经正确地调用了Grandparent的display()
        super.display(); // 这将调用Parent的display(),而Parent可以进一步调用Grandparent的
    }
}

// 注意:在Child类中直接调用Grandparent的display()通常不是最佳实践。
// 更好的做法是在Parent类中处理这种调用,或者在Child类中通过其他方式(如方法参数、组合等)来实现。

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.display(); // 输出:Parent display()
        // child.callGrandparentDisplay(); // 这将仍然输出:Parent display(),因为Parent没有调用Grandparent的
    }
}

// 为了完整性,我们可以修改Parent类来正确调用Grandparent的display()
class ParentExtended extends Grandparent {
    @Override
    void display() {
        super.display(); // 现在Parent调用了Grandparent的display()
        System.out.println("Parent display() after calling Grandparent");
    }
}

// 然后让Child继承ParentExtended而不是Parent
// class ChildExtended extends ParentExtended { ... }

// 注意:上面的代码示例是为了说明目的而编写的,并没有完整地展示多重继承链中super的使用。
// 在实际编程中,你应该避免直接操作远祖类的方法,而是通过设计良好的继承层次结构来间接实现。

注意:上面的代码示例中关于直接调用Grandparentdisplay()方法的注释部分并不是最佳实践。在实际编程中,你应该避免在子类中直接调用远祖类的方法,因为这可能会破坏封装性和代码的可维护性。相反,你应该通过设计良好的继承层次结构来间接实现这一功能,比如让Parent类调用Grandparent类的方法,并在Child类中通过super来调用Parent类的方法。

例子二:在方法覆盖中使用super来保持父类行为

当子类覆盖父类的方法时,如果仍然想保留父类方法的行为,可以在子类方法内部调用super来实现。

class Animal {
    void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        super.makeSound(); // 调用父类的makeSound()方法
        System.out.println("Woof! Woof!"); // 添加子类特有的行为
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound(); // 输出:Some generic animal sound\nWoof! Woof!
    }
}

在这个例子中,Dog类覆盖了Animal类的makeSound()方法,但在覆盖的方法中仍然调用了父类的makeSound()方法,以保留父类的行为,并添加了子类特有的行为。

这些例子应该能帮助你更好地理解super关键字在Java中的使用。

super关键字在Java编程中有多个重要的应用场景,以下是其主要应用场景的归纳:

1. 调用父类构造方法

  • 在子类的构造方法中,可以使用super()来调用父类的构造方法。这是确保父类属性被正确初始化的关键步骤。
  • super()调用必须在子类构造方法的第一行,且一个构造方法中只能有一个super()调用。

2. 访问父类成员变量

  • 当子类中定义了一个与父类同名的成员变量时,可以使用super关键字来引用父类的成员变量。
  • 这有助于在子类中区分和访问父类与子类的同名变量。

3. 调用父类方法

  • 如果子类覆盖了父类的方法,但仍然想调用父类的方法,可以使用super.method_name()语法。
  • 这在保留父类行为的同时,允许子类添加或修改特定的行为。

4. 表示父类类型的引用

  • 在子类的实例方法中,super可以作为一个引用变量来使用,它引用了当前对象的父类类型。
  • 这使得子类可以像操作父类实例一样调用其方法或访问其属性。

5. 在多重继承模拟中的使用(虽然不是直接多重继承)

  • 虽然Java不支持多重继承,但可以通过类的层次结构来模拟多重继承的效果。
  • 在这种情况下,super可以用来引用直接父类,而父类可以进一步引用其祖先类。
  • 然而,直接操作远祖类的方法通常不是最佳实践,更好的做法是通过设计良好的继承层次结构来间接实现。

示例代码

以下是一些示例代码,展示了super关键字在不同应用场景中的使用:

// 示例1:调用父类构造方法
class Parent {
    int number;
    Parent(int number) {
        this.number = number;
    }
}

class Child extends Parent {
    String name;
    Child(int number, String name) {
        super(number); // 调用父类的构造方法
        this.name = name;
    }
}

// 示例2:访问父类方法
class Animal {
    void makeSound() {
        System.out.println("Some generic animal sound");
    }
}

class Dog extends Animal {
    @Override
    void makeSound() {
        super.makeSound(); // 调用父类的方法
        System.out.println("Woof! Woof!");
    }
}

// 示例3:访问父类变量
class ParentClass {
    int value = 10;
}

class ChildClass extends ParentClass {
    int value = 20;
    void printValues() {
        System.out.println("Parent's value: " + super.value); // 访问父类的变量
        System.out.println("Child's value: " + this.value);
    }
}

综上所述,super关键字在Java编程中扮演着重要角色,它允许子类直接访问和操作父类的成员,有助于实现代码的重用和多态性。


原文地址:https://blog.csdn.net/qq_45746668/article/details/143821868

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!