1.方法的重载:
1、什么叫做方法的重载?
在同一个类/对象中出现了两个或更多个,方法名相同,形参列表不同的方法,我们称为方法的重载。
和返回值类型无关。
方法名:代表方法的功能,即重载的几个方法的功能是一致的,只是处理的数据类型、个数不同。
关键词:方法名和形参列表
2、举例
声明一个我们自己的数学工具类MyMath,它里面包含这样的一组方法:
(1)boolean equals(byte a, byte b)
(2)boolean equals(int a, int b)
(3)boolean equals(double a, double b)
(4)boolean equals(String a, String b)
又包含另一组方法:
(1)int max(int a, int b)
(2)int max(int a, int b , int c)
3、重载方法,调用时的原则
(1)先看是否有实参的个数、类型最匹配的
(2)如果没有,看是否有形参可以兼容当前的实参
(3)如果没有,就报错
*/
public class TestOverload {
public static void main(String[] args) {
//比较两个数是否相同
byte b1 = 4;
byte b2 = 6;
System.out.println(MyMath.equals(b1, b2));
System.out.println("=-------------------------------");
int x = 5;
int y = 5;
System.out.println(MyMath.equals(x,y));
System.out.println("=-------------------------------");
int m = 6;
double d = 9.0;
System.out.println(MyMath.equals(m,d));
System.out.println("=-------------------------------");
long num1 = 56L;
long num2 = 90L;
System.out.println(MyMath.equals(num1, num2));
System.out.println("=-------------------------------");
String str = "hello";
double num = 67.0;
// System.out.println(MyMath.equals(str, num));//错误,一个方法都匹配不上
System.out.println("=-------------------------------");
System.out.println(MyMath.max(5,6));
System.out.println(MyMath.max(5,6,7));
System.out.println(MyMath.max(5,6,7,9,1));
}
}
class MyMath{
static boolean equals(byte a, byte b){
System.out.println(“byte”);
return a == b;
}
static boolean equals(int a, int b){
System.out.println(“int”);
return a == b;
}
static boolean equals(double a, double b){
System.out.println(“double”);
return a == b;
}
static boolean equals(String a, String b){
if(a == b){//地址相同
return true;
}
if(a == null && b!= null){//避免a==null时,a.equals发生空指针异常
return false;
}
return a.equals(b);
}
static double max(double a, double b){
return a > b ? a :b;
}
static int max(int a, int b){
System.out.println("2个");
return a>b?a:b;
}
static int max(int a, int b, int c){
System.out.println("3个");
return max(max(a,b),c);
}
static int max(int... nums){
System.out.println("n个");
if(nums == null || nums.length==0){//如果传入的是数据不符合要求,抛异常
throw new RuntimeException("不正常");
}
int max = nums[0];
for (int i = 0; i < nums.length; i++) {
if(max < nums[i]){
max = nums[i];
}
}
return max;
}
//不是重载,即两个方法名相同,形参列表相同,返回值类型不同的方法看成重载是错误的
/* //用于两个int值比较小的
static int sum(int a ,int b){
return a + b;
}
//用于两个int值比较大
static long sum(int a, int b){
return a + b;
}*/
}
2.陷阱1:
从声明的角度来说,只要方法名相同,形参列表不同,就是重载。
但是从调用者来说,必须能唯一确定一个方法匹配调用格式,否则这样的重载是有问题的。
陷阱2:
编译器会认为 int… 和int[]是一样的
2.命令行参数(了解)
了解:命令行参数
1、什么是命令行参数?
给main方法传入的实参就是命令行参数
public static void main(String[] args){
}
2、如何给main传入实参
(1)在命令行运行
java 主类名 参数1 参数2 。。。。 (参数值之间使用空格分隔)
(2)在idea中
Run菜单–> Edit Configurations -->
①确认一下,当前的main class是否是你要运行的main所在的类
②programm arguments:里面填写参数值,参数值之间使用空格分隔
3.递归(难)
1、什么叫递归?
当一个方法直接或间接出现自己调用自己就是递归。
void a(){
a();//直接调用自己
}
void b(){
c();//间接出现自己调用自己
}
void c(){
b();
}
2、问题
(1)如果不加条件限制,会出现栈内存溢出StackOverflowError
因为,方法的每一次调用都会在栈中开辟独立的空间,直到方法运行结束
(2)虽然加了条件,但是递归的太“深”,也会出现内存溢出StackOverflowError
3、注意
凡是会递归调用的方法必须加结束条件。
结束条件:当满足xx条件时不再递归。
4、举例:
(1)计算1-100之间所有自然数的和
1-100之间所有自然数的和 ==》 1-99之间所有自然数的和 + 100
1-99之间所有自然数的和 ==》 1-98之间所有自然数的和 + 99
…
1-2之间所有自然数的和 ==> 1 + 2
sum(int n):负责就1-n之间的和
(2)求n!
n! ==> (n-1)! * n
…
1! ==> 1
*/
public class TestRecursion {
static void a(){
System.out.println(“a被调用了”);
a();//Exception in thread “main” java.lang.StackOverflowError
}
public static void main(String[] args) {
//a();
System.out.println(sum(100));
System.out.println(jieCheng((10)));
System.out.println(f(5));
}
//(1)计算1-100之间所有自然数的和
//不考虑负数
static int sum(int n){
if(n==1){
return 1;
}
return sum(n-1) + n;
/*
n=1, sum(1)=> return 1;
n=2, sum(2)=> return sum(1) + 2
n=3, sum(3)=> return sum(2) + 3
...
n=100, sum(100) => return sum(99) + 100;
*/
}
//(2)n!
static int jieCheng(int n){
if(n==1){
return 1;
}
return jieCheng(n-1) * n;
}
//(3)示例三:计算斐波那契数列(Fibonacci)的第n个值
/*
规律:一个数等于前两个数之和,
f(0) = 1,
f(1) = 1,
f(2) = f(0) + f(1) = 2,
f(3) = f(1) + f(2) = 3,
f(4) = f(2) + f(3) = 5,
f(5) = f(3) + f(4) = 8,
...
f(n) = f(n-2) + f(n-1);
*/
static int f(int n){
if(n==0 || n==1){
return 1;
}
return f(n-2) + f(n-1);
}
}
4.对象数组
1、什么是对象数组?
把对象存到数组中,或者说,数组的元素是对象。
2、如何声明对象数组?
以一维数组为例
语法格式:
元素的数据类型[] 数组名;
只是现在的元素的数据类型是引用数据类型,例如是类。
3、初始化数组
(1)静态初始化
n象2 。。。};
简化:声明和静态初始化在一句
元素的数据类型[] 数组名 = {对象1, 对象2 。。。};
(2)动态初始化
数据类型【】数组名 = new 元素的数据类型[长度]; 到这步元素是默认值
数组名[下标] = 对象(new数据类型【】); 这一步非常关键,否则元素是null,会报空指针异常
数组名[下标].成员变量 或 数组名[下标].成员方法
4、如何使用对象数组的元素
强调:对象数组的元素是一个对象
数组名[下标]是一个对象,它的类型看你声明数组时[]前面的类型
(1)访问数组的元素的成员变量
数组名[下标].成员变量
(2)访问数组的元素的成员方法
数组名[下标].成员方法(【…】)
5.封装
1.封装是面向对象的第一个基本特征,也是最基本的特征。
2.为什么要封装
代码中:
(1)保护数据的安全,不能让使用者随意的使用我内部的成员(成员变量、成员方法。。。)
没有封装性,只要符合语法就可以使用,不受控制
(2)简化使用者的使用方式
可以把不需要使用者知道的内部细节给隐藏起来,这样呢使用者就不会关注太多的信息,反而不知道怎么使用。
2、如何封装?
给不同的类、以及它们的成员(方法、变量)加访问控制修饰符,不同的访问控制修饰符的可见性范围是不同。
3、有哪些访问控制修饰符,或者又称为权限修饰符?
从小到大:
private, 缺省(不写),protected, public
它们的可见性范围:
本类 本包 本包+其他包子类 任意位置
private √ × × ×
缺省(不写) √ √ × ×
protected √ √ √ ×
public √ √ √ √
4、哪些东西可以使用权限修饰符?
(1)类:只能有俩,一个是public,一个是缺省 现在不谈内部类
(2)成员变量:四种
(3)成员方法:四种
(4)其他,后面再加
特别注意:如果一个类使用了public,那么它必须与.java文件同名;
换句话说,一个.java源文件中,只能有一个public类,现在不谈内部类
6成员变量的封装问题
1、按照习惯上,如果没有特殊的需求,成员变量基本上是私有的,即private
因为成员变量中存储的是类或对象的数据,是需要重点保护的信息。
2、一旦成员变量私有化了,外部想要给成员变量赋值或访问成员变量的值怎么办?
(1)要确定该值确实需要外部操作
(2)如果是,那么可以提供对应的get/set方法。
get方法:给外面访问/获取成员变量的值的方法
set方法:给外面设置/修改成员变量的值的方法
3.get/set的标准格式
public void setXxx(数据类型 形参名){
…
成员变量 = 形参名;
}
public 数据类型 getXxx(){
return 成员变量;
}
注意:set和get后面是成员变量名把首字母变为大写
特殊的get方法:当成员变量是boolean类型,把get换为is
快捷键:快捷键alt + insert
7、this关键字
1、this单词本身的意思:这个
this在Java中什么意思:当前对象
2、this的用法
(1)this.成员变量
(2)this.成员方法
(3)this()或this(…) 明天讲
3、this.成员变量
表示访问当前对象自己的成员变量,区别于局部变量,
当成员变量与局部变量重名时,可以使用它区分。
4、this.成员方法
表示访问当前对象的其他成员方法。
这种形式,没有必须用的情况。
5、this不能出现在哪里?
不能出现在静态方法{}中。