当前位置: 首页 > news >正文

Java知识【继承中的成员访问特点】

目录

1,继承中的成员访问特点

1.1:继承中变量的访问特点(掌握)

1.2:super(掌握)

1.3:继承中构造方法的访问特点(理解)

1.4:继承中成员方法的访问特点(掌握)

1.5:super内存图(理解)

1.6:方法重写(掌握)

1.7:方法重新的注意事项(掌握)

1.8:权限修饰符(理解)

1.9:信息管理系统使用继承改进(掌握)


1,继承中的成员访问特点

1.1:继承中变量的访问特点(掌握)

在子类方法中访问一个变量,采用的是就近原则。

  1. 子类局部范围找

  2. 子类成员范围找

  3. 父类成员范围找

  4. 如果都没有就报错(不考虑父亲的父亲…)

  • 示例代码

    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(掌握)

  • this&super关键字:

    • this:代表本类对象的引用

    • super:代表父类存储空间的标识(可以理解为父类对象引用)

  • this和super的使用分别

    • 成员变量:

      • this.成员变量 - 访问本类成员变量

      • super.成员变量 - 访问父类成员变量

    • 成员方法:

      • this.成员方法 - 访问本类成员方法

      • super.成员方法 - 访问父类成员方法

  • 构造方法:

    • this(…) - 访问本类构造方法

    • super(…) - 访问父类构造方法

1.3:继承中构造方法的访问特点(理解)

注意:子类中所有的构造方法默认都会访问父类中无参的构造方法

子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化,原因在于,每一个子类构造方法的第一条语句默认都是:super()

问题:如果父类中没有无参构造方法,只有带参构造方法,该怎么办呢?

1. 通过使用super关键字去显示的调用父类的带参构造方法
2. 子类通过this去调用本类的其他构造方法,本类其他构造方法再通过super去手动调用父类的带参的构造方法

注意: this(…)super(…) 必须放在构造方法的第一行有效语句,并且二者不能共存

 

1.4:继承中成员方法的访问特点(掌握)

通过子类对象访问一个方法

1. 子类成员范围找
2. 父类成员范围找
3. 如果都没有就报错(不考虑父亲的父亲…)

1.5:super内存图(理解)

对象在堆内存中,会单独存在一块super区域,用来存放父类的数据

 

 

1.6:方法重写(掌握)

  • 1、方法重写概念

    • 子类出现了和父类中一模一样的方法声明(方法名一样,参数列表也必须一样)

  • 2、方法重写的应用场景

    • 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容

  • 3、Override注解

    • 用来检测当前的方法,是否是重写的方法,起到【校验】的作用

1.7:方法重新的注意事项(掌握)

  • 方法重写的注意事项

  1. 私有方法不能被重写(父类私有成员子类是不能继承的)

  2. 子类方法访问权限不能更低(public > 默认 > 私有)

  3. 静态方法不能被重写,如果子类也有相同的方法,并不是重写的父类的方法

  • 示例代码

    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:权限修饰符(理解)

 

1.9:信息管理系统使用继承改进(掌握)

  • 需求

    把学生类和老师类共性的内容向上抽取,抽取到出一个 Person 父类,让学生类和老师类继承 Person 类

  • 实现步骤

    1. 抽取Person类

    2. 优化StudentController类中,inputStudentInfo方法,将setXxx赋值方式,改进为构造方法初始化

      注意:直接修改这种操作方式,不符合我们开发中的一个原则

      开闭原则 ( 对扩展开放对修改关闭 ) : 尽量在不更改原有代码的前提下以完成需求

      解决:重新创建一个OtherStudentController类

      编写新的inputStudentInfo方法

    3. 根据StudentController类、OtherStudentController类,向上抽取出BaseStudentController类 再让StudentController类、OtherStudentController类,继承BaseStudentController类

  • 代码实现

    Person类及学生类和老师类

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类

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类

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;
    }
}

相关文章:

  • <Linux进程控制(2)>——《Linux》
  • 嵌入式软件编程模式
  • VL8 使用generate_for语句简化代码
  • 从零开始搭建uni-app框架的小程序开发环境
  • 【web】TCP/UDP协议详解(字节二面:TCP三次握手、四次挥手)
  • C++打怪升级(二)- 引用详解
  • MongoDB的日志目录被删除了,导致无法启动:(code=exited, status=1/FAILURE)
  • 数据我爬定了,限流也挡不住,我说的
  • 可持久化线段树
  • 计算机网络-网络层篇-子网划分
  • DataX 初识
  • 工程项目管理——第十章 软件项目团队计划
  • 基于Java+SpringBoot+Thymeleaf+Mysql摄影图片分享网站系统设计与实现
  • C#的Dictionary类使用说明
  • 【FPGA教程案例90】机器视觉1——通过FPGA实现基于颜色模型的交通灯检测,使用MATLAB辅助测试
  • Android开源项目规范总结
  • Java,console输出实时的转向GUI textbox
  • Java面向对象及其三大特征
  • Python 反序列化安全问题(二)
  • scala基础语法(二)
  • webpack+react项目初体验——记录我的webpack环境配置
  • XML已死 ?
  • 基于遗传算法的优化问题求解
  • 前端
  • 使用 @font-face
  • Python 之网络式编程
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # 数论-逆元
  • #Linux(权限管理)
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (1)STL算法之遍历容器
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (pojstep1.3.1)1017(构造法模拟)
  • (定时器/计数器)中断系统(详解与使用)
  • (离散数学)逻辑连接词
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四)Linux Shell编程——输入输出重定向
  • (一)插入排序
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)可以带来幸福的一本书
  • (转)我也是一只IT小小鸟
  • .net core webapi 大文件上传到wwwroot文件夹
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET Standard 的管理策略
  • .Net Web项目创建比较不错的参考文章
  • .net 调用php,php 调用.net com组件 --
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET多线程执行函数
  • .NET开发者必备的11款免费工具
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @vue/cli 3.x+引入jQuery
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹