- super关键字
- 可以访问父类的属性和方法,但是不能访问父类的私有属性和私有方法
- 调用另一个方法时的顺序:
写法:cal()/this.cal()
先找本类,有则调用;没有就找父类,父类有并且可以调用就调用;父类没有就找父类的父类
super.call()
直接找父类,其他规则一样。
总结:当子类和父类有一样的成员时,访问父类的成员必须用super,如果没有重名,super和this访问效果是一样的。
- 方法重写/覆盖
- 子类的方法参数、方法名称和父类的方法参数、方法名称一致
- 子类的返回类型要么和父类的返回类型一样,要么是父类返回类型的子类。
子类方法不能缩小父类方法的访问权限
,可以扩大权限(public>protected>default>private)- 方法重写与方法重载
名称 | 发生范围 | 方法名 | 参数列表 | 返回类型 | 修饰符 |
---|---|---|---|---|---|
重载 | 本类 | 必须一致 | 类型、个数或者顺序至少有一个不同 | 无要求 | 无要求 |
重写 | 父子类 | 必须一致 | 必须一致 | 必须一致或者子类返回类型也是子类 | 一致或子类的访问权限更大 |
-
面向对象的第三大特征-多态:方法或对象具有多种形态。多态是建立在封装和继承之上的。
-
对象的多态:
一个对象的编译类型和运行类型可以不一致
;编译类型定义对象时是确定的,不可改变的,但运行类型是可以改变的,可以指向另外的运行类型;编译类型看=左边,运行类型看=右边 -
向上转型:父类引用指向子类对象(子类引用指向父类对象)
语法:父类类型 引用名 = new 子类类型();
可以调用父类的所有成员(需遵守访问权限);但不能调用子类的特有成员,因为在编译阶段,能调用哪些成员还是编译类型决定的
。
- 向下转型:子类类型 引用名 = (子类类型) 父类引用;
只能强转父类的引用,不能强转父类的对象
要求父类的引用必须指向当前目标类型的对象
向下转型后,可以调用子类类型中的所有成员
- 属性没有重写之说!属性的值看编译类型;instanceOf比较操作符,用于判断对象的类型是否为XX类型或XX类型的子类型。
- java的动态绑定机制
- 当调用对象方法时,
该方法会和对象的内存地址/运行类型绑定。
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
- 多态的应用
多态数组:数组定义类型为父类类型,里面保存的实际元素类型为子类类型。
多态参数:方法定义的形参为父类类型,实参类型为子类类型。 - == vs equals
- == 是一个操作符;如果判断基本类型,判断的是
值是否相等
;如果判断引用类型,判断的是地址是否相等
。 - equals是object类的方法,只能判断引用类型。默认判断的是地址是否相等,子类往往重写该方法,用于判断内容相等。
Object类的方法
- hashCode方法
- 提高具有哈希结构的容器的效率!
- 两个引用,如果指向同一个对象,则哈希值一定一样!
- 两个引用,如果指向不同对象,则哈希值是不一样的。出现一样造成哈希碰撞!
- 哈希值是根据地址号来的,但不能将哈希值完全等价于地址
- 在集合中需要重写hashCode方法
- toString方法
- 默认返回:
全类名+@+哈希值的16进制
- 直接输出一个对象时,默认调用toString方法
- finalize方法
- 对象被回收时系统自动调用该对象的finalize方法;子类可以重写该方法,做一些释放资源的操作
- 什么时候会被回收:
当某个对象没有任何引用时,jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象
。销毁对象前,会调用finalize方法
- 垃圾回收机制的调用,是由系统来决定。也可以通过System.gc()(注意不能确定百分百调用)主动触发垃圾回收机制。
- 实际开发中几乎不会运用到finalize
- 断点调试
- 调试过程中,是以对象的运行类型来执行的。
- 快捷键:F7跳入方法内 shift+F8跳出方法 F9执行到下一个断点
F8逐行执行代码
- 创建对象的流程
- 加载person类信息
- 初始化 :默认初始化 显式初始化 构造器初始化
- 返回对象的地址
- 编程思路:找出不正确的条件,给出提示,直接break
面向对象的高级
- 类变量,也叫静态变量,使用static关键字修饰。该变量
最大特点是会被类的所有实例对象共享
。 - 静态变量:JDK8之前放在方法区,JDK8之后放在堆空间,通过反射机制加载class对象
- 静态方法:使用static修饰的方法就是静态方法;静态方法可以访问静态属性/变量
- 方法中不涉及任何和对象相关的成员,或者不希望创建实例,则可以将方法设计成静态方法,提高开发效率。
- 类方法中无this的参数,不能使用this和super的关键字
静态方法只能访问静态成员
;非静态方法,可以访问静态成员和非静态成员(必须遵守访问权限)- main方法(public static void main())
- java虚拟机在调用。访问权限必须是public,因为java虚拟机和main方法不在同一个类。
- static修饰,因为希望调用时可以不必创建对象。
- 代码块
- 称为初始化块,属于类中成员,使用{}包围
- 和方法不同,没有方法名、返回、参数,只有方法体
- 不用通过对象或类显示调用,而是加载类时、或创建对象时隐式调用
- 代码块前可以加修饰符static,使用static修饰是静态代码块,没有static修饰是普通代码块。
- ;可写可不写
- 注意⚠️构造器的前面隐含了super()和调用普通代码块。
- 父类子类创建对象时,静态代码块、静态属性初始化、普通代码块、普通属性初始化、构造方法调用顺序如下:
父类的静态代码块和静态属性
(优先级一样按顺序执行)子类的静态代码块和静态属性
(优先级一样按顺序执行)父类的普通代码块和普通属性
(优先级一样按顺序执行)父类构造方法
子类的普通代码块和普通属性
(优先级一样按顺序执行)子类构造方法
- 静态代码块只能调用静态成员,普通代码块可以调用任意成员。
- 单例模式:(两种)饿汉式和懒汉式
饿汉式步骤如下:(类加载时就已经创建好了)
(1) 构造器私有化
(2) 类的内部创建对象(静态对象,因为需要在静态方法中被调用)
(3) 向外暴露一个静态的公共方法getInstance
懒汉式:只有当调用静态方法时才会创建静态对象。后面再调用时会返回第一次调用时创建的对象,从而保证单例的实现。
饿汉式VS懒汉式
- 二者创建的时机不同,饿汉式是在类加载时创建对象,懒汉式是在使用时创建
- 饿汉式没有线程安全问题,懒汉式会有线程安全问题
- 饿汉式存在浪费资源的问题
- final可以修饰类、属性、方法、和局部变量
- 不希望类继承时final修饰
- 不希望父类的方法被子类覆盖或重写时
- 不希望属性的值被修改时
- 不希望局部变量被修改时
- final类的属性被定义时必须赋初值,并且以后不能被修改。赋值的三种地方:定义时private final double TAX_RATE = 0.08;在构造器中;在代码块中
- 如果final修饰的属性是静态的,则初始化位置只能是定义时or静态代码块中,不能在构造器中赋值
- final类不能继承,但是可以实例化对象。
- final不能修饰构造器。
- final和static可以搭配使用,效率更高,不会导致类加载,底层编译器做了优化。
- 包装类都是final类,都不可以被继承。String类也是final类。