一、IDEA软件
(1)快捷键修改
file->setting->Keymap进行修改
- 删除当前行(Delete Line) Ctrl+Y
- 复制当前行(Duplicate Line or Selection) Ctrl+D
- 补全代码 Alt+/
- 注释/取消注释 Ctrl+/
- 生成构造器(Generate Consructor) Alt+Insert
- 查看类的层级关系 Ctrl+H
- 光标放在方法上,查看方法的定义 Ctrl+B
- 自动分配变量名 在最后加.var
- 导入该行需要的类,先配置Editor->General->Auto import->(ADD...,Optimize...勾选) Alt+Enter
- 快速格式化 Ctrl+Alt+L
- 快速执行程序 Alt+R
(2)模板(Template)
file->setting->editor->Live templates->查看有哪些模板快捷键/可以自己增加模板
添加模板后需要定义(Define)适用范围
常用模板
- fori for循环
- main 主方法
- sout System.out.println("");
(3)查看jdk源码
- 一般来说IDEA配置好JDK后,jdk的源码也自动配置好了
- 如果没有的话,点击菜单File->Project Stucture->SDKs->Souce path,然后点击+号
选择jdk目录下的(javafx-src.zip和src.zip),最后点击Applay - 然后就可以使用ctrl+b了
二、包
作用:
- 区分相同名字的类
- 当类很多时,方便管理
- 控制访问范围
(1)基本语法
包的打包
package com.hspedu
- package 关键字,表示打包
- com.hspedu 表示包名
包的引入
import java.util.Scanner
import java.util.*
- import 关键字,表示导入包中的类
- 可以直接导入需要的类,也可以选择导入包中所有类,*表示当前包下所有类
(2)命名规则和规范
命名规则:只能包含数字、字母、下划线、小圆点,但不能用数组开头,不能是关键字或保留字
命名规范:
- 一般是小写字母+小圆点 (如: com.hh)
- 一般是 com.公司名.项目名.业务模块名
(3)常用的包
- java.lang.* //lang包时基本包,默认引入,不需要再引入
- java.util.* //util包,系统提供的工具包,工具类,使用 Scanner
- java.net.* //网络包,网络开发
- java.awt.* //是做java的界面开发GUI
(4)包的细节
- package的作用是声明当前类所在包,需要放在类的最前面,只能有一句package
- import指令,位置放在package的下面,可以有多句,没有顺序限制
(5)访问修饰符
java提供四种访问修饰符,用于控制方法和属性的访问范围。
- 公开级别:用public修饰,对外公开
- 受保护级别:用protected修饰,对子类和同一个包中的类公开
- 默认级别:没有修饰符号,向同一个包的类公开
- 私有级别:用private修饰,只有类本身可以访问,不对外公开
三、三幻神-封装、继承、多态
(1)封装(encapsulation)
1)封装的概念
介绍:把抽象出来的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作[方法],才能对数据进行操作。
好处:
- 隐藏实现细节
- 可以对数据进行验证,保证安全合理
2)封装的步骤
- 将属性进行私有化private(使无法直接调用属性)
- 提供一个公共的(public)set方法,用于对属性判断并赋值
public void setXxx(类型 参数名){ //Xxx表示属性名
//数据验证的业务逻辑
属性 = 参数名;
} - 提供一个公共的(public)get方法,用于对属性的获取
public void getXxx(){
return xxx;
}
(2)继承(extends)
继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个类存在相同的属性和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends来声明继承父类即可
1)基本语法
class 子类 extends 父类{
}
- 子类就会自动拥有父类定义的属性和方法
- 父类又叫超类,基类
- 子类又叫派生类
2)细节
- 子类继承了父类所有的属性和方法,但是私有属性(private)不能在子类直接访问,要通过父类提供的公共方法去访问,非私有的属性和方法可以在子类直接访问。
- 子类必须调用父类的构造器,完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作。
- 如果希望指定去调用父类的某个构造器,则显式的调用一下
- super在使用时,需要放在构造器第一行,且只允许在构造器中使用
- super()和this()都只能放在构造器第一行,因此两个方法不能共存
- java所有类都是Object类的子类,Object是所有类的父类
- 父类构造器的调用不限于直接父类,将一直追溯到Object类
- 子类最多只能继承一个父类(直接继承),则java中是单继承机制(extends后只能跟一个父类)
- 不能滥用继承,子类和父类必须满足is-a的逻辑关系(要有逻辑关系,比如人不能继承水果的属性和方法)
3)继承的本质
当子类对象创建好后,建立查找关系
分析:
- 当Son类对象创建后,会从顶层父类Object类开始从上到下查找子类直到Son类。
- 在堆中会分配一个空间,从上至下初始化属性,并指向位于常量池中的常量
- 初始化完成后,栈中的对象引用就会指向堆中这片空间的地址
例题:22-23
4)super关键字
介绍:super代表父类的引用,用于访问父类的属性、方法、构造器
基本语法:
- 访问父类的属性,但不能访问父类的private属性
super.属性名; - 访问父类的方法,不能访问父类的private方法
super.方法名(参数列表); - 访问父类的构造器
super(参数列表);只能放在构造器第一句,只允许出现一句
细节:
- 调用父类的构造器的好处(分工明确,父类属性由父类初始化,子类属性由子类初始化)
- 当子类中有和父类中的成员(属性和方法)重名时,为了访问父类的成员,必须通过super。如果没有重名,使用super、this、直接访问是一样的效果
- super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员;如果多个基类中都有同名的成员,使用super访问遵循就近原则
5)方法重写(Override)
介绍:方法覆盖(重写)就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么子类的这个方法就覆盖了父类的方法
细节:
- 子类的方法的参数,方法名称,要和父类方法的参数,方法名称完全一样
- 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类
- 子类方法不能缩小父类方法的访问权限
(3)多态(Polymorphic)
介绍:方法或对象具有多种状态。是OOP的三大特征之一,多态是建立在封装和继承上的。
1)方法的多态
方法的重载和重写就是多态的表现
2)对象的多态
介绍:
- 一个对象的编译类型和运行类型可以不一致,编译类型在定义对象时,就确定了,不能改变
- 运行类型是可以变化的,运行类型可以是编译类型的子类,可以通过getClass()查询运行类型
- 编译类型看定义时 = 号 的左边,运行类型看 = 号的右边
//Person person 中的Person是编译类型,new Person()中Person是运行类型 Person person = new Person(); //编译类型Animal类 与 运行类型Dog类是不同的 Animal dog = new Dog();
2.1 向上转型
本质:父类的引用指向了子类的对象
语法:
父类类型 引用名 = new 子类类型();
特点:
- 编译类型看左边,运行类型看右边
- 可以调用父类中所有成员(遵守访问权限)
- 不能调用子类中特有成员(编译时能调用的成员由编译类型决定)
- 最终运行效果看子类的具体实现,调用方法的查找顺序与继承一致,从运行类型(即两者中的子类)开始查找。
- 向上转型后,属性看编译,方法看运行
例题26
2.2 向下转型
语法:
子类类型 引用名 = (子类类型) 父类引用
- 只能强转父类的引用,不能强转父类的对象
- 强转时,要求父类的引用必须指向的是当前目标类型的对象
- 当向下转型后,可以调用子类类型中所有成员
例题26
2.3 属性重写
属性的值看编译类型,属性没有重写。
instanceOf 比较操作符,用于判断对象的运行类型是否为XXX的对象实例或其子类实例
对象名 instanceof 类名
//返回boolean类型
例题25
2.4 动态绑定机制
- 当调用对象方法时,该方法会和该对象的内存地址/运行类型绑定
- 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
例题27
3)多态数组
介绍:数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。
例题28
4)多态参数
介绍:方法定义的形参类型为父类类型,实参类型允许为子类类型
四、Object类的常用方法
(1)equals()
1)==
- ==:既可以判断基本类型,又可以判断引用类型
- ==:如果判断基本类型,判断的是值是否相等
- ==:如果判断引用类型,判断的是地址是否相等,即判断是不是一个对象
2)equals方法
- equals:是Object类中的方法,只能判断引用类型
- 默认判断的是 地址是否相等,子类中往往重写该方法,用于判断内容是否相等,如Integer,String
例题29
(2)hashCode方法
介绍:返回该对象的哈希码值,此方法是为了提高哈希表的性能。
实际上,由object类定义的hashCode方法确实会针对不同的对象返回不同的整数。(这一般是通过将对象的内部地址转换成一个整数来实现,但是java编程语言不需要这种实现技巧)
总结:
- 提高具有哈希结构的容器的效率
- 两个引用,如果指向的是同一个对象,则哈希值肯定一样
- 两个引用,如果指向的是不同对象,则哈希值是不一样的
- 哈希值主要根据地址号来的,但哈希值不完全等价于地址
- 在集合中,hashCode如果需要的话,也会重写
例题29
(3)toString方法
介绍:
- 默认返回:全类名+@+哈希值的十六进制,[查看Object的toString方法]
子类往往重写toString方法,用于返回对象的属性信息 - 全类名 = 包名 + 类名
- System,out,println(对象名),当输出一个对象时,toString方法默认调用,
例题29
(4)finalize方法
- 当对象被回收时,系统自动调用搞该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作
- 什么时候被回收:当某个对象没有任何引用时,则jvm就认为该对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法
- 垃圾回收机制的调用,是由系统来决定,也可以通过System.gc()主动触发垃圾回收机制
例题29
五、断点调试
介绍:
- 在断点调试 过程中,是运行过程,是以对象的 运行类型来执行的
- 断电调试时指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后就可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试出错的代码行即显示错误,停下,进行分析从而找到这个Bug
- 断点调试时程序员必须掌握的技能
- 断点调试也能帮助我们查看java底层源代码的执行过程,提高程序员的java水平
(1)快捷键
- F7(跳入) :跳入方法内
- F8(跳过):逐行执行代码
- Shift + F8(跳出):跳出方法
- F9(resume):执行到下一个断点
(2)F7没有进入源码的解决办法
方法一:
使用force step into 快捷键 alt + shift + F7
方法二:
点击Setting->Build,Execution,Deployment->Debugger->Stepping
把Do not step into the classes中的ajva.*,javax.*取消勾选