退出方法用 return
注:完成方法题的思路
1、方法的返回类型是什么?
2、方法的名字是什么?
3、方法的形参是什么?
4、方法体是什么?
// 使用OOP面向对象解决
// 实例化一只猫[创建一只猫对象]
// 1、new Cat() 创建一只猫
// 2、Cat cat1 = new Cat(); 把创建的猫赋给 cat1
// 3、cat1、cat2 就是一个对象
Cat cat1 = new Cat();
cat1.name = "小白";
cat1.age = 3;
cat1.color="白色";
// 创建第二只猫,并赋给 cat2
Cat cat2 = new Cat();
cat2.name = "小花";
cat2.age = 100;
cat2.color="花色";
//怎么访问对象的属性呢
System.out.println("第一只猫的信息"+cat1.name+"其它信息"+cat1.color+cat1.age);
System.out.println("第一只猫的信息"+cat2.name+"其它信息"+cat2.color+cat2.age);
}
}
// 使用面相对象的方式来解决养猫问题
// 定义一个猫类 Cat -> 自动义的数据类型
class Cat {
// 属性/成员变量
// 名字
String name;
// 年龄
int age;
// 颜色
String color;
}
注:只new 不引用称为匿名对象,匿名对象只能使用一次,使用后就不能使用了
一、对象在内存中的存在形式(非常重要)
注:因为 12 是 int类型,所以直接存放在堆里;因为 小白 是string类型,所以存放到常量池里;
在执行 Cat cat1 = new Cat(); 时,会加载Cat类信息
// cat1 是对象名(对象引用)
// new Cat() 创建的对象空间(数据) 才是真正的对象
二、属性/成员变量
-
基本介绍
2、注意事项和细节说明
三、类与对象
1、如何创建对象
2、如何访问属性
3、类和对象的内存分配机制(重要)
注:当程序执行到 b = null; 时,b 会滞空,将不会再指向0x0011,所以输出b.age时会报异常
4、java内存的结构分析
5、java创建对象的流程简单分析
Person p = new person();
p.name = "jack";
p.age = 10;
1、在执行 Person p = new person(); 时,先加载Person类信息(属性和方法信息,只会加载一次)
2、在堆中分配空间,进行默认初始化(看规则)
3、把地址赋给 p , p 就指向对象
4、进行指定初始化,比如 p.name = "jack"; p.age = 10;
四、成员方法
public class Lianxi {
public static void main(String[] args) {
// 方法使用
// 1、方法写好后,不去调用(使用),不会生效
// 2、先创建对象,然后调用方法即可
Person p1 = new Person();
// 调用方法
p1.speak();
// 调用方法cal01
p1.cal01();
// 调用cal02方法,同时给 n = 5
p1.cal02(5);
// 调用了getSum方法,同时给 num = 10 num = 20
// 把方法 getSum 返回的值,赋给 变量 returnRes
int returnRes = p1.getSum(10, 20);
System.out.println("getSum方法返回的值=" + returnRes);
int[][] map = {{0,1,2},{5,4,2},{4,5,3}};
p1.printArr(map);
}
}
class Person {
String name;
int age;
// 方法(成员方法)
// 添加speak 成员方法,输出”我是一个好人“
// 1、public :表示方法是公开的
// 2、void : 表示方法没有返回值
// 3、speak() :speak 是方法名,"()" 表示形参列表
// 4、{} :方法体,可以写我们要执行的代码
// 5、System.out.println("我是一个好人"); 表示我们的方法就是输出一句话
public void speak() {
System.out.println("我是一个好人");
}
// 添加cal01 成员方法,可以计算从 1+...+1000 的结果
public void cal01() {
// 循环完成
int res = 0;
for (int i = 1; i <= 1000; i++) {
res += i;
}
System.out.println("cal01方法 计算结果=" + res);
}
//注意:
// 添加cal02 成员方法,该方法可以接收一个数 n 计算从 1+...+n 的结果
// (int n) 形参列表,表示当前有一个形参 n ,可以接收用户输入
public void cal02(int n) {
int res = 0;
for (int i = 1; i <= n; i++) {
res += i;
}
System.out.println("cal02方法 计算结果=" + res);
}
//注意:
// 添加getSum 成员方法,可以计算两个数的和
// 1、public :表示方法是公开的
// 2、int :表示方法执行后,返回一个 int 值
// 3、getSum 方法名
// 4、(int num1, int num2) 形参列表,2个形参,可以接收用户传入的两个数
// 5、return res; 表示把 res 的值,返回
public int getSum(int num1, int num2) {
int res = num1 + num2;
return res;
}
public void printArr(int[][] map){
// 对传入的map数组遍历输出
for(int i = 0;i<arr.length;i++){
for(int j = 0;j<arr[i].length;j++){
System.out.print(map[i][j]+"\t")
}
System.out.println();
}
}
}
1、方法的调用机制:
注:当程序执行到 return res;时,getSum栈(独立空间)就会被销毁,释放资源
方法调用小结:
1、当程序执行到方法时,就会开辟一个独立的空间(栈空间)
2、当方法执行完毕,或者执行到 return 语句时,就会返回,返回到调用的地方
3、返回后,继续执行方法后面的代码
4、当main方法(栈)执行完毕,整个程序退出
2、成员方法的定义
3、成员方法的注意事项和细节
(1)访问修饰符、返回数据类型
public class Lianxi {
public static void main(String[] args) {
AA a = new AA();
// 1 、4 为实参
int[] res = a.getSumAndSub(1, 4);
System.out.println("和="+res[0]);
System.out.println("差="+res[1]);
}
}
class AA {
// 1、一个方法最多有一个返回值 [如果要返回多个结果 用数组进行返回]
// n1 、n2 为形参
public int[] getSumAndSub(int n1, int n2) {
// 创建数组
int[] resArr = new int[2];
resArr[0] = n1 + n2;
resArr[1] = n1 - n2;
return resArr;
}
}
(2)形参列表
(3)调用细节
public class Lianxi {
public static void main(String[] args) {
A a = new A();
a.sayOk();
a.m1();
}
}
class A {
//同一个类中的方法调用:直接调用即可
public void print(int n){
System.out.println("print()方法被调用 n=" + n);
}
public void sayOk(){
// sayOk调用 print (直接调用即可)
print(10);
System.out.println("继续执行sayOk");
}
// 跨类中的方法A类调用B类方法:需要通过对象名调用
public void m1(){
// 创建B对象,然后调用方法即可
System.out.println("m1() 方法被调用");
B b = new B();
b.hi();
System.out.println("m1() 继续执行");
}
}
class B {
public void hi() {
System.out.println("B类中的 hi()被执行");
}
}
2、成员方法传参机制
paramter(参数)
注:基本数据类型,传递的是值(值拷贝),形参的任何改变不影响实参
注:引用类型传递的是地址,可以通过形参影响实参!!!(对象的传递也是引用传递)
注:p = null; 指的是把自己滞空,自己不指向对象了,不会影响main栈
练习题:克隆对象
编写一个方法copyPerson,可以复制一个Person对象,返回复制的对象,克隆对象,注意要求得到新对象和原来的对象是两个独立的对象,只是他们属性相同
package ceshi.demo;
import static javax.print.attribute.standard.MediaSizeName.B;
public class Lianxi {
public static void main(String[] args) {
Person p = new Person();
p.name = "milan";
p.age = 100;
MyTools tools = new MyTools();
Person p2 = tools.copyPerson(p);
//到此 p 和 p2是Person对象,但是是两个独立的对象,属相相同
System.out.println("p的属性 age=" + p.age + "名字=" + p.name);
System.out.println("p2的属性 age=" + p2.age + "名字=" + p2.name);
//可以通过输出对象的hashCode看看对象是否是一个
// false
System.out.println(p == p2 );
}
}
class Person {
String name;
int age;
}
class MyTools {
// 1、方法的返回类型是什么?Person
// 2、方法的名字是什么? copyPerson
// 3、方法的形参是什么?(Person p)
// 4、方法体是什么? 创建一个新对象,并复制属性,返回即可
public Person copyPerson(Person p) {
// 创建一个新的对象
Person p2 = new Person();
// 把原来对象的名字赋给p2.name
p2.name = p.name;
// 把原来对象的年龄赋给p2.age
p2.age = p.age;
return p2;
}
}
五、递归
介绍:递归就是方法自己调用自己,每次调用时传入不同的变量。递归有助于编程者解决复杂问题,同时可以让代码变得简洁
// 打印问题
注:当程序执行到 t1.test(4) 时就会创建一个栈 ,此时新栈里面 n = 4 ,当程序执行到 test( 4-1)时,又调用自己创建了一个新栈,此时新栈里面 n = 3,当程序执行到 test(3-1) 时,又调用自己创建了一个新栈,此时新栈里面 n=2 ,因为 n =2 ,n >2 不成立,所以执行输出语句,输出 n =2,(n =2栈销毁释放资源),执行完后返回到 n =3 的栈里继续执行未完成的程序输出 n =3 , 以此类推
// 阶乘问题
注:哪儿调用就返回到哪儿,下图第五点
1、递归重要规则
六、方法重载
1、
介绍:java中允许同一个类中,多个同名方法的存在,但是要求形参列表不一致!
如:
public class Lianxi {
public static void main(String[] args) {
Mycalculate mc = new Mycalculate();
System.out.println(mc.calculate(1, 2));
System.out.println(mc.calculate(1.1, 2));
System.out.println(mc.calculate(2, 3.3));
System.out.println(mc.calculate(1, 2, 3));
}
}
class Mycalculate {
//下面的四个calculate方法构成了重载
// 两个整数的和
public int calculate(int n1, int n2) {
return n1 + n2;
}
// 一个整数,一个double的和
public double calculate(int n1, double n2) {
return n1 + n2;
}
// 一个double,一个int的和
public double calculate(double n1, int n2) {
return n1 + n2;
}
//三个int的和
public int calculate(int n1, int n2, int n3) {
return n1 + n2 + n3;
}
}
2、使用细节
练习:
七、可变参数
1、
注:注意基本语法中,... 不能省略
例如:
2、使用细节
八、作用域
1、基本使用
2、使用细节
九、构造方法/构造器(constructor)
1、
注意说明,构造器没有返回类型
构造器是初始化对象,不是在创建对象
2、使用细节
构造器的重载
第7点很重要
3、练习
public class Lianxi {
public static void main(String[] args) {
//无参构造器
Person p1 = new Person();
System.out.println("p1:name="+p1.name+"age="+p1.age);
Person p2 = new Person("king",20);
System.out.println("p1:name="+p2.name+"age="+p2.age);
}
}
class Person{
//默认值是 null
String name;
int age;
// 第一个无参构造器
public Person(){
//age默认18,只要创建Person,age就是18
age = 18;
}
public Person(String pName,int pAge){
name = pName;
age = pAge;
}
}
创建对象流程分析(加上构造器)
注:1、加载Person类信息(Person.class),只会加载一次
2、在堆中分配空间(地址)
3、完成对象初始化 [ 1、先进行默认初始化 age =0 name = null
2、显示初始化 age = 90 name = null
3、构造器的初始化 age = 20 name =小倩
4、在把对象在堆中的地址返回给 p(p是对象名/引用)]
十、this 关键字
1、
右边的name 和 age 还是局部变量
简单的说:哪个对象调用,this 就代表哪个对象
2、this关键字使用细节
注意:如果有 this(参数列表); 必须放在第一句话 ,访问构造器必须在构造器中使用,不能在普通方法中使用
练习: