成员方法

  • 方法的概念
  • 方法的原则
  • 成员方法的分类
  • 定义实例方法的格式
  • 实例方法调用
  • 定义和调用实例方法举例
    • 声明客户和账户类、银行类
  • 方法调用内存分析
    • 可变参数
    • 举例1:找最大值
    • 举例2:字符串拼接
  • 方法重载
    • 方法重载示例:比较两个数据是否相等
  • 方法的参数传递机制
  • 命令行参数
  • 递归方法(recursion)
    • 举例1:计算1-100之间所有自然数的和
    • 举例2:计算斐波那契数列(Fibonacci)的第n个值

方法的概念

方法也叫函数,是一个独立功能的定义,是一个类中最基本的功能单元。

把一个功能封装为方法的目的是,可以实现代码重用,从而简少代码量。

方法的原则

方法的使用原则:

(1)必须先声明后使用

类,变量,方法等都要先声明后使用

(2)不调用不执行,调用一次执行一次。调用一次,在栈中压入一个方法栈。

成员方法的分类

成员方法分为两类:

  • 实例方法:属于对象的方法,由对象来调用。
  • 静态方法:也叫类方法,属于整个类的,不是属于某个实例,由类名来调用。

定义实例方法的格式

1、语法格式

修饰符 返回值类型 方法名(【参数列表:参数类型1 参数名1,参数类型2 参数名, ...... 】){方法体;【return 返回值;】
}
  • 修饰符: public(暂时写着一种,后面会补充)
  • 返回值类型: 表示方法运行的结果的数据类型,方法执行后将结果返回到调用者
    • 基本数据类型
    • 引用数据类型
    • 无返回值类型:void
  • 方法名:给方法起一个名字,见名知意,能准确代表该方法功能的名字
  • 参数列表:方法内部需要用到其他方法中的数据,需要通过参数传递的形式将数据传递过来,可以是基本数据类型、引用数据类型、也可以没有参数,什么都不写
  • 方法体:特定功能代码
  • return:结束方法,并将方法的结果返回去,
    • 如果返回值类型不是void,方法体中必须保证一定有【return 返回值;】语句,并且要求该返回值结果的类型与声明的返回值类型一致或兼容。
    • 如果返回值类型为void时,return 后面不用跟返回值,甚至也可以没有return语句。
    • return语句后面就不能再写其他代码了,否则会报错:Unreachable code

2、方法声明的位置必须在类中方法外(方法中不能声明方法)

正确示例:

类{方法1(){}方法2(){}
}

错误示例:

类{方法1(){方法2(){  //错误}}
}

实例方法调用

  • 方法调用的位置:在另一个方法中调用。

    正确示例:

    类{方法1(){调用其他方法;}
    }
    
  • 方法调用的分类:

    • 单独调用,格式如下:

      对象名.方法名(参数);
      
    • 输出或返回调用,格式如下:

      System.out.println(对象名.方法名(参数));//直接输出方法调用后的返回值或return 对象名.方法名(参数);//直接返回方法调用后的返回值作为当前方法的返回值
      
    • 赋值调用,格式如下:

      数据类型 变量名 = 对象名.方法名(参数);
      

如果实例方法是在本类的另一个实例方法中调用,那么可以省略“对象名.”

class Count {/*定义计算两个整数和的方法返回值类型,计算结果是int参数:不确定数据求和,定义int参数.参数又称为形式参数*/public int getSum(int a, int b) {return a + b;}/*定义计算两个整数差的方法返回值类型,计算结果是int参数:不确定数据求差,定义int参数.参数又称为形式参数*/public int getSubtract(int a, int b){return getSum(a,-b);//直接返回getSum(a,-b)方法调用的结果作为getSubtract(a,b)的结果}
}public class Method_Demo1 {public static void main(String[] args) {// 创建对象Count c = new Count();// 通过单独调用方式调用方法c.getSum(3,4);// 通过输出调用方式调用方法System.out.println(c.getSum(3,4));// 通过赋值调用方式调用方法int sum = c.getSum(3,4);System.out.println(sum);}
}
  • 形参:在定义方法时方法名后面括号中的变量名称称为形式参数(简称形参),即形参出现在方法定义中。
  • 实参:调用者方法中调用另一个方法时,方法名后面括号中的参数称为实际参数(简称实参),即实参出现在调用者方法中。

总结:

(1)调用时,需要通过方法名来识别调用哪个方法

(2)调用时,需要传“实参”,实参的个数、类型、顺序顺序要与形参列表一一对应

​ 如果方法没有形参,就不需要也不能传实参。

(3)调用时,如果方法有返回值,可以接受或处理返回值结果。

​ 如果方法的返回值类型是void,不需要也不能接收和处理返回值结果。

定义和调用实例方法举例

声明客户和账户类、银行类

  • 声明账户类Account

    • 包含:账户和余额两个实例变量
    • 包含save存款方法
    • 包含withdraw取款方法
  • 声明客户类Customer
    • 包含:姓名和手机、身份证号、拥有的一个账户,四个实例变量
  • 声明银行类BankClerk
    • 包含open方法,给某个客户对象开户,关联Customer和Account两个对象的信息
class Account{String id;double balance;public void save(double money){if(money > 0){balance += money;}else{System.out.println("参数有误");}}public void withdraw(double money){if(money <0){System.out.println("参数有误");}else if(money > balance){System.out.println("余额不足");}else{balance -= money;}}
}
class Customer{String name;String tel;String cid;Account account;
}
class BankClerk{public void open(Customer c, Account a){c.account = a;}
}
public class Method_Exer6 {public static void main(String[] args) {//创建客户对象Customer c = new Customer();c.name = "柴林燕";c.tel = "10086";c.cid = "111111111111111111";//创建银行卡账号对象Account a = new Account();a.id = "12345678910";a.balance = 0;//银行对象BankClerk b = new BankClerk();b.open(c, a);System.out.println("姓名:" + c.name + ",电话:" + c.tel + ",身份证号:" + c.cid + ",账号:" + c.account.id + ",余额:" + c.account.balance);//存款c.account.save(1000);System.out.println("姓名:" + c.name + ",电话:" + c.tel + ",身份证号:" + c.cid + ",账号:" + c.account.id + ",余额:" + c.account.balance);//取款c.account.withdraw(2000);//显示信息System.out.println("姓名:" + c.name + ",电话:" + c.tel + ",身份证号:" + c.cid + ",账号:" + c.account.id + ",余额:" + c.account.balance);}
}

方法调用内存分析

方法不调用不执行,调用一次执行一次,每次调用会在栈中有一个入栈动作,即给当前方法开辟一块独立的内存区域,用于存储当前方法的局部变量的值,当方法执行结束后,会释放该内存,称为出栈,如果方法有返回值,就会把结果返回调用处,如果没有返回值,就直接结束,回到调用处继续执行下一条指令。

栈结构:先进后出,后进先出。

class Test18_Invoke_Memory{public static void main(String[] args){Count c = new Count();int x = 1;int y = 2;int sum = c.getSum(x,y);System.out.println(x + " + " + y + " = " + sum);}
}
class Count{public int getSum(int a, int b){return a + b;}
}

可变参数

JDK1.5之后,如果我们定义一个方法时,此时某个形参的类型可以确定,但是形参的个数不确定,那么我们可以使用可变参数。

格式:

修饰符 返回值类型 方法名(【非可变参数部分的形参列表,】参数类型... 形参名){ 方法体;}

要求:

(1)一个方法只能有一个可变参数

(2)可变参数必须是形参列表的最后一个

(3)其实这个书写“等价于”

修饰符 返回值类型 方法名(【非可变参数部分的形参列表,】参数类型[] 形参名){ 方法体;}

只是后面这种定义,在调用时必须传递数组,而前者更灵活,既可以传递数组,又可以直接传递数组的元素,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。

好处:

同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。

代码演示:

public class ChangeArgs {public static void main(String[] args) {// 创建对象Count c = new Count();int[] arr = { 1, 4, 62, 431, 2 };int sum1 = c.getSum1(arr);System.out.println(sum1);int sum2 = c.getSum2(arr);System.out.println(sum2);int sum3 = c.getSum2(1, 4, 62, 431, 2);System.out.println(sum3);}}class Count {// 完成数组 所有元素的求和// 原始写法public int getSum1(int[] arr) {int sum = 0;for (int i = 0; i < arr.length; i++) {sum += arr[i];}return sum;}// 可变参数写法public int getSum2(int... arr) {int sum = 0;for (int i = 0; i < arr.length; i++) {sum += arr[i];}return sum;}
}

举例1:找最大值

定义求1-n个整数中的最大值

public class ChangeArgs_Exer1 {public static void main(String[] args) {Count c = new Count();System.out.println(c.max(1));System.out.println(c.max(5,3,2,6));}
}
class Count{public int max(int num, int... others){int max = num;for (int i = 0; i < others.length; i++) {if(max < others[i]){max = num;}}return max;}
}

举例2:字符串拼接

定义将n个字符串进行拼接,如果没有传入字符串,那么返回空字符串

public class ChangeArgs_Exer2 {public static void main(String[] args) {StringUtil su = new StringUtil();System.out.println(su.concat());System.out.println(su.concat("hello","world"));}
}
class StringUtil{public String concat(String... args){String str = "";for (int i = 0; i < args.length; i++) {str += args[i];}return str;}
}

方法重载

  • 方法重载:指在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表不同即可,与修饰符和返回值类型无关。
  • 参数列表:数据类型个数不同,数据类型不同,数据类型顺序不同。
  • 重载方法调用:JVM通过方法的参数列表,调用不同的方法。

方法重载示例:比较两个数据是否相等

比较两个数据是否相等。参数类型分别为两个byte类型,两个short类型,两个int类型,两个long类型,并在main方法中进行测试。

public class Method_Demo6 {public static void main(String[] args) {//创建Count c = new Count();//定义不同数据类型的变量byte a = 10;byte b = 20;short c = 10;short d = 20;int e = 10;int f = 10;long g = 10;long h = 20;// 调用System.out.println(c.compare(a, b));System.out.println(c.compare(c, d));System.out.println(c.compare(e, f));System.out.println(c.compare(g, h));}
}class Count {// 两个byte类型的public boolean compare(byte a, byte b) {System.out.println("byte");return a == b;}// 两个short类型的public boolean compare(short a, short b) {System.out.println("short");return a == b;}// 两个int类型的public boolean compare(int a, int b) {System.out.println("int");return a == b;}// 两个long类型的public boolean compare(long a, long b) {System.out.println("long");return a == b;}
}

方法的参数传递机制

  • 形参:在定义方法时方法名后面括号中的变量名称称为形式参数(简称形参),即形参出现在方法定义中。
  • 实参:调用者方法中调用另一个方法时,方法名后面括号中的参数称为实际参数(简称实参),即实参出现在调用者方法中。
  • 方法的参数传递机制:实参给形参赋值
    • 方法的形参是基本数据类型时,形参值的改变不会影响实参;
    • 方法的形参是引用数据类型时,形参地址值的改变不会影响实参,但是形参地址值里面的数据的改变会影响实参,例如,修改数组元素的值,或修改对象的属性值。
      • 注意:String、Integer等特殊类型除外

示例代码1:

class Test{public static void swap(int a, int b){int temp = a;a = b;b = temp;}public static void main(String[] args){int x = 1;int y = 2;swap(x,y);//调用完之后,x与y的值不变}
}

陷阱实例1:

/*
陷阱1:在方法中,形参 = 新new对象,那么就和实参无关了
*/
class Test{public static void change(MyData my){my = new MyData();//形参指向了新对象my.num *= 2;}public static void main(String[] args){MyData m = new MyData();m.num = 1;change(m);//调用完之后,m对象的num属性值仍然为1}
}class MyData{int num;
}

陷阱实例2:

public class Test {public static void main(String[] args) {StringUtil util = new StringUtil();String str = "尚硅谷";util.change(str);System.out.println(str);}
}
class StringUtil{public void change(String str){str += "你好";//String对象不可变,一旦修改就会产生新对象}
}

命令行参数

通过命令行给main方法的形参传递的实参称为命令行参数

public class TestCommandParam{//形参:String[] argspublic static void main(String[] args){System.out.println(args);System.out.println(args.length);for(int i=0; i<args.length; i++){System.out.println("第" + (i+1) + "个参数的值是:" + args[i]);}}
}

运行命令:

java TestCommandParam
java TestCommandParam 1 2 3
java TestCommandParam hello atguigu

递归方法(recursion)

  • 递归:指在当前方法内调用自己的这种现象。
  • 递归的分类:
    • 递归分为两种,直接递归和间接递归。
    • 直接递归称为方法自身调用自己。
    • 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
  • 注意事项
    • 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
    • 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

举例1:计算1-100之间所有自然数的和

public class RecursionMethod1{public static void main(String[] args) {Count c = new Count();int sum = c.sum(100);System.out.println("1-100的和:" + sum);}
}
class Count{public int sum(int n){if(n == 1){return 1;}else{return n + sum(n-1);}}
}

举例2:计算斐波那契数列(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(n) = f(n-2) + f(n-1);

public class RecursionMethod3{public static void main(String[] args) {Count c = new Count();System.out.println("f(10):" + c.f(10));System.out.println("f方法被调用的总次数:" + c.total);}
}
class Count{int total = 0;public int f(int n){total++;if(n <= 1){return 1;}else{return f(n-2) + f(n-1);}}
}

零基础Java学习之成员方法相关推荐

  1. java学习笔记:零基础java学习路线+配套资料+书籍推荐

    公众号菜鸟名企梦2018年,精品文章汇总: 01 我的秋招 我的秋招offer 我的offer选择 秋招全面总结-必读宝典 求职必读 02 零基础学习路线 零基础-java学习路线(上) 零基础-ja ...

  2. 授人予鱼不如授人予渔:零基础java学习路线分享

    一切不以求职找工作为目标的学习路线分享都是耍流氓. 博主是19年7月毕业的应届生:985.A+学科硕士.2018年的秋招收获了:百度.腾讯.头条.美团.猿辅导.度小满.猫眼.流利说等offer.off ...

  3. 零基础——java学习路线(下)

    学习路线分上中下三篇,前两篇已经发布了,本文是学习路线系列的最后一篇.有没有提到的点或学习疑问欢迎评论区留言~ 公众号后台回复"资料"即可获取学习资料大礼包,你想找的基本都有,外加 ...

  4. 零基础Java学习之接口

    介绍 接口的介绍我们从三个方面来说: 从使用上来说是继承的一种扩展,因为java不支持多继承,而有了接口就能够实现多继承的效果. 有时候需要必须从几个类中抽取出一些共同的行为特征,而它们之间又没有继承 ...

  5. 零基础Java学习之继承

    继承 继承的概述 继承的理解 继承的好处 继承的格式 继承的特点一:成员变量 私有化(private) 成员变量不重名 成员变量重名 继承的特点二:成员方法 成员方法不重名 成员方法重名--重写(Ov ...

  6. 零基础Java学习之多态

    介绍 多态是Java的三大特性之一,另外两个分别是:继承和封装(前面博客已经说了继承和封装了,可以看一下).这两个可以说在一定程度了为多态打下了基础. 通过多态,可以实现一个行为具有多种形态,这里的形 ...

  7. 零基础Java学习之包(Package)

    包的作用 1.可以避免类重名 有了包之后,类的全名称就变为:包.类名 2.分类组织管理众多的类 例如: java.lang----包含一些Java语言的核心类,如String.Math.Integer ...

  8. 零基础Java学习之类和对象

    类和对象 类 对象 类与对象的关系 类的定义和对象的创建 事物与类的对比 类的定义格式 对象的创建 类 类:是一类具有相同特性的事物的抽象描述,是一组相关属性和行为的集合.可以看成是一类事物的模板,使 ...

  9. 零基础Java学习之this关键字

    this的含义 this代表当前对象的引用(地址值),即对象自己的引用. this可以用于构造器中:表示正在创建的那个实例对象,即正在new谁,this就代表谁 this用于实例方法中:表示调用该方法 ...

最新文章

  1. 扩增子图表解读6韦恩图:比较组间共有和特有OTU或分类单元
  2. ADO.NET与XML的结合
  3. 【机器学习入门笔记10:TensorFlow矩阵基础】20190217
  4. 审计 Linux 系统的操作行为的 5 种方案对比
  5. c# 定位内存快速增长_CTF丨Linux Pwn入门教程:针对函数重定位流程的相关测试(下)...
  6. python中定制类_python定制类__str__(实例详解)
  7. LeetCode 986. 区间列表的交集
  8. 开机按f12怎么恢复系统 开机按f12恢复系统
  9. vmware工具克隆linux系统步骤及配置
  10. 从零开始学前端:链接跳转 --- 今天你学习了吗?(CSS:Day03)
  11. 【汇编优化】之CPUID获取x86处理器信息
  12. Nginx如何实现读写限流的方法
  13. bim 水利枢纽 运维_BIM——运维专篇
  14. 揭秘黑客攻击内幕和20个黑客相关术语
  15. [渝粤教育] 内蒙古大学 微生物学 参考 资料
  16. 悉尼大学计算机科学gpa,悉尼大学计算机gpa
  17. 听说你还不会制作“GIF动图”,手把手包教会,这不就来了吗
  18. php长图生成,用 3 行代码就可以生成好看的锤子便签图片(传入内容即可,俗称长微博)...
  19. 大数据学习之——Zookeeper安装
  20. 正在连接172.16.1.54:9703...无法打开到主机的连接。 在端口 23: 连接失败

热门文章

  1. 【 Vivado 】基本的时序约束、分析的概念
  2. 【 FPGA 】时序分析中的基本概念和术语
  3. 【 Notes 】Best linear unbiased estimator(BLUE) approach for time-of-arrival based localisation
  4. 【 MATLAB 】程序流程控制语句格式简记
  5. 【 C 】用动态数组实现堆栈
  6. PLL_BASE——Basic Phase Locked Loop Clock Circuit(Virtex-5, Spartan-6)
  7. 配置tomcat虚拟主机
  8. 将Linux脚本中的正常输出,警告,错误等信息输出到文件中
  9. Map集合的遍历(java)
  10. NOIP2013pj车站分级[拓扑排序]