Java knowledge [member access characteristics in inheritance]

Table of contents

1. Member access features in inheritance

1.1: Access characteristics of variables in inheritance (master)

1.2: super (master)

1.3: Access characteristics of constructors in inheritance (understanding)

1.4: Access characteristics of member methods in inheritance (master)

1.5: super memory map (understanding)

1.6: Method Overriding (Mastering)

1.7: Precautions for Method Rework (Mastering)

1.8: Permission Modifiers (understanding)

1.9: Information Management System Use Inheritance Improvement (Mastery)


1. Member access features in inheritance

1.1: Access characteristics of variables in inheritance (master)

Accessing a variable in a subclass method follows the proximity principle.

  1. subclass local scope find

  2. Subclass member scope lookup

  3. parent class member scope

  4. If there is none, report an error (don't consider the father's father...)

  • sample code

    class Fu {
        int num = 10;
    }
    class Zi {
        int num = 20;
        public void show(){
            int num = 30;
            System.out.println(num);
        }
    }
    public class Demo1 {
        public static void main(String[] args) {
            Zi z = new Zi();
            z.show();	// 输出show方法中的局部变量30
        }
    }

1.2: super (master)

  • this&super keyword:

    • this: the reference representing the object of this class

    • super: the identifier representing the storage space of the parent class (which can be understood as a reference to the parent class object)

  • The use of this and super respectively

    • Member variables:

      • this.member variable - access the member variable of this class

      • super.member variables - access super class member variables

    • Member method:

      • this.membermethods - access to member methods of this class

      • super.membermethods - access parent class member methods

  • Construction method:

    • this(…) - access to this class constructor

    • super(…) - access the super class constructor

1.3: Access characteristics of constructors in inheritance (understanding)

Note: By default, all constructors in the subclass will access the no-argument constructor in the parent class

Subclasses inherit data from the parent class and may also use data from the parent class. Therefore, before the subclass is initialized, the initialization of the parent class data must be completed first. The reason is that the first statement of each subclass constructor is by default: super()

Question: What if there is no parameterless constructor in the parent class, but only a parameterized constructor?

1. By using the super keyword to display the call to the parent class's constructor with parameters
2. The subclass uses this to call other constructors of this class, and the other constructors of this class then use super to manually call the parent class's constructor with parameters Construction method

Note: this(…)super(…) must be placed in the first valid statement of the constructor, and the two cannot coexist

 

1.4: Access characteristics of member methods in inheritance (master)

Access a method through a subclassed object

1. Find the subclass member range
2. Find the parent class member range
3. If there is none, report an error (don't consider the father's father...)

1.5: super memory map (understanding)

In the heap memory, the object will have a separate super area to store the data of the parent class

 

 

1.6: Method Overriding (Mastering)

  • 1. Method overriding concept

    • The subclass has the same method declaration as in the parent class (the method name is the same, and the parameter list must be the same)

  • 2. Application scenarios of method rewriting

    • When the subclass needs the function of the parent class, and the function main subclass has its own unique content, the method in the parent class can be rewritten, so that it inherits the function of the parent class and defines the unique content of the subclass

  • 3. Override annotation

    • It is used to detect whether the current method is an overridden method, which plays the role of [check]

1.7: Precautions for Method Rework (Mastering)

  • Notes on method overriding

  1. Private methods cannot be overridden (private members of parent classes cannot be inherited by subclasses)

  2. Subclass method access rights cannot be lower (public > default > private)

  3. Static methods cannot be overridden, if the subclass has the same method, it is not the method of the overridden superclass

  • sample code

    public class Fu {
        private void show() {
            System.out.println("Fu中show()方法被调用");
        }
    
        void method() {
            System.out.println("Fu中method()方法被调用");
        }
    }
    
    public class Zi extends Fu {
    
        /* 编译【出错】,子类不能重写父类私有的方法*/
        @Override
        private void show() {
            System.out.println("Zi中show()方法被调用");
        }
       
        /* 编译【出错】,子类重写父类方法的时候,访问权限需要大于等于父类 */
        @Override
        private void method() {
            System.out.println("Zi中method()方法被调用");
        }
    
        /* 编译【通过】,子类重写父类方法的时候,访问权限需要大于等于父类 */
        @Override
        public void method() {
            System.out.println("Zi中method()方法被调用");
        }
    }

1.8: Permission Modifiers (understanding)

 

1.9: Information Management System Use Inheritance Improvement (Mastery)

  • need

    Extract the common content of the student class and the teacher class upward, extract a Person parent class, and let the student class and the teacher class inherit the Person class

  • Implementation steps

    1. Extract the Person class

    2. In the StudentController class, the inputStudentInfo method is optimized, and the setXxx assignment method is improved to the constructor initialization

      Note: Modifying this mode of operation directly does not conform to a principle in our development

      Open-closed principle (open for extension but closed for modification): try to complete the requirements without changing the original code

      Solution: Recreate a OtherStudentController class

      Write a new inputStudentInfo method

    3. According to the StudentController class and the OtherStudentController class, extract the BaseStudentController class upwards, and then let the StudentController class and the OtherStudentController class inherit the BaseStudentController class

  • Code

    Person class and student class and teacher class

public class Person {
    private String id;
    private String name;
    private String age;
    private String birthday;

    public Person() {
    }

    public Person(String id, String name, String age, String birthday) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAge() {
        return age;
    }

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

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
}
// Student类
public class Student extends Person {
    public Student() {
    }

    public Student(String id, String name, String age, String birthday) {
        super(id, name, age, birthday);
    }
}
// Teacher类
public class Teacher extends Person {
    public Teacher() {
    }

    public Teacher(String id, String name, String age, String birthday) {
        super(id, name, age, birthday);
    }
}

BaseStudentController class

public abstract class BaseStudentController {
    // 业务员对象
    private StudentService studentService = new StudentService();

    private Scanner sc = new Scanner(System.in);

    // 开启学生管理系统, 并展示学生管理系统菜单
    public void start() {
        //Scanner sc = new Scanner(System.in);
        studentLoop:
        while (true) {
            System.out.println("--------欢迎来到 <学生> 管理系统--------");
            System.out.println("请输入您的选择: 1.添加学生  2.删除学生  3.修改学生  4.查看学生  5.退出");
            String choice = sc.next();
            switch (choice) {
                case "1":
                    // System.out.println("添加");
                    addStudent();
                    break;
                case "2":
                    // System.out.println("删除");
                    deleteStudentById();
                    break;
                case "3":
                    // System.out.println("修改");
                    updateStudent();
                    break;
                case "4":
                    // System.out.println("查询");
                    findAllStudent();
                    break;
                case "5":
                    System.out.println("感谢您使用学生管理系统, 再见!");
                    break studentLoop;
                default:
                    System.out.println("您的输入有误, 请重新输入");
                    break;
            }
        }
    }

    // 修改学生方法
    public void updateStudent() {
        String updateId = inputStudentId();
        Student newStu = inputStudentInfo(updateId);
        studentService.updateStudent(updateId, newStu);

        System.out.println("修改成功!");
    }

    // 删除学生方法
    public void deleteStudentById() {
        String delId = inputStudentId();
        // 3. 调用业务员中的deleteStudentById根据id, 删除学生
        studentService.deleteStudentById(delId);
        // 4. 提示删除成功
        System.out.println("删除成功!");
    }

    // 查看学生方法
    public void findAllStudent() {
        // 1. 调用业务员中的获取方法, 得到学生的对象数组
        Student[] stus = studentService.findAllStudent();
        // 2. 判断数组的内存地址, 是否为null
        if (stus == null) {
            System.out.println("查无信息, 请添加后重试");
            return;
        }
        // 3. 遍历数组, 获取学生信息并打印在控制台
        System.out.println("学号\t\t姓名\t年龄\t生日");
        for (int i = 0; i < stus.length; i++) {
            Student stu = stus[i];
            if (stu != null) {
                System.out.println(stu.getId() + "\t" + stu.getName() + "\t" + stu.getAge() + "\t\t" + stu.getBirthday());
            }
        }
    }

    // 添加学生方法
    public void addStudent() {
        // StudentService studentService = new StudentService();
        // 1. 键盘接收学生信息
        String id;
        while (true) {
            System.out.println("请输入学生id:");
            id = sc.next();
            boolean flag = studentService.isExists(id);
            if (flag) {
                System.out.println("学号已被占用, 请重新输入");
            } else {
                break;
            }
        }

        Student stu = inputStudentInfo(id);

        // 3. 将学生对象,传递给StudentService(业务员)中的addStudent方法
        boolean result = studentService.addStudent(stu);
        // 4. 根据返回的boolean类型结果, 在控制台打印成功\失败
        if (result) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }
    }

    // 键盘录入学生id
    public String inputStudentId() {
        String id;
        while (true) {
            System.out.println("请输入学生id:");
            id = sc.next();
            boolean exists = studentService.isExists(id);
            if (!exists) {
                System.out.println("您输入的id不存在, 请重新输入:");
            } else {
                break;
            }
        }
        return id;
    }

    // 键盘录入学生信息
    // 开闭原则: 对扩展内容开放, 对修改内容关闭
  public Student inputStudentInfo(String id){
    return null;
  }
}

StudentController class

public class StudentController extends BaseStudentController {

    private Scanner sc = new Scanner(System.in);

    // 键盘录入学生信息
    // 开闭原则: 对扩展内容开放, 对修改内容关闭
    @Override
    public Student inputStudentInfo(String id) {
        System.out.println("请输入学生姓名:");
        String name = sc.next();
        System.out.println("请输入学生年龄:");
        String age = sc.next();
        System.out.println("请输入学生生日:");
        String birthday = sc.next();
        Student stu = new Student();
        stu.setId(id);
        stu.setName(name);
        stu.setAge(age);
        stu.setBirthday(birthday);
        return stu;
    }
}

OtherStudentController类

public class OtherStudentController extends BaseStudentController {

    private Scanner sc = new Scanner(System.in);

    // 键盘录入学生信息
    // 开闭原则: 对扩展内容开放, 对修改内容关闭
    @Override
    public Student inputStudentInfo(String id) {
        System.out.println("请输入学生姓名:");
        String name = sc.next();
        System.out.println("请输入学生年龄:");
        String age = sc.next();
        System.out.println("请输入学生生日:");
        String birthday = sc.next();
        Student stu = new Student(id,name,age,birthday);
        return stu;
    }
}

Guess you like

Origin blog.csdn.net/m0_64550837/article/details/127142142