目录
1.6.2 谈谈你对面向对象中类和对象的理解,并指出二者的关系?
1.6.3 面向对象思想的体现一:类和对象的创建和执行操作有哪三步?
1.6.4类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?
1 面向对象OOP和面向过程POP
1.1 面向对象的三条主线
Java类及类的成员:属性、方法、构造器;代码块、内部类
面向对象的三大特征:封装、继承、多态
其他关键字:this、super、static、final、abstract、interface、package、import
1.2 两者区别
人把大象装进冰箱
面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做
把冰箱打开、抬起大象塞进冰箱、关门
面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
*人{
* 打开(冰箱){
* 冰箱.开开();
* }
*
* 抬起(大象){
* 大象.进入(冰箱);
* }
*
* 关闭(冰箱){
* 冰箱.闭合();
* }
*
* }
*
*
* 冰箱{
* 开开(){}
* 闭合(){}
* }
*
* 大象{
* 进入(冰箱){
* }
* }
方便之处:拓展功能
两个要素:
* 类:对一类事物的描述,是抽象的、概念上的定义
* 对象:是实际存在的该类事物的每个个体,因而也称为实例(instance)
* >面向对象程序设计的重点是类的设计
* >设计类,就是设计类的成员。
1.3 举例:创建第一个类
区分类 对象 属性 方法
/*
* 一、设计类,其实就是设计类的成员
*
* 属性 = 成员变量 = field = 域、字段
* 方法 = 成员方法 = 函数 = method
*
* 创建类的对象 = 类的实例化 = 实例化类
*
* 二、类和对象的使用(面向对象思想落地的实现):
* 1.创建类,设计类的成员
* 2.创建类的对象
* 3.通过“对象.属性”或“对象.方法”调用对象的结构
*
* 三、如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性。(非static的)
* 意味着:如果我们修改一个对象的属性a,则不影响另外一个对象属性a的值。
*
* 四、对象的内存解析
*/
//测试类
public class PersonTest {
public static void main(String[] args) {
//2.创建Person类的对象
Person p1 = new Person();//为啥要重复写两个Person
//Scanner scannner = new Scanner(System.in);
//调用对象的结构:属性、方法
//调用属性:"对象.属性"
p1.name = "Tom";
p1.isMale = true;
System.out.println(p1.name);
//调用方法:"对象.方法"
p1.eat();
p1.sleep();
p1.talk("Chinese");
//**************************
Person p2 = new Person();
System.out.println(p2.name);
System.out.println(p2.isMale);
//**************************
//将p1变量保存的对象地址赋值给p3,导致p1和p3指向了堆空间中的同一个对象实体。
//类似array
Person p3 = p1;
System.out.println(p3.name);//Tom
p3.age = 99;
System.out.println(p1.age);//10
//创建类
Tiger t1 = new Tiger();
//调用属性
System.out.println(t1.name);
t1.name = "Queen";
System.out.println(t1.name);
t1.age = 8;
//调用方法
t1.eat();
t1.state();
}
}
//1.创建类:设计类的成员
class Person{
//属性
String name;
int age = 1;
boolean isMale;
//方法
public void eat(){
System.out.println("人可以吃饭");
}
public void sleep(){
System.out.println("人可以睡觉");
}
public void talk(String language){
System.out.println("人可以说话,使用的是:" + language);
}
}
class Tiger{
//属性
String name = "King";
int age = 10;
boolean isMale;
//方法
public void eat(){
System.out.println("老虎啥都吃");
}
public void state() {
System.out.println("老虎是丛林之王!");
}
}
1.4 内存解析
1.5 类中方法的声明和使用
1.5.1 方法:描述类应该具有的功能。
* 比如:Math类:sqrt()\random() \...
* Scanner类:nextXxx() ...
* Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...
*
* 1.举例:
* public void eat(){}
* public void sleep(int hour){}
* public String getName(){}
* public String getNation(String nation){}
1.5.2 方法的声明
权限修饰符public 返回值类型void 方法名sort(形参列表arr){
方法体
}
* 注意:static、final、abstract 来修饰的方法,后面再讲。
1.5.3 说明
* 3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
* Java规定的4种权限修饰符:private、public、缺省、protected -->封装性再细说
*
* 3.2 返回值类型: 有返回值 vs 没有返回值
* 3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用
* return关键字来返回指定类型的变量或常量:“return 数据”。
* 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要
* 使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
*
* 3.2.2 我们定义方法该不该有返回值?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
*
* 3.4 形参列表: 方法可以声明0个,1个,或多个形参。
* 3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...
*
* 3.4.2 我们定义方法时,该不该定义形参?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.5 方法体:方法功能的体现。
1.5.4 return关键字的使用:
* 1.使用范围:使用在方法体中
* 2.作用: ① 结束方法
* ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
* 3.注意点:return关键字后面不可以声明执行语句。
1.5.5 方法的使用中:
* 5.1可以调用当前类的属性或方法
* 5.2特殊的:方法A中又调用了方法A:递归方法。
* 5.3方法中,不可以定义方法。
public class CustomerTest {
public static void main(String[] args) {
Customer cust1 = new Customer();
cust1.eat();
//测试形参是否需要设置的问题
// int[] arr = new int[]{3,4,5,1,2,34,1};
// cust1.sort(arr);//排号后直接输出就ok
cust1.sleep(8);
}
}
//客户类
class Customer{
//属性
String name;
int age;
boolean isMale;
//方法
public void eat(){
System.out.println("客户吃饭");
return;//为什么要加?
}
public void sleep(int hour){
System.out.println("休息了" + hour + "个小时");
eat();//5.1
//sleep(10);5.2递归调用,会爆炸
}
public String getName(){
if(age > 18){//5.1
return name;
}else{
return "Tom";
}
}
public String getNation(String nation){
String info = "我的国籍是 " + nation;
return info;
}
//体会形参是否需要设置的问题
// public void sort(int[] arr){//排完就好
//
// }
// public void sort(){
// int[] arr = new int[]{3,4,5,2,5,63,2,5};
// //。。。。
// }
//不能在方法中调用方法
public void info(){
//错误的
// public void swim(){
//
// }
}
1.5 课后练习
1.5.1 写一个类并调用
写一个Person类
package com.exam.oop;
public class Person {
String name;
int age;//默认值0
/*
* sex = 1 男性
* sex = 0 女性
*/
int sex;
public void study(){
System.out.println("studying");
}
//展示当前的年龄
public void showAge(){
System.out.println("age: " + age);
}
//增加年龄
public int addAge(int i){
age += i;
return age;
}
}
调用Person类
package com.exam.oop;
/*
* 要求:
* (1)创建Person类的对象,设置该对象的name、age和sex属性,调用study方法,
* 输出字符串“studying”,调用showAge()方法显示age值,
* 调用addAge()方法给对象的age属性值增加2岁。
* (2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系。
*
*
*/
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Tom";
p1.age = 18;
p1.sex = 1;
p1.study();
p1.showAge();
int newAge = p1.addAge(2);
System.out.println(p1.name + " 的新年龄为: " + newAge);
System.out.println(p1.age);
//**************************
Person p2 = new Person();
p2.showAge();
p2.addAge(10);
p2.showAge();
p1.showAge();
}
}
1.5.2 编写一个可以输出矩阵的方法
package com.exam.oop;
public class Exam3Test {
public static void main(String[] args) {
Exam3Test e1 = new Exam3Test();
int area = e1.method(10, 8);
System.out.println("area is " + area);
}
public int method(int m, int n){
//m为行参数 n为列参数
//m n为形式参数,做菜的时候需要原材料了!
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print("* ");
}
System.out.println("\n");
}
return m * n;
}
}
1.5.3 编写一个students类
方法一:单独写了两个流程,没有封装
package com.exam.oop;
public class StudentTest {
public static void main(String[] args) {
//声明一个Student类型的数组
int personNum = 20;
Student[] stus = new Student[personNum];
//String[] str = new String[] 对象数组
for (int i = 0; i < personNum ; i++) {
//给元素赋值
stus[i] = new Student();
//给student对象的属性赋值
stus[i].number = i + 1;
stus[i].state = (int)(Math.round(Math.random() * 3));
stus[i].score = (int)(Math.random() * 101);
}
//遍历学生数组
//映射关系:栈stus的地址——》堆stus[i]的地址——》stus[i]的属性值
//打印每个对象的地址值
for (int j = 0; j < stus.length; j++) {
if (stus[j].state == 3) {
System.out.println(stus[j].info());
}
}
//冒泡排序:从小到大
for (int i = 0; i < stus.length - 1; i++) {
for (int j = 0; j < stus.length - 1 - i; j++) {
if (stus[j].score > stus[j + 1].score) {
int temp = stus[j].score;
stus[j].score = stus[j + 1].score;
stus[j + 1].score = temp;
}
}
}
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
}
}
class Student{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ", 年级:" + state + ", 成绩:" + score;
}
}
只要有new就会在堆里面生成一个
方法二:将一些操作封装起来
package com.exam.oop;
public class StudentTest3 {
public static void main(String[] args) {
//声明一个Student类型的数组
int personNum = 20;
//利用Student1类声明一个元素为Student1的数组
Student1[] stus = new Student1[personNum];
//String[] str = new String[] 对象数组
//给stus赋值
for (int i = 0; i < personNum ; i++) {
//给元素赋值
stus[i] = new Student1();
//给student对象的属性赋值
stus[i].number = i + 1;
stus[i].state = (int)(Math.round(Math.random() * 3));
stus[i].score = (int)(Math.random() * 101);
}
//生成主类的对象 test
StudentTest3 test = new StudentTest3();
//test调用主类的方法
//遍历学生数组
test.print(stus);
test.searchState(stus, 3);
test.sort(stus);
}
//遍历Student1[]数组的操作
public void print(Student1[] stus){
System.out.println("遍历学生数组:");
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
}
//查找Student1[]数组中指定年级的元素
public void searchState(Student1[] stus,int state){
System.out.println("遍历学生数组中年级为 " + state + " 的学生");
for (int j = 0; j < stus.length; j++) {
if (stus[j].state == state) {
System.out.println(stus[j].info());
}
}
}
public void sort(Student1[] stus){
//冒泡排序:从小到大
System.out.println("对数组进行冒泡排序:");
for (int i = 0; i < stus.length - 1; i++) {
for (int j = 0; j < stus.length - 1 - i; j++) {
if (stus[j].score > stus[j + 1].score) {
int temp = stus[j].score;
stus[j].score = stus[j + 1].score;
stus[j + 1].score = temp;
}
}
}
for (int i = 0; i < stus.length; i++) {
//System.out.println(stus[i]);//输出地址
System.out.println(stus[i].info());
}
}
}
class Student1{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ", 年级:" + state + ", 成绩:" + score;
}
}
重构:方法都放到子类,主类尽量简洁
package com.exam.oop;
public class StudentTest3 {
public static void main(String[] args) {
//声明一个Student类型的数组
int personNum = 20;
//利用Student1类声明一个元素为Student1的数组
Student1[] stus = new Student1[personNum];
//什么类型的数组? 生成一下?
//String[] str = new String[] 对象数组
//给stus赋值
for (int i = 0; i < personNum ; i++) {
//给元素赋值
stus[i] = new Student1();
//给student对象的属性赋值
stus[i].number = i + 1;
stus[i].state = (int)(Math.round(Math.random() * 6));
stus[i].score = (int)(Math.random() * 101);
}
//生成主类的对象 test
StudentTest test = new StudentTest();
//test调用主类的方法
//遍历学生数组
test.print(stus);
test.searchState(stus, 4);
test.sort(stus);
}
}
class Student1{
int number;//学号
int state;//年级
int score;//成绩
//显示学生信息的方法
public String info(){
return "学号:" + number + ", 年级:" + state + ", 成绩:" + score;
}
}
class StudentTest{
//遍历Student1[]数组的操作
public void print(Student1[] stus){
System.out.println("遍历学生数组:");
for (int i = 0; i < stus.length; i++) {
System.out.println(stus[i].info());
}
}
//查找Student1[]数组中指定年级的元素
public void searchState(Student1[] stus,int state){
System.out.println("遍历学生数组中年级为 " + state + " 的学生");
for (int j = 0; j < stus.length; j++) {
if (stus[j].state == state) {
System.out.println(stus[j].info());
}
}
}
public void sort(Student1[] stus){
//冒泡排序:从小到大
System.out.println("对数组进行冒泡排序:");
for (int i = 0; i < stus.length - 1; i++) {
for (int j = 0; j < stus.length - 1 - i; j++) {
if (stus[j].score > stus[j + 1].score) {
int temp = stus[j].score;
stus[j].score = stus[j + 1].score;
stus[j + 1].score = temp;
}
}
}
for (int i = 0; i < stus.length; i++) {
//System.out.println(stus[i]);//输出地址
System.out.println(stus[i].info());
}
}
}
1.5.4 MyDate类
1.6 Day8测试
1.6.1 面向对象思想编程内容的三条主线分别是什么?
类及类的成员:属性、方法、构造器;代码块,内部类
面向对象的三大特征:封装、继承、多态
其它关键字:this,super,abstract,interface,static,final,package,import
1.6.2 谈谈你对面向对象中类和对象的理解,并指出二者的关系?
类:抽象
对象:符合抽象出来的属性,被定义出来的一个实实在在的个体
1.6.3 面向对象思想的体现一:类和对象的创建和执行操作有哪三步?
创建类:class xxx{}
类的实例化:xxx yyy = new xxx() xxx[] yyy = new xxx[]
调用类的方法、属性:xxx.ccc = ? xxx.bbb()
1.6.4类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?
y y n y
package playground;
public class TigerTest {
public static void main(String[] args) {
Tiger t1 = new Tiger();
t1.name = "xiaolong";
t1.age = 19;
t1.showAge();//显示虚岁,实岁不变
t1.minusAge(10);//2.该方法会调用age属性 age=0
// t1.showAge();
}
}
class Tiger {
String name;
int age;
boolean sex;
public void bite(){
System.out.println("老虎可以咬人!");
}
//展示当前性别
public void showSex(boolean sex){
if (sex) {
System.out.println("是雄性老虎!");
} else {
System.out.println("是雌性老虎!");
}
}
//展示年龄
public void showAge(){
//1.声明变量
int addAge = 3;
System.out.println("这只老虎的年龄是(虚岁):" + (age + addAge));
//4.调用类中的其他方法
bite();
showSex(true);
}
//减少年龄
public int minusAge(int j){
//2.调用age
age -= j;
System.out.println("老虎现在的年龄是:" + age);
return age;
}
}
2 面向对象上概念总结
2.1 类与对象
2.1.1 JVM内存结构
编译完成后,生成一个或多个字节码文件。使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中
《JVM规范》
虚拟机栈:将局部变量存储在栈结构中。
堆:我们将new出来的结构(数组、对象)加载到堆空间中。补充:对象的属性(非 state)加载到堆空间中。方法区:类的加载信息、常量池、静态域。
2.2 类的结构之一:属性
/*
* 类中属性的使用
*
* 属性(成员变量) vs 局部变量
* 1.相同点:
* 1.1 定义变量的格式:数据类型 变量名 = 变量值
* 1.2 先声明,后使用
* 1.3 变量都有其对应的作用域
*
*
* 2.不同点:
* 2.1 在类中声明的位置的不同
* 属性:直接定义在类的一对{}内
* 局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
*
* 2.2 关于权限修饰符的不同
* 属性:可以在声明属性时,指明其权限,使用权限修饰符。
* 常用的权限修饰符:private、public、缺省、protected --->封装性
* 目前,大家声明属性时,都使用缺省就可以了。
* 局部变量:不可以使用权限修饰符。
*
* 2.3 默认初始化值的情况:
* 属性:类的属性,根据其类型,都有默认初始化值。
* 整型(byte、short、int、long):0
* 浮点型(float、double):0.0
* 字符型(char):0 (或'\u0000')
* 布尔型(boolean):false
*
* 引用数据类型(类、数组、接口):null
*
* 局部变量:没有默认初始化值。
* 意味着,我们在调用局部变量之前,一定要显式赋值。
* 特别地:形参在调用时,我们赋值即可。
*
* 2.4 在内存中加载的位置:
* 属性:加载到堆空间中 (非static)
* 局部变量:加载到栈空间
*
*/
2.2.1 变量的分类方法
2.3 类的结构之一:方法
/*
* 类中方法的声明和使用
*
* 方法:描述类应该具有的功能。
*
* 比如:Math类:sqrt()\random() \...
* Scanner类:nextXxx() ...
* Arrays类:sort() \ binarySearch() \ toString() \ equals() \ ...
*
* 1.举例:
* public void eat(){}
* public void sleep(int hour){}
* public String getName(){}
* public String getNation(String nation){}
*
* 2. 方法的声明:权限修饰符 返回值类型 方法名(形参列表){
* 方法体
* }
* 注意:static、final、abstract 来修饰的方法,后面再讲。
*
* 3. 说明:
* 3.1 关于权限修饰符:默认方法的权限修饰符先都使用public
* Java规定的4种权限修饰符:private、public、缺省、protected -->封装性再细说
*
* 3.2 返回值类型: 有返回值 vs 没有返回值
* 3.2.1 如果方法有返回值,则必须在方法声明时,指定返回值的类型。同时,方法中,需要使用
* return关键字来返回指定类型的变量或常量:“return 数据”。
* 如果方法没有返回值,则方法声明时,使用void来表示。通常,没有返回值的方法中,就不需要
* 使用return.但是,如果使用的话,只能“return;”表示结束此方法的意思。
*
* 3.2.2 我们定义方法该不该有返回值?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.3 方法名:属于标识符,遵循标识符的规则和规范,“见名知意”
*
* 3.4 形参列表: 方法可以声明0个,1个,或多个形参。
* 3.4.1 格式:数据类型1 形参1,数据类型2 形参2,...
*
* 3.4.2 我们定义方法时,该不该定义形参?
* ① 题目要求
* ② 凭经验:具体问题具体分析
*
* 3.5 方法体:方法功能的体现。
2.3.1.return关键字
* 1.使用范围:使用在方法体中
* 2.作用: ① 结束方法
* ② 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
* 3.注意点:return关键字后面不可以声明执行语句。
* 5. 方法的使用中:
* 5.1可以调用当前类的属性或方法
* 5.2特殊的:方法A中又调用了方法A:递归方法。
* 5.3方法中,不可以定义方法。
*/
3 匿名对象
代码
内存解析
在堆里面生成,赋值给show方法,形参作为局部变量储存在栈中。即将new出来的部分的地址值赋值给形参。
/**
*
*/
package com.lee.java;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日上午9:51:11
*/
public class Instance {
public static void main(String[] args) {
Phone p = new Phone();
System.out.println(p);//com.lee.java.Phone@15db9742
// p.sendEmail();
// p.playGame();
//匿名对象
new Phone().sendEmail();
new Phone().playGame();
new Phone().price = 1999;
new Phone().showPrice();//0.0
//*************************************
PhoneMall mall = new PhoneMall();
//匿名对象
mall.show(new Phone());
}
}
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
class Phone{
double price;//价格
public void sendEmail(){
System.out.println("发送邮件");
}
public void playGame(){
System.out.println("玩游戏");
}
public void showPrice(){
System.out.println("手机价格为:" + price);
}
}
4 自己写一个数组类
/**
*
*/
package com.lee.java;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日上午10:14:58
*/
/**
* 自定义数组的工具类
*
*/
public class ArrayTools {
//求数组的最大值
public int getMax(int[] arr) {
int maxValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > maxValue) {
maxValue = arr[i];
}
}
return maxValue;
}
//求数组最小值
public int getMin(int[] arr) {
int minValue = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] < minValue) {
minValue = arr[i];
}
}
return minValue;
}
//求数组的总和
public int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
//求数组的平均值
public int getAvg(int[] arr){
return getSum(arr) / arr.length;
}
//反转数组
public void reverse(int[] arr) {
for (int i = 0; i < arr.length / 2; i++) {
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
}
//复制数组
public int[] copy(int[] arr) {
int[] arr1 = new int[arr.length];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = arr[i];
}
return arr1;
}
//数组排序
public void sort(int[] arr){
//冒泡排序 从小到大
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr,j,j + 1);
}
}
}
}
//交换数组两个位置的元素
public void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//遍历数组
public void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
//查找指定元素
public int getIndex(int[] arr, int dest) {
//线性查找
for (int i = 0; i < arr.length; i++) {
if (dest == arr[i]) {
return i;
}
}
return -1;
}
}
/**
*
*/
package com.lee.java;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日上午10:34:06
*/
public class ArrayToolsTest {
public static void main(String[] args) {
ArrayTools util = new ArrayTools();
int[] arr = new int[]{32,34,32,5,3,54,654,-98,0,-53,5};
int max = util.getMax(arr);
System.out.println("最大值为:" + max);
System.out.println("排序前:");
util.print(arr);
util.sort(arr);
System.out.println("排序后:");
util.print(arr);
int key = -33;
System.out.println("查找:" + key);
int index = util.getIndex(arr, key);
if(index >= 0){
System.out.println("找到了,索引地址为:" + index);
}else{
System.out.println("未找到");
}
System.out.println("反转前: ");
util.print(arr);
util.reverse(arr);
System.out.println("反转后:");
util.print(arr);
}
}
5 再谈方法
5.1 重载
/*
* 方法的重载(overload) loading...
*
* 1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
*
* "两同一不同":同一个类、相同方法名
* 参数列表不同:参数个数不同,参数类型不同
*
* 2. 举例:
* Arrays类中重载的sort() / binarySearch() 查API
*
* 3.判断是否是重载:
* 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
*
* 4. 在通过对象调用方法时,如何确定某一个指定的方法:
* 方法名 ---> 参数列表
*/
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日上午11:08:32
*/
public class OverLoadTest {
public static void main(String[] args) {
OverLoadTest test = new OverLoadTest();
test.getSum(1, 2);//调用第一个/注释第一个会执行2
test.getSum(1.0, 2.0);
test.getSum("Nihao", 2);
}
//如下四个方法构成了重载
public void getSum(int i, int j){
System.out.println("1");
}
public void getSum(double i, double j){
System.out.println("2");
}
public void getSum(String s, int i){
System.out.println("3");
}
public void getSum(int i, String s){
System.out.println("4");
}
//如下的3个方法不能与上述4个方法构成重载
// public int getSum(int i,int j){
// return 0;
// }
// public void getSum(int m,int n){
//
// }
// private void getSum(int i,int j){
//
// }
}
5.2 可变个数的形参
/*
* 可变个数形参的方法
*
* 1.jdk 5.0新增的内容
* 2.具体使用:
* 2.1 可变个数形参的格式:数据类型 ... 变量名
* 2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
* 2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
* 2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
* 2.5 可变个数形参在方法的形参中,必须声明在末尾
* 2.6 可变个数形参在方法的形参中,最多只能声明一个可变形参。
*
*/
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日上午11:31:59
*/
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
test.show("hello");
test.show("hello","world","yeah");
test.show();
test.show(new String[]{"AA","BB","CC"});
}
public void show(int i){
}
//会被优先考虑
public void show(String s){
System.out.println("show(String)");
}
//传入几个变量都可以
public void show(String ...strs){
System.out.println("show(String ...strs)");
for (int i = 0; i < strs.length; i++) {
System.out.println(strs[i]);
}
}
//不能与上一个方法同时存在
// public void show(String[] strs){
//
// }
//The variable argument type String of the method
//show must be the last parameter
// public void show(String ...strs,int i){
//
// }
}
5.3 方法参数的值传递机制
/*
*
* 关于变量的赋值:
*
* 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
*/
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月26日下午3:14:28
*/
/**
* 方法的形参的传递机制:值传递
*
* 1.形参:方法定义时,声明的小括号内的参数
* 实参:方法调用时,实际传递给形参的数据
*
* 2.值传递机制:
* 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
* 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值。
*
*/
public class ValueTransferTest1 {
public static void main(String[] args) {
int m = 10;
int n = 20;
System.out.println("m = " + m + ", n = " + n);
//交换两个变量的值的操作
// int temp = m ;
// m = n;
// n = temp;
ValueTransferTest1 test = new ValueTransferTest1();
test.swap(m, n);
System.out.println("m = " + m + ", n = " + n);
}
//形式参数。此方法没法改变两个数
public void swap(int m,int n){
int temp = m ;
m = n;
n = temp;
}
}
第二种方法: * 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。
string是类 特例
5.3.1 面试题 参数传递
15 0
20
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月27日上午9:29:34
*/
public class ValueTransferTest3 {
public static void main(String[] args) {
ValueTransferTest3 test = new ValueTransferTest3();//栈空间压入test,test指向堆空间
test.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println(v.i);
}
public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println(v.i + " " + i);
}
}
class Value {
int i = 15;
}
5.3.2 面试题 貌似考参数传递
/**
*
*/
package com.lee.java1;
import java.io.PrintStream;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月27日上午9:43:42
*/
public class Test1 {
public static void main(String[] args) {
int a = 10;
int b = 10;
method(a,b);
System.out.println("a = " + a);
System.out.println("b = " + b);
//仅打印a=100 b=200
}
//加了static就不用声明对象也可以调用方法
// public static void method(int a, int b){
// a *= 10;
// b *= 20;
// System.out.println(a);
// System.out.println(b);
// System.exit(0);
// }
public static void method(int a, int b){
PrintStream ps = new PrintStream(System.out){
public void println(String x){
if ("a = 10".equals(x)) {
x = "a = 100";
}else if("b = 10".equals(x)) {
x = "b = 200";
}
super.println(x);
}
};
System.setOut(ps);
}
}
5.3.3 看似简单实则有坑的题
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月27日上午10:42:05
*/
//让数组的每个位置的元素除以首位置的元素,得到结果,作为该位置的新值
public class Test2 {
public static void main(String[] args) {
int[] arr = new int[]{12,3,3,34,56,77,432};
for (int i = arr.length - 1; i >= 0; i--) {
arr[i] = arr[i] / arr[0];
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月27日上午10:48:46
*/
public class ArrayPrintTest {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
System.out.println(arr);//地址值
char[] arr1 = new char[]{'a','b'};
System.out.println(arr1);//ab
}
}
5.3.4 将对象作为参数传递给方法
/**
*
*/
package com.lee.java1;
/**
* @Description
* @author LF E-mail:ljjrichard@163.com
* @version
* @date 2021年5月27日上午11:10:04
*/
public class CircleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
PassObject p1 = new PassObject();
p1.printAreas(c1, 7);
System.out.println("now radius is " + c1.radius);
}
}
class Circle{
double radius;
public double findArea(){
return Math.PI * radius * radius;
}
}
class PassObject{
public void printAreas(Circle c, int time){
System.out.println("Radius\t\tArea");
for (int i = 1; i <= time; i++) {
c.radius = i;
System.out.println(i + "\t\t" + c.findArea());
}
c.radius = time + 1;
}
}
5.4 递归
* 递归方法的使用(了解)
* 1.递归方法:一个方法体内调用它自身。
* 2. 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
* 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
n级台阶,我只能走1级或者2级,一共有几种走法
6 方法的课后练习
6.1 什么是方法的重载?
“两同一不同”:同一个类、相同方法名;参数列表不同。
如何调用确定的方法:方法名->参数列表
6.2 说明Java方法中的参数传递机制的具体体现?
基本数据类型:数据值
引用数据类型:地址值 (含变量的数据类型)
Person p1 = new Person(); eat();age
User u1 = p1;//编译错误 (逆向思维、反证法)
u1.eat() u1.age
3. 成员变量和局部变量在声明的位置上、是否有默认初始化值上、是否能有权限修饰符修饰上、内存分配的位置上有何不同?
6.4. 谈谈return关键字的使用
① 结束方法 ② 针对于有返回值的方法,return + 返回数据
5. 提供如下代码的内存解析
1. 内存结构:栈(局部变量)、堆(new出来的结构:对象(非static成员变量)、数组)
2. 变量:成员变量 vs 局部变量(方法内、方法形参、构造器内、构造器形参、代码块内)