面向对象(静态和非静态)

6.8 static关键字

    当我们在设计类的时候 发现多个对象中有共享数据的时候 我们就可以把这个共享的数据 定义为静态的
    name age虽然每个对象都有 但是值不一定一样 对象的特有数据->成员变量
    country虽然每个对象也都有 但是值一样 对象的共有数据-> 静态变量

也就是说:共有的数据存在于一个特定的空间 静态方法区

那么静态变量是如何定义的呢

成员函数+static=静态函数; 我们当前的成员函数如果不访问任何成员变量的情况下 这个函数就可以定义为静态的,这就意味着 静态函数不能直接调用当前类中的成员变量 无法从静态上下文中引用非静态,原因就是静态的生命周期要长与对象,所以静态是优先于对象存在的,静态也称之为是类的成员,我们可以直接通过类去调用(类.静态成员)

那么为什么主函数是静态的呢?

主函数是程序的入口,优于其它运行
        假设主函数是非静态的 那么必须先创建对象 才能调用主函数
        怎么去创建对象呢?是不是需要写代码?这段代码咋运行呢?

6.9 类的分类

实体类:

            就是为了描述一个事物 Person Point
            类中内容基本上都是成员函数/成员变量
            也会而存在一个静态成员

工具类

            提供一些已经被实现好的功能 向外部供应
            所以工具类中基本上全都是静态函数
            类.Xxx 类.Xxx() Math Arrays
            为啥工具类中都是静态?
            1.共有的
            2.长时间存在
            3.加载一次 后期随便使用
            一个道理:
                当我们钉一个钉子的时候 找榔头
                你是造一个榔头 还是用已存在的榔头?
            如果工具类可以被创建对象 是不是就想用的时候去创建
                效率较低

主类/测试类

            主要用于运行/测试代码
            这个类中会有主函数的存在
            实体类是可以存在主函数的 但是不推荐
            工具类一般不会存在主函数

6.9 对象的内存图解III


    1.javac 将Java源代码进行编译 生成字节码文件
    2.java 将字节码文件加载进虚拟机中 开始运行程序
        字节码具体被加载在方法区里面
        方法区可以大致分为 非静态方法区/静态方法区
        所有非静态的代码(二进制)内容加载进非静态去
        所有静态的代码(二进制)内容加载进静态区
        JVM接下来会根据参数(java 字节码文件名(类名)) 去静态区找主函数
        将主函数代码加载进虚拟机栈 开始运行
    3.后面的和之前一样

6.10 静态变量与成员变量的区别

    1.生命周期
        成员变量随着对象的创建而创建 随着对象的消亡而消亡
        静态变量随着类的加载而创建 随着程序结束而消失
    2.调用方式
        成员变量必须先创建对象 在通过对象去调用
        静态变量可以被对象调用 也可以直接用类调用
    3.存储位置
        成员变量存在于堆内存中对象的所属空间里
        静态变量存在于静态方法区中类的所属空间里
    4.命名
        成员变量-对象的特有属性
        静态变量-对象的共有属性 类成员

6.11 代码块

    代码块 { ... }
    
    局部代码块:存在于函数当中(包括函数) for(){...} if(){...}
    
    构造代码块:直接在类中出现的{...}
        当对象创建一次 构造代码块执行一次
        作用等同于构造函数

    静态代码块:直接在类中出现的static{...}
        当类被加载的时候 仅且只执行一次
        作用于 对类进行一些初始化操作 JDBC

6.12 单例模式


    设计模式:就是我们的前辈们总结出来的一些编码技巧
    它并不是随着Java的诞生而诞生的
    它是由Java的广大使用者总结出来的一套编码经验
    常见26种

    单例模式:使用场景是 某一个类只能创建一个对象
    比如某一个朝代的皇帝 只能是唯一的
    1.既然只能创建一个对象的话 就得不能让外界去创建对象
        限制使用new不现实
        只能从对象的创建流程中考虑 只要有一个步骤不行 对象就创建不出来
        开辟空间分配地址 是由计算机底层决定 我们也控制不了
        构造函数执行  只需要将构造函数私有化即可
    2.既然外界不能创建对象 我们还得保证对象的创建
        所以我们只能在类内部创建对象
        Single s=new Single();
        能否写成 成员变量的形式?
        所以private static
    3.内部创建出对象 还得向外界提供
        因为private 外界不能直接访问
        所以见解 向外界提供一个函数 外界通过调用函数获取对象

6.13 继承


    继承由来是什么:当我们在定义若干个类的时候,发现某一些类中具有相同的属性和行为
        那么,我们就可以将这些相同的部分进行抽取,独立生成另外一个类,那么这个生成出来
        的类我们称之为是父类,其他的被抽取内容的类称之为子类
        子类与父类之间就是所谓的继承关系 用 extends来表示
    那么在现实生活中,父与子之间的一对多 还是多对多的关系?
    所以 在Java当中 继承是单继承(一个子类只能有一个父类,但是一个父类可以有若干个子类)
    当然,在C++中,继承是多继承的,不太符合实际的社会问题,所以Java更加符合现实编程
    (不代表Java当中就没有多继承的时候!如果是类与类之间 必须是单继承;如果是接口与接口之间,可以是多继承)
    既然有了继承,那么在Java当中就有了继承体系
    (既然有了父子关系,是不是就产生出了族谱这个东西)
    先说一点:我们常用的继承体系 异常体系 集合体系 IO体系 网络体系 多线程体系
    C->B->A->?->?->龙的传人/炎黄子孙
    C就是B的儿子,那么A就是C的爷爷

    在Java继承体系当中,所有类的最终父类都是Object!Object就不存在爸爸了
    如果我们在定义一个类的时候,没有显著声明父类的时候 那么该类的父类默认是Object

    注意一点:在分析设计继承的时候 一定要符合社会常识问题 
            子类 和 父类 之间 必须是 is a 关系 子类必须父类的一种 同一系列的
            she is a Girl  ; he is a boy ; he is a ladyboy ; 旺财 is a Dog 
        所以,千万不要为了获取某一个类的功能而把这个类叫爸爸!

    子父类中成员变量/静态变量的特点:
        如果只有子类有且非私有 那么就调用子类的
        如果只有父类有且非私有 那么就调用父类的
        如果子父类都有且非私有 那么就调用子类的
        (成员变量之间 是不存在重写关系的!!!)
        子类.属性 顺序:子类对象成员->子类静态->父类成员->父类静态
        子类成员函数在内部调用变量时 局部变量->子类对象成员->子类静态->父类成员->父类静态

    子父类中构造函数的特点:
        现象:子类的构造函数在调用运行的时候 先执行父类的构造函数
        在子类的构造函数当中,有一句默认的super(...)隐藏了,而且这句代码必须是在第一行
        对super的调用必须是构造器中的第一个
        为什么?道理很简单 儿子向老爸要钱,那么老爸是不是得先准备一下钱
        既然子类继承自父类 那么必然会继承到父类当中的一些数据
        所以,在子类构造函数之中,必须先让父类把这些数据进行一些初始化才能继承给子类
        注意:父类的构造函数被调用,但不代表父类就被创建对象了!
              所以this是当前对象的引用,而super不是父类对象的引用,而是父类空间的引用
        并且注意super(...) 如果父类没有默认无参构造函数 那么子类构造函数中super()失效了
        所以在调用父类构造函数时,一定要注意父类构造函数的参数情况!适时修改super(...)

        this(...)是当前类中 本类构造函数调用本类构造函数的方式
        super(...)是本类构造函数调用父类构造函数的方式
        都必须在第一行 那么这两冲突不?
        如果本类构造函数当中不存在调用关系 那么每一个本类构造函数第一句都是super(...)
        如果本类构造函数当中存在调用关系,那么最后被调用的那个构造函数第一句绝对是super(...)
        this(...)的调用是单向的还是递归的?是单向的,那么最后被调用的第一句绝对就是super(...)

    子父类中成员函数的特点:
        如果只有子类有且非私有 那么就调用子类的
        如果只有父类有且非私有 那么就调用父类的
        如果子父类都有且非私有 那么就调用子类的(函数重写)
    函数重写:在子父类中,同名函数
    函数有什么组成:函数声明(权限 类型 返回值类型 函数名 参数列表)+函数体({}里面的内容)
    重写的意义在于哪?在于子类继承了父类的函数声明(功能),但是子类可以将该函数的具体实现进行优化或更改
                    郭德纲会说相声 郭麒麟也会说相声
                    子承父业!
        1.保留父类的功能声明 子类可以进一步优化
        2.保留父类的功能声明 子类可以重新定义
    重写当中应该注意到的一些细节:
    1.函数重名 但是参数列表不同 不构成重写关系
    2.函数重名 参数列表相同 构成重写关系 返回值类型也必须是一样的
    3.子类重写父类函数时,权限>=父类权限
    4.当然 如果父类函数权限为private 子类压根就继承不到 何谈重写

6.14 抽象类


    抽象类:模糊不清的类 不具体的类
    当我们在抽取一个父类的时候,发现子类当中的一些共同方法在父类中无法进行具体的实现
    并且这些方法只能在子类中具体实现时,父类当中的这些函数就只保留函数声明即可,不必写函数体
    那么此时这个函数就是 抽象函数! 有抽象函数的类 就是抽象类!
    特点:
    1.抽象类能否创建对象?不能 对象本身是一个具体的东西 而抽象类中含有不具体的内容
    2.抽象类必须作为父类存在吗?必须 抽象类就等着被继承呢!
    3.抽象类和一般类有什么区别?就是一般类的特殊情况 
        唯一的区别只在于抽象类中有抽象函数!
    4.抽象类中必须有抽象函数吗?不一定 AWT界面开发
    5.abstract这个关键字不能和那些关键字共存?
        private 抽象函数就等着被子类重写实现呢!
        static  静态是优先于对象存在的,在加载静态数据的时候 肯定是具体的数据
                类名.抽象函数 很尴尬! 
                如果抽象函数可以被静态 那么我们还需要对象干什么?

 

 

6.17 多态


    多种状态:就是指一个对象可以有多种状态(他在继承体系中的位置变化)
    D->C->B->A->Animal
    位置的变化只能是向上变 但不能低于自身
    对于C而言 可以当做B来看 也可以当做A来看 也可以当成Animal
        小明        男人             人     动物
    小明的学校开家长会 小明不想让他爸爸去 他让大明去 大明就是小明他哥
    大明冒充Dad去参加家长会的话,那么所表现出来的行为 是不是应该符合他爸行为
    不同的视角 不同的角色
    无论是在哪个视角场合 对象本身变了没有?只不过我们需要对象在不同的场合表现出相对应的行为
    在Java当中 多态代码表现 就是 父类引用指向子类的对象
    多态的前提:继承 重写
    多态的好处:对代码的功能进行了可扩展性
        子类对象可以当做父类对象去使用 但是有限制 只能调用父类函数或重写的函数
        不能使用子类特有的行为
    
    多态当中 成员变量的特点:只能访问父类中的成员变量
    多态当中 成员函数的特点:
        如果子类没有重写 且父类中有 调用父类的
        如果子类有重写 调用子类重写的
        如果不存在重写 父类没有 那就报错了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值