包:
包的三大作用:区分相同名字的类;当类很多时,可以很好地管理类;控制访问范围
包的基本语法:package 包名;
包的本质:创建不同的文件夹/目录来保存类文件
包的命名规则与规范:
命名规则:只能包含字母、数字、下划线、小圆点,但不能用数字开头,不能是关键字或者保留字
命名规范:一般是小写字母+小圆点,一般是com.公司名.项目名.业务模块名
引入包的使用细节:
package的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多只有一句package
import指令位置放在package的下面,在类定义前面,可以有多句且没有顺序要求
访问修饰符:
四种访问修饰符的访问范围(背下来)
访问控制修饰符 | 同类 | 同包 | 子类 | 不同包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | x |
默认 | √ | √ | x | x |
private | √ | x | x | x |
使用注意事项:
访问修饰符可以用于修饰属性、方法和类
修饰类只能使用默认的和public,并且遵循上述访问权限的特点
成员方法的访问规则和属性完全一样
面向对象的三大特征:封装、继承和多态
封装(encapsulation):
介绍:封装就是把抽象出的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(方法),才能对数据进行操作
封装的理解和好处:隐藏实现细节;可以对数据进行验证,保证安全合理
封装的三步:将属性私有化——提供公共的set方法用于对属性进行判断并赋值——提供一个公共的get方法用于获取属性的值
继承:
基本语法:class 子类 extends 父类{
}
子类会自动拥有父类定义的属性和方法
父类又叫超类、基类
子类又叫派生类
便利:代码的复用性、扩展性和维护性提高了
使用细节:
子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
子类必须调用父类的构造器,完成父类的初始化
当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
如果希望指定去调用父类的某个构造器,则显式地调用一下:super(参数列表)
super在使用时,必须放在构造器第一行(super只能在构造器中使用)
super()和this()都只能放在构造器第一行,因此这两个方法不能共存在一个构造器中
Java所有类都是Object类的子类,Object是所有类的基类
父类构造器的调用不限于直接父类!将一直往上追溯直到Object类(顶级父类)
子类最多只能继承一个父类(指直接继承),即Java是单继承机制
不能滥用继承,子类和父类之间必须满足is-a的关系
通过子类对象访问属性和方法:首先看子类是否有该属性;如果子类有这个属性,并且可以访问,则返回信息;如果子类没有这个属性,就看父类有没有这个属性,如果父类有则返回,没有则继续找上级父类,直到Object;
子类创建的内存布局
super关键字
基本介绍:super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法
1、访问属性(不能访问private属性)
super.属性名;
2、访问方法(不能访问private方法)
super.方法名(参数列表);
3、访问父类构造器
super(参数列表) 只能放在构造器中的第一句,并且只能出现一句
super的细节说明:
调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类属性由子类初始化)
当子类中有和父类中的成员(属性和方法)重名时,为了直接访问父类的成员,必须使用super。如果没有重名,使用super、this、直接访问的效果相同
super的访问不限于直接父类,如果多个基类(上级类)中都有同名的成员,使用super访问遵循就近原则,也需要遵循访问权限的相关规则
super和this的比较
区别点 | this | super |
访问属性 | 访问本类中的属性,如果本类没有此属性则从父类中继续查找 | 从父类开始查找属性 |
调用方法 | 访问本类中的方法,如果本类没有此方法则从父类继续查找 | 从父类开始查找方法 |
调用构造器 | 调用本类构造器,必须放在构造器的首行 | 调用父类构造器,必须放在子类构造器的首行 |
特殊 | 表示当前对象 | 子类中访问父类对象 |
方法重写/覆盖(Override)
使用条件:
子类方法的形参列表、方法名称,要和父类方法的形参列表、方法名称完全一样
子类方法的返回类型要和父类方法的返回类型一样,或者是父类返回类型的子类
子类方法不能缩写父类方法的访问权限,但是可以扩大
方法重载和重写的区别
名称 | 发生范围 | 方法名 | 形参列表 | 返回类型 | 修饰符 |
重载 | 本类 | 必须一样 | 不一样,类型、个数、顺序至少有一个不一样 | 没有要求 | 没有要求 |
重写 | 子父类 | 必须一样 | 必须一样 | 一样或者是父类返回类型的 | 不能缩小父类的访问权限,但是可以扩大 |
多态(Polymorphic)
多态的基本介绍:方法或者对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承的基础之上
多态的具体体现
方法的多态:方法的重载和重写
对象的多态(难点):
核心要点:(1)一个对象的编译类型和运行类型可以不一致(2)编译类型在定义对象时,就确定了,不能改变(3)运行类型是可以变化的(4)编译类型看定义时=号的左边,运行类型看=号的右边
多态使用细节:
前提:两个对象(类)存在继承关系
多态的向上转型:
本质:父类的引用指向了子类的对象
语法:父类引用 引用名 = new 子类类型()
特点:编译类型看左边,运行类型看右边;可以调用父类中的所有成员(需要遵守访问权限),不能调用子类中特有成员;最终运行效果看子类的具体体现,即调用方法时,按照从子类(运行类型)开始查找,然后调用
多态的向下转型:
语法:子类类型 引用名=(子类类型)父类引用
只能强转父类引用,不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后,可以调用子类类型中所有成员
属性没有重写之所,属性看编译类型
instanceOf:比较操作符,用于判断对象的运行类型是XX类型或为XX类型的子类型
Java的动态绑定机制
当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定
当调用对象属性的时候,没有动态绑定机制,哪里声明,哪里使用
多态的应用:
多态数组:数组的定义类型为父类类型,里面保存的实际元素类型是子类类型
多态参数:方法定义的形参类型为父类类型,实参类型允许为子类类型
Object类详解
equals方法:
“==”是一个比较运算符,既可以比较基本类型,又可以判断引用类型;如果判断的是基本类型,判断的是值是否相等;如果判断的是引用类型,则判断地址是否相等
equals是Object类中的方法,只能判断引用类型;默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等,比如String、Integer
重写Object类中的equals方法
hashCode方法(6个小结):
提高具有哈希结构的容器的效率
两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
两个引用,如果指向的是不同对象,则哈希值是不一样的
哈希值主要根据地址号来的,但不能完全将哈希值等价于地址
toString方法
基本介绍:默认返回 全类名+@+哈希值的十六进制;子类往往重写toString方法,用于返回对象的属性信息
重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式
finalize方法
当对象被回收时,系统自动调用该对象的finalize方法;子类可以重写该方法,做一些释放资源的操作
回收的时间点:当对象没有任何引用时,jvm就会认为该对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法
垃圾回收机制的调用:由系统决定(有自己的GC算法),也可以通过System.gc()主动出发垃圾回收机制
断点调试快捷键:
F7跳入方法体内;
F8:逐行执行代码;
shift+F8:跳出方法
F9(resume,执行到下一个断点)