• day09_面向对象_多态_static


    今日内容

    1.作业
    2.访问修饰符
    3.static
    4.多态

    零、复习

    私有化的单词: private

    继承的关键词: extends

    属性的封装

    • 将属性私有,private
    • 提供一对儿set,get

    继承的特性:(自己的话说明)

    • 继承目的是减少重复代码,父类代码子类自己使用
    • A extends B
    • 关于属性: 子类可以使用父类非私有的属性
    • 关于方法: 子类可以使用父类非私有的方法,
    • 如果父类方法不适用,就要重写方法
    • 关于构造: 子类构造方法内有super()可以调用父类构造方法

    this能干什么

    • this调用属性,调用方法,调用构造方法

    super能干什么

    • 调用父类属性,调用父类方法,调用父类构造方法

    重写的语法

    • 子类和父类的访问修饰符,返回值类型,方法名,参数列表完全一样

    一、作业

    作业1: 详见项目day09/src/com/qf/homework/pdf6_t19

    主要考察:属性封装,类继承,和方法重写

    image-20231019092058884

    这是UML类体. 实线箭头代表继承关系

    作业2: 详见项目day09/src/com/qf/homework/pdf6_t24

    主要考察:属性封装,类继承,和方法重写以及super的使用,还有基本的代码逻辑(如何算工资)

    二、访问修饰符

    访问修饰符又叫 访问权限符,访问控制

    就是用来限制属性和方法的使用范围的,即类中的属性和方法在什么地方可以使用 什么地方不可以使用

    所以就有了两个研究方向

    • 有哪些修饰符?
    • 都有哪些地方?
    当前类中同一包下其他类其他包子类内其他包非子类
    public(公开公共)自己能用,子对象能用
    protected(受保护)自己不能用,子类对象能用×
    缺省(默认)(不写)××
    private(私有)×××

    总结: 访问修饰符有访问大小范围:

    public > protected > package > private

    延伸: 子类重写父类方法,子类的访问修饰符 >= 父类访问修饰符

    三、static

    3.1 介绍

    static 修饰符, 意思是静态的, 静态的一旦设置值就可以被所有对象使用

    • 修饰属性
    • 修饰方法
    • 修饰内部类(了解)

    作用:

    • 被static修饰的属性或者方法在内存只有一个
    • 被static修饰的属性或者方法,就会被所有对象共享
    • 会随着类(class字节码文件)加载而初始化

    回忆以前(没有static时)

    • 一个类创建的多个对象和对象的关系? 相互独立互不影响
    • 对象和属性和方法的关系, 每次创建一个对象,对象都有属于自己的属性和方法

    static特性

    • 凡是被static修饰的属性和方法,会随着class文件加载到内存而初始化
      • 其他的普通成员变量是随着创建对象,在堆中出现初始化
      • 静态的属性和方法会先出现,即没有创建对象时可以被使用了
      • 有静态修饰的属性和方法时 不一定有对象
    • 凡是被static修饰的属性和方法,在内存只有一份,被该类的所有对象共享

    总结

    • 不加静态的属性和方法通过对象调用
    • 加了静态的属性和方法都通过类名调用
    • 静态方法可以直接调用静态的方法和属性
    • 静态方法不能直接调用非静态方法
    • 非静态方法能调用静态属性和方法
    • 静态方法内不能使用this

    3.2 演示

    黄牛卖演唱会票,假设100张票,多个黄牛在卖

    public class Huangniu {
        /**
         * 属性不加static,那就是成员变量,又叫对象属性
         * 叫对象属性是因为,每次创建对象,每个对象都有该属性
         * 成员变量/对象属性是在内存堆中
         * -----------------------------------------
         * 但是加上static,不再是对象属性,即不属于每个对象,也不存在于堆中
         * 而是在
         */
        static int ticket = 100;
        String name;
        // 卖票
        public void sellTicket(){
            System.out.println("黄牛卖票" );
            ticket--;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class TestHuangniu {
        public static void main(String[] args) {
            // 找到黄牛
            Huangniu niu1 = new Huangniu( );
            // 先看有多少张票
            // System.out.println(niu1.ticket );
            // 静态的属性建议使用类名调用
            System.out.println(Huangniu.ticket );
    
            // 卖一张
            niu1.sellTicket();
            // 再看一眼余票
            System.out.println( niu1.ticket);
            System.out.println("----------------" );
    
            // 再找到黄牛,卖票
            Huangniu niu2 = new Huangniu( );
            // 查看余票
            System.out.println(niu2.ticket );
    
            System.out.println("------------------" );
    
            // toString就是静态方法,类名直接调用
            Arrays.toString(new int[]{1});
            // PI就是静态属性,类名直接调用
            System.out.println(Math.PI );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    image-20231019151119752

    3.3 应用场景

    1. 将一些方法或者属性定义成静态,方便调用,因为类名直接调用
      例如: Arrays.toString, Math.PI
    2. 当有些时候确实需要某个数据被共享时,就加上静态
      例如: 火车票

    四、多态

    4.1 介绍

    多态: 同一种东西多种形态

    面向对象中的多态: 特指某个方法,运行得到不同的结果 (同一个对象调用同一个方法结果却不一样)


    如何做?要同时满足三个条件

    • 继承
    • 重写
    • 父类引用指向子类对象(向上转型)(把子类包装成父类)

    为什么要多态?有什么好处?

    • 提高代码扩展性
    • 兼容性
    • 降低耦合性

    4.2 演示

    image-20231019154649525

    4.3 关于多态的应用场景

    1. 方法的参数列表是父类,传参数传入子类对象,让该方法展现多态
    public class TestPoly {
    
        public static void main(String[] args) {
            // 父类引用指向父类对象(自己引用指向自己对象)
            // Animal animal = new Animal( );
    
            // 子类引用指向子类对象(自己引用指向自己对象)
            // Dog dog = new Dog( );
    
            // 父类引用 指向 子类对象(向上转型)(将子类包装成父类)
            // Animal animal = new Dog( );
            // System.out.println(animal );
            Animal animal = new Cat();
    
            // eat方法就会出现多态
            animal.eat();
            System.out.println("-------------------" );
            dogShow(new Dog());
            catShow(new Cat());
            System.out.println("-------------------" );
    
            // 使用多态调用方法
            animalShow(new Dog());// 向上转型
            animalShow(new Cat());
            animalShow(new Pig());
    
        }
    
        /**
         * 设计方法,展示每个动物吃的东西
         */
        public static void dogShow(Dog dog){
            dog.eat();
        }
        public static void catShow(Cat cat){
            cat.eat();
        }
        // 如果再加动物,这里就需要再重新定义好多方法
        // 有了多态就可以解决这些问题
        // 将方法参数列表设计父类,传参数时传入子类对象(向上转型)
        // 这样就可以提高代码扩展性,大大减少了耦合性
        public static void animalShow(Animal animal){
            animal.eat();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    1. 方法的返回值是父类,允许返回子类对象
    class Animal {
    }
    
    class Dog extends Animal {
    }
    
    class Cat extends Animal {
    }
    
    public class TestAnimal {
        public static Animal getAnimal() {
            //1
            // return null; // ok
            // return new Animal(); // ok
             return new Cat(); // ok
            //return new Dog(); // ok
        }
    
        public static void main(String args[]) {
            Animal animal = getAnimal( );
            System.out.println(animal );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    image-20231019165032938

    1. 利用多态性,设计父类类型的数组,存储子类对象
    public class TestShape {
    
        public static void main(String[] args) {
    
            // 创建父类类型数组
            // 数据类型[] 数组名 = new 数据类型[长度];
            Shape[] shapes = new Shape[3];
    
            // 存储的是子类对象
            Circle circle = new Circle( );
            circle.setR(10);
            shapes[0] = circle;// 相当于向上转型
    
            // 子类对象circle赋值给父类类型shape的引用
            Rect rect = new Rect( );
            rect.setLength(10);
            rect.setWidth(5);
            shapes[1] = rect;
    
            Square square = new Square( );
            square.setL(10);
            shapes[2] = square;
    
            for (int i = 0; i < shapes.length; i++) {
                Shape shape = shapes[i];// 取值
                // 运行看子类
                double area = shape.area( );// 该方法会展现多态性
                double girth = shape.girth( );// 该方法会展现多态性
                System.out.println("面积:" + area );
                System.out.println("周长:" + girth );
                System.out.println("----------" );
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    image-20231019173419365

    4.4 注意事项

    多态方法运行的注意事项

    • 父类引用调用的方法如果子父类都有,那么就是展示子类的(运行看子类)
    • 父类引用调用的方法父类有,子类没有 ----> 允许(编译看父类)
    • 编译看父类,运行看子类
      • 父类引用调用的方法,父类得有该方法,父类没有的话编译就报错
      • 父类引用调用的方法,子类中有,那么就运行子类的
        • 子类中没有该方法,就运行父类的

    五、总结

    关于访问修饰符 ,见到认识,知道什么效果即可
    static,见到认识,知道类名可以直接调用静态方法和属性
    重点还是多态,重点在于使用多态(参数,返回值,数组),重点在于题
    写题口诀
    	多态前提: 继承,重写,向上转型
    	编译看父类,运行看子类
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    六、作业

    t22
    t25
    
    • 1
    • 2
  • 相关阅读:
    数据库学习之库的操作
    【CGAL_空间搜索与排序】3D快速求交和距离计算
    实验笔记之——Gaussian Splatting SLAM配置与测试
    字符串和内存函数
    Golang并发控制的三种方案
    Linux·socket编程
    React18中各种Hooks用法总结( 内附案例讲解)
    R语言计算代码的运行时间:使用tictoc包计算代码的运行时间长短
    【音视频|ALSA】SS528开发板编译Linux内核ALSA驱动、移植alsa-lib、采集与播放usb耳机声音
    webrtc H265 网页播放器迈向实用第一步
  • 原文地址:https://blog.csdn.net/weixin_39641494/article/details/133931565