当前位置 : 主页 > 编程语言 > c语言 >

super关键字和方法重写

来源:互联网 收集:自由互联 发布时间:2023-09-07
1.super关键字介绍 super 代表父类的引用,用于访问父类的属性、方法、构造器 2.基本语法 297 代码在com.stulzl.super_.包中 父类A package com.stulzl.super_;public class A { //4 个属性 public int n1 = 100;

1.super关键字介绍

super 代表父类的引用,用于访问父类的属性、方法、构造器

2.基本语法 297

super关键字和方法重写_子类

代码在com.stulzl.super_.包中

父类A

package com.stulzl.super_;

public class A {
    //4 个属性
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    //无参构造器
    public A() {
    }

    public A(String name) {
    }

    public A(String name, int age) {
    }

    // public void cal() {
// System.out.println("A 类的 cal() 方法...");
// }
    public void test100() {

    }
    protected void test200() {

    }
    void test300() {

    }
    private void test400() {

    }
}

子类B

package com.stulzl.super_;

public class B extends A{
    //访问父类的属性 , 但不能访问父类的 private 属性 [案例]super.属性名
    public void hi(){
        System.out.println(super.n1+" "+super.n2+" "+super.n3);
    }
    //访问父类的属性 , 但不能访问父类的 private 方法 [案例]super.方法名(参数列表)
    public void ok(){
        super.test100();
        super.test200();
        super.test300();
        //super.test400();//不能访问父类private方法
    }
    //访问父类的构造器(这点前面用过):super(参数列表);只能放在构造器的第一句,只能出现一句!
    public B(){
        //super();
        //super("jack");
        super("jack",10);
    }
}

3. super关键字细节 298由于内容较多看视频

1. 调用父类构造器的好处(分工明确,父类属性有父类初始化,子类的属性由子类初始化)

2. 当子类中有和父类中的成员(属性和方法名)重名时,为了访问父类的成员,必须通过super,如果没有重名,使用super,this直接访问是一样的效果

3. super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员; 如果多个基类(上级类)中都有同名的成员,使用 super 访问遵循就近原则。A->B->C

代码在com.stulzl.super_detalil.包中

测试SuperDetail

package com.stulzl.super_detalil;


public class SuperDetail {
    public static void main(String[] args) {
        D b = new D();
        b.sum();   //298
        b.test();
    }
}

Base类父类是Object

package com.stulzl.super_detalil;

public class Base {//父类是Object
    public int n1=999;
    public int age =111;
    public void cal(){
        System.out.println("Base类的cal() 方法……");
    }
    public void eat(){
        System.out.println("Base类的eat() 方法……");
    }
}

父类C

package com.stulzl.super_detalil;

public class C extends Base{//父类
    //4 个属性
    public int n1 = 100;
    protected int n2 = 200;
    int n3 = 300;
    private int n4 = 400;

    //无参构造器
    public C() {
    }
    //有参构造器
    public C(String name) {
    }
    public C(String name, int age) {
    }

    //方法
    public void cal() {
        System.out.println("A 类的 cal() 方法...");
    }


}

子类D

package com.stulzl.super_detalil;

public class D extends C{ //子类
    //属性
    //public int n1 = 888;

    //当子类中有和父类中的成员(属性和方法名)重名时,为了访问父类的成员,必须通过super,
    // 如果没有重名,使用super,this直接访问是一样的效果
    public void sum(){

        System.out.println("B类的sum");

        //希望调用父类A中的cal方法          298
        //这时,因为子类 B 没有 cal 方法,因此我可以使用下面三种方式
        //找 cal 方法时(cal() 和 this.cal()逻辑一样),顺序是:
        // (1)先找本类,如果有,则调用
        // (2)如果没有,则找父类(如果有,并可以调用,则调用)
        // (3)如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object 类
        // 提示:如果查找方法的过程中,找到了,但是不能访问, 则报错, cannot access
        // 如果查找方法的过程中,没有找到,则提示方法不存在
        cal();
        this.cal();//等价cal();
        super.cal();//找 cal 方法(super.call()) 的顺序是直接查找父类,其他的规则一样

        //演示访问属性的规则   298
        //n1 和 this.n1 查找的规则是
        //(1) 先找本类,如果有,则调用
        //(2) 如果没有,则找父类(如果有,并可以调用,则调用)
        //(3) 如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到 Object 类
        // 提示:如果查找属性的过程中,找到了,但是不能访问, 则报错, cannot access
        // 如果查找属性的过程中,没有找到,则提示属性不存在
        System.out.println(n1);
        System.out.println(this.n1);
        System.out.println(super.n1); //找 n1 (super.n1) 的顺序是直接查找父类属性,其他的规则一样
    }

    public void test(){  //299
        //super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员;
        // 如果多个基类(上级类)中都有同名的成员,使用 super 访问遵循就近原则。A->B->C
        System.out.println("super.n1="+super.n1);
        super.cal();
    }
}

4. super关键字和this关键字的比较300

super关键字和方法重写_构造器_02

5. 基本介绍

super关键字和方法重写_构造器_03

注:这里的父类和子类关系不一定,也有可能是爷爷和孙子的关系

5.1 方法重写的注意事项 302

方法重写也叫方法覆盖,需要满足下面的条件

super关键字和方法重写_构造器_04

6. 快速入门 301-302

代码在com.stulzl.override_.包中

测试Override

package com.stulzl.override_;

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

父类Animal

package com.stulzl.override_;

public class Animal {//父类
    public void cry(){
        System.out.println("动物叫唤……");
    }

    //细节: 子类方法的返回类型和父类方法返回类型一样,302
    // 或者是父类返回类型的子类
    //比如 父类 返回类型是 Object , // 子类方法返回类型是 String
    public Object m1(){
        return null;
    }

    //细节: 子类方法不能缩小父类方法的访问权限
    //public > protected > 默认>private
    public void eat(){  //302

    }

    // 细节:这里 Object 不是 String 的子类,因此编译错误  302
//    public String m2(){
//        return null;
//    }
}

子类Dog

package com.stulzl.override_;

public class Dog extends Animal{//子类   301
    //解读
    //1. 因为 Dog 是 Animal 子类
    //2. Dog 的 cry 方法和 Animal 的 cry 定义形式一样(名称、返回类型、参数)
    //3. 这时我们就说 Dog 的 cry 方法,重写了 Animal 的 cry 方法
    public void cry(){//和父类中的cry方法重写了
        System.out.println("小狗叫……");
    }

    //细节: 子类方法的返回类型和父类方法返回类型一样,302
    // 或者是父类返回类型的子类
    //比如 父类 返回类型是 Object , // 子类方法返回类型是 String
    public String m1(){    //302
        return null;
    }

    //细节: 子类方法不能缩小父类方法的访问权限  302
    //public > protected > 默认>private
//    protected void eat(){
//
//    }

    // 细节:这里 Object 不是 String 的子类,因此编译错误  302
//    public Object m2(){
//        return null;
//    }

}

7. 方法重写练习

7.1 请对方法的重写和重载做一个比较 303

super关键字和方法重写_子类_05

7.2 题2 304

1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。

2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,定义 say 方法(返回自我介绍的信息)。

3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍

代码在com.stulzl.override_exercise.包中

测试OverrideExercise

package com.stulzl.override_exercise;

//1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
//2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,
//    定义 say 方法(返回自我介绍的信息)。
//3) 在 main 中,分别创建 Person 和 Student 对象,调用 say 方法输出自我介绍

public class OverrideExercise {
    public static void main(String[] args) {
        Person person = new Person("jack",30);
        System.out.println(person.say());

        Student student = new Student("smith",20,123456,99.8);
        System.out.println(student.say());
    }
}

父类Person

package com.stulzl.override_exercise;

//1) 编写一个 Person 类,包括属性/private(name、age),构造器、方法 say(返回自我介绍的字符串)。
public class Person {
    private String name;
    private int age;

    //构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //返回信息
    public String say(){
        return "name="+name+" age="+age;
    }
    //set和get方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

子类Student

package com.stulzl.override_exercise;

//2) 编写一个 Student 类,继承 Person 类,增加 id、score 属性/private,以及构造器,
//    定义 say 方法(返回自我介绍的信息)。
public class Student extends Person{
    private int id;
    private double score;

    //构造器
    public Student(String name, int age, int id, double score) {
        super(name, age);
        this.id = id;
        this.score = score;
    }
    //返回信息
    public String say(){//这里体现super的好处,代码复用
        return super.say()+" id="+id+" score="+score;
    }

    //set和get方法
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}


上一篇:C语言函数大全-- l 开头的函数
下一篇:没有了
网友评论