一、Java中参数的传递机制:值传递
-
规则:
- 如果变量是基本数据类型,此时赋值的是变量所保存的数据值
-
如果变量是引用数据类型,此时赋值的是变量所保存的地址值
-
面向对象的特征一:封装与隐藏
- 当我们创建一个类的对象以后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。
-
这里赋值操作要受到属性的数据类型和存储范围的制约。但是除此之外,没有其他制约条件。
3. 但是,在实际问题当中,我们往往需要给属性赋值加入额外的限制条件。这个条件就不能在属性声明时提现,我们只能通过方法进行限制条件的添加。
4. (比如说:setLegs()方法)
5. 同时,我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。则需要将属性声明为私有的(private)
6. --> 此时,针对属性就体现了封装性。
二、封装的体现
-
我们将类的属性私有化(private),同时提供公共的(public)方法来获取(getXXX)和设置(setXxx)此属性的值
-
拓展:封装的体现:① 如上 ② 不对外暴露的私有的方法 ③ 单例模式 …
-
封装性的体现需要权限修饰符来配合。
1.Java规定了4种权限(从小到大排列):private\缺省\protected\public
2.4种权限可以用来修饰类及内部结构:属性、方法、构造器、内部类
3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类。
-
修饰类的话,只能使用:缺省、public
-
总结封装性:Java提供了4种权限修饰符来修饰类及类内部的结构,体现类及类的内部结构在被调用时的可见性的大小。
继承
- 子类中所有的构造方法默认都会访问父类中无参的构造方法
- 子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。所以子类初始化之前一定先完成父类的初始化。
- 怎么初始化?构造方法的第一条语句默认都是:super()
- 注意:我们编写的类,没有手动指定父类,系统也会自动继承Object(Java继承体系中的最顶层父类)
super关键字的使用
- super理解为:父类的
- super可以用来调用:属性、方法、构造器
- super的使用
- 我们可以在子类的方法或构造器中。通过使用“super.属性”或“super.方法”的方式,显式的调用父类中声明的属性或方法。但是通常情况下,我们习惯省略“super.”
- 特殊情况:当子类和父类中定义了同名的属性时,我们想要在子类中调用父类中声明的属性,则必须显式的使用“super.属性”的方式,表明调用的是父类中声明的属性。
多态
- 子类对象可以赋值给父类引用
- 只能对引用调用其引用类型中声明的方法
- 运行时,根据对象实际类型,调用子类覆盖之后的方法
- 对象类型不变 强制类型转换,用于父类引用赋值给子类引用,无法改变对象类型。
- 引用 instanceof 类名 “判断引用中的对象 是不是 类名” 用作在强制类型转换之前进行类型判断,避免类型转换异常
abstract(抽象类)
- 抽象类和抽象方法必须使用abstract关键字修饰
- public abstract class 类名{}
- public abstract void eat();
- 抽象方法:只有声明 没有实现
- 有抽象方法的类一定是抽象类,抽象类不一定有抽象方法
- 抽象类不能实例化
- 参照多态的方式,通过子类对象实例化,这叫抽象类多态
- 抽象类的子类
- 要么是抽象类
- 要么重写抽象类中的所有抽象方法
- 抽象类的成员特点
- 成员变量
- 可以是变量
- 也可以是常量
- 构造方法
- 有构造方法,但是不能实例化
- 那么,构造方法的左右是什么呢?用于子类访问父类数据的初始化
- 成员方法
- 可以使抽象方法:限定子类必须完成某些动作
- 也可以是非抽象方法:提高代码的复用性
- 成员变量
- 抽象类名作为形参和返回值
- 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
- 方法的返回值是抽象类名,其实返回值是该抽象类的子类对象
static
- 属性:静态属性 全类共有 可以用类名直接访问
- 方法:类名调用 静态方法中只能访问类的静态成员,不能出现this
- 静态方法只能被子类的静态方法覆盖,而且没有多态(只根据引用类型,调用相应的静态方法)
- 初始代码块:静态初始代码块在类加载的时候执行
- 类加载:当JVM第一次使用一个类时,读入这个类所对应的.class文件,并保存起来。
- 类加载的时机:1)创建对象 2)加载子类,需要先加载父类 3)访问静态成员 4)Class.forName(“类名”)
- 如果只是声明一个类的引用,不需要类的加载。
- 类加载的步骤:
- 如果需要,先加载父类
- 按照顺序初始化静态属性,或执行静态初始代码块
方法覆盖override
- 子类用特殊的方法实现,替换掉父类继承给它的方法实现
- 语法:方法名相同,参数列表相同,返回值类型相同,访问修饰符相同或更宽
- 从JDK5开始,子类方法的返回值类型 可以是父类方法返回值类型的子类
final
- 变量:常量 一旦赋值,不可改变
- public static final
- final修饰属性的时候,该属性就没有默认值,就必须手动赋值
- 修饰基本数据类型,使其数据值不能被改变
- 修饰引用数据类型,使其地址不能被改变
- 方法:final修饰的方法不能被子类重写
- 类:final类不能被继承
- private 属性 方法 构造方法
- (default) 属性 方法 构造方法 类
- protected 属性 方法 构造方法
- public 属性 方法 构造方法 类
- private abstract 不能联用
- final abstract 不能联用
- static abstract 不能联用
接口(特殊的抽象类)
- 接口就是一种公共的规范标准,只要符合规范标准,大家都可以通过Java中的接口更多的体现在对行为的抽象。
- 接口特点
- 属性都是公开静态常量 public static final
- 方法都是公开抽象方法 public abstract
- 构造方法
- 没有构造方法(构造器),因为接口主要是对行为进行抽象的,是没有具体存在
- 一个类如果没有父类,默认继承自Object类
- 成员方法
- 只能是抽象方法
- 默认修饰符:public abstract
- 接口不能实例化
- 接口如何实现实例化?参照多态的方式,通过实现对象的实例化,这叫接口多态。
- 多态的形式:具体类多态,抽象类多态,接口多态。
- 多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象。
- 接口的实现类
- 重写接口中的所有抽象方法
- 要么是抽象类
- 类和接口的关系
- 类和类的关系
- 继承关系,只能单继承,但是可以多层继承
- 类和接口的关系
- 实现关系,可以单实现,也可以多实现,还可以继承一个类的同时实现多个接口
- 接口和接口的关系
- 继承关系,可以单继承,也可以多继承
- 类和类的关系
- 抽象类和接口的区别
- 成员区别
- 抽象类:变量,常量;有构造方法,也有抽象方法
- 接口:常量;抽象方法
- 关系区别
- 类与类:继承,单继承
- 接口与类:实现,可以单实现,也可以多实现
- 接口与接口:可以单继承,也可以多继承
- 设计理念区别
- 抽象类 对类抽象,包括属性、行为
- 接口 对行为抽象,主要是行为
- 成员区别
- 接口之间可以定义多继承关系
- 一个类在继承另外一个类的同时,还能实现多个接口
- 子类引用可以直接赋值给父类引用
- 父类引用需要强转才能赋值给子类引用
- 没有继承关系的两种类型之间不能强转赋值
- 强转的两种类型中,如果包含接口类型,强转代码一定编译通过
- 弱耦合性
- 接口作为标准,使接口的使用者和接口的实现者分离,实现弱耦合关系
- 接口回调:程序员负责实现接口,从而实现接口中的方法,而不用关心方法何时被谁调用
- 接口名作为形参和返回值
- 方法的形参是接口名,其实需要的是该接口的实现类对象
- 方法的返回值是接口名,其实返回值是该接口的实现类对象
JDK8版本中接口成员的特点
- JDK版本后
- 允许在接口中定义非抽象方法,但是需要使用关键字default
- 允许在接口中定义静态方法,public static
内部类
- 内部类的访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
- 静态内部类:只能访问外部类的静态成员
- 创建方法:外部类名.内部类名 对象名 = new 外部类名.内部类名();
- 成员内部类:创建对象:先创建外部类对象,再通过外部类对象.new 内部内部类类名() 创建内部类对象
- 外部类类名.this引用外部类的当前对象
- 局部内部类
- 作用范围:从定义开始,到代码块结束
- 局部内部类不能定义静态成员
- 局部内部类可以访问外部类的私有成员,还能访问外部类的局部变量,但是要加final
- 匿名内部类:特殊的局部内部类
- 格式:new 类名或者接口名(){ 重写方法 }
- 是一个继承某个类或者实现某个接口的子类对象
- 只会创建一个对象
- 用法:new 父类名或者接口名() {继承父类或者实现接口的代码}
内部类
- 内部类的访问特点
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
- 静态内部类:只能访问外部类的静态成员
- 创建方法:外部类名.内部类名 对象名 = new 外部类名.内部类名();
- 成员内部类:创建对象:先创建外部类对象,再通过外部类对象.new 内部内部类类名() 创建内部类对象
- 外部类类名.this引用外部类的当前对象
- 局部内部类
- 作用范围:从定义开始,到代码块结束
- 局部内部类不能定义静态成员
- 局部内部类可以访问外部类的私有成 员,还能访问外部类的局部变量,但是要加final
- 匿名内部类:特殊的局部内部类
- 用法:new 父类名或者接口名() {继承父类或者实现接口的代码}
- 理解:将(继承/实现)(方法重写)(创建对象)三个步骤,放在了一步进行
- 是一个继承某个类或者实现某个接口的子类对象
- 只会创建一个对象
- Lambda表达式(匿名内部类使用的优化)
- 标准格式:(形参) -> (代码块)
- 使用前提:有一个接口、接口中仅有一个抽象方法
- 形参:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
- ->:由英文中划线和大于符号组成,固定写法。代表指向动作
- 代码块:是我们具体要做的事情,也就是以前我们写的方法内容
- 省略规则:
- 参数类型可以省略,但是有多个参数的情况下,不能只省略一个
- 如果参数有且仅有一个,那么小括号可以省略
- 如果代码块语句只有一条,可以省略大括号和分号,甚至是return
- 与匿名内部类的区别
- 所属类型不同
- 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
- Lambda表达式:只能是接口
- 使用限制不同
- 如果接口中只有一个抽象方法,可以使用lambda表达式,也可以使用匿名内部
- 类如果接口中多于一个抽象方法,只能使用你名内部类,而不能使用lambda表达式
- 实现原理不同
- 匿名内部类:编译之后,产生一个单独的.class字节码文件
- lambda表达式:编译之后没有一个单独的字节码文件。对应的字节码文件会在运行的时候动态生成
- 所属类型不同
Object 所有Java类的父亲
- Object o = 任何对象
- Object类中的方法是所有对象都具有的方法
- 本身有11个方法
- getClass():返回对象的实际类型Class对象(反射)
- toString(): public String toString() 返回值是对象的字符串形式,等同于打印对象的toString()方法的返回值
- 可以重写覆盖此次方法
三、进制
-
语法
- 十进制:默认不加修饰符
- 十六进制:数值前加 0x
- 八进制:数值前面加 - 0
- 二进制:数值前面加 - 0b
-
进制转换
- 其他进制转换为十进制公式:系数*基数^权重
- 十进制转换为其他进制:除以基数,取余数,然后余数倒过来写。
Random范围公式
- 数字范围(a - b) => ( b - a +1)+a
import关键字的使用
import:导入
- 1.在源文件中显式的使用import结构导入指定包下的类、接口
- 2.声明在包的声明和类的声明之间
- 3.如果需要导入多个结构,则并列写出即可
- 4.可以使用xxx.*的方式,表示可以导入xxx包下的所有结构。
- 5.如果使用的类或接口是java.lang包下定义的,则可以省略import结构
- 6.如果使用的类或接口是本包下定义的,则可以省略import结构
- 7.如果在源文件中,使用了不同包下的同名类,则必须至少有一个类需要以全类名的方式显示。
- 8.使用"xxx.*"方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显示导入。
- 9.import static:导入指定类或接口中的静态结构:属性或方法。
1.1多态概述
- 同一对象,在不同时刻表现出来的形态
- 多态的前提和体现
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
1.2多态中成员访问的特点
- 成员变量:编译看左边,运行看左边
- 成员方法:编译看左边,运行看右边
- 为什么成员变量和成员方法访问不一样呢?
- 因为成员方法有重写,而成员变量没有
1.3多态的好处和弊端
- 多态的好处:提高了程序的扩展性
- 具体体现:定义方法的时候,使用父类型作为作为参数,将来在使用的时候,使用具体的子类型参与操作。
- 多态的弊端:不能使用子类的特有功能。
Objects类的常用方法
- toString(对象) 返回参数中对象的字符串表示形式
- toString(对象,默认字符串) 返回对象的字符串表示形式
- isNull(对象) 判断对象是否为空
- nonNull(对象) 判断对象是否不为空
BigDecimal(用来进行精确计算)
- add(另一个BigDecimal对象) 加法
- subtract(另一个BigDecimal对象) 减法
- multiply(另一个BigDecimal对象) 乘法
- divide(另一个BigDecimal对象) 除法
- //参数一:表示参数运算的另一个对象
- //参数二:表示小数点后精确到多少位
- //参数三:舍入模式**//**进一法BigDecimal.ROUND_UP
- **//**去尾法BigDecimal.ROUND_FLOOR
- //四舍五入BigDecimal.ROUND_HALF_UP
基本类型包装类
- 概述:将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
- 常用的操作之一:用于基本数据类型与字符串之间的转换“123”-> 123
- 自动装箱和自动拆箱
- 装箱:把基本数据类型转换为对应的包装类类型
- 拆箱:把包装类类型转换为对应的基本数据类型
- 注意:在使用包装类类型的时候,如果做操作,最好先判断是否为null,我们推荐的是,只要是对象,在使用前就必须进行不为null的判断
- int和string的相互转换
- 基本类型包装类的最常见操作就是:用于基本类型和字符串之间的相互转换
- int装换为string
- 方式一:直接与“”相加自动转换类型
- 方式二:使用String.valueof(int a)方法转换为字符串类型
- 将String字符串转化为int数组进行存储缤纷遍历。利用Integer中的方法parseInt()
数组的高级操作
-
基本查找
-
数组的二分查找步骤
-
public static int BinarySearch(int[] arr, int value){ //定义两个变量,表示要查找的范围,min=0,max=最大索引 int min = 0;int max = arr.length-1; //循环查找,但是min<=max while (min <= max){ int mid = (max + min) >> 1; if (arr[mid]==value){ return mid; }else if (mid<value){ min = mid+1; }else if (mid>value){ max = mid-1; } } return -1; }
-