day11_类中成员之方法

news2024/11/18 16:43:24

成员变量是用来存储对象的数据信息的,那么如何表示对象的行为功能呢?就要通过方法来实现

方法

概念:

方法也叫函数,是一个独立功能的定义,是一个类中最基本的功能单元。把一个功能封装为方法的目的是,可以实现代码重用,从而简少代码量。

方法的使用原则

  • 必须先声明后使用。类,变量,方法等都要先声明后使用
  • 不调用不执行,调用一次执行一次。调用时必须严格匹配方法的参数情况。谁先调用,谁先执行
  • 方法执行完毕之后,会回到方法调用处
  • 方法体中的代码遵循自上而下的顺序依次逐行执行。
  • 方法与方法之间是平级关系,方法不能嵌套定义(在定义方法的内部又定义了其它方法),可以嵌套调用其它方法
  • 方法必须写在类中,不能独立存在。

声明方法语法格式

方法声明时:

  • 返回值类型、形参列表可以按照需求进行填写 

真正需要关注的就两点:

  • 分析方法是否需要申明返回值类型;
  • 分析方法是否需要接收参数。

例如: 

格式详解:

  • 修饰符: 修饰符后面一一介绍,例如:public,static等都是修饰符
  • 返回值类型:表示方法运行的结果的数据类型,方法执行后将结果返回到调用者。可以是基本数据类型也可以是引用数据类型,如果无返回值类型就可以使用void来代替
  • 方法名:给方法起一个名字,见名知意,能准确代表该方法功能的名字
  • 参数列表:方法内部需要用到其他方法中的数据,需要通过参数传递的形式将数据传递过来,可以是基本数据类型、引用数据类型。带参方法定义时,参数中的数据类型变量名都不能缺少,缺少任意一个程序将报错。带参方法定义时,多个参数之间使用逗号(,)分隔,且不能给初始化值。参数列表也可以为空。
  • 方法体:方法要完成特定功能代码
  • return:结束方法,并将方法的结果返回去。如果返回值类型不是void,方法体中必须保证一定有return 返回值语句,并且要求该返回值结果的类型与声明的返回值类型一致或兼容。如果返回值类型为void时,return 后面不用跟返回值,甚至也可以没有return语句。return语句后面就不能再写其他代码了,否则会报错:Unreachable code

成员方法分类

  • 实例方法:没有static修饰的方法,必须通过实例对象来调用
//有参,有返回值的实例方法
    public int getMax(int a, int b) {
        return (a > b ? a : b);
    }
  • 静态方法:有static修饰的方法,也叫类方法,可以由实例对象来调用也可以由类名来调用。推荐使用类名调用
  //有参,有返回值的静态方法
    public static int getMax(int a, int b) {
        return (a > b ? a : b);
    }

如何在其他类中调用方法

实例方法

类方法

​代码示例

public class Demo02Method {
    //无参,无返回值实例方法
    public void method1() {
        System.out.println("无参,无返回值方法");
    }

    //无参,有返回值静态方法
    public static int method2() {
        return 1;
    }
}

class TestDemo02Method{
    public static void main(String[] args) {
        //创建对象
        Demo02Method method = new Demo02Method();
        //调用实例方法
        method.method1();
        //调用静态方法
        method.method2(); //不推荐
        Demo02Method.method2(); //推荐
    }
}

如何在本类中调用方法

  • 直接写方法名,不需要加“对象名."和"类名."。唯一例外:静态方法中不能直接访问本类的非静态的成员变量和成员方法,因为静态的内容加载时间早于非静态内容需要在先创建对象才能间接使用。实例方法可以直接访问静态和非静态的资源。
public class Demo02Method {
    //无参,无返回值实例方法
    public void method1() {
        method2();//本类中调用其他方法
        System.out.println("无参,无返回值方法");
    }

    //无参,有返回值静态方法
    public static int method2() {
        //method1();错误:静态方法中不能直接访问本类的非静态的成员变量和成员方法
        return 1;
    }
}

形参和实参

  • 形参:在定义方法时方法名后面括号中声明的变量称为形式参数(简称形参)即形参出现在方法定义时。形参列表可以有多个,甚至可以没有; 如果有多个形参,多个形参必须用“,”隔开,且不能给初始化值。
  • 实参:调用方法时方法名后面括号中的使用的值/变量/表达式称为实际参数(简称实参)即实参出现在方法调用时

注意事项

  • 调用时,需要传“实参”,实参的个数、类型、顺序顺序要与形参列表一一对应如果方法没有形参,就不需要也不能传实参。
  • 调用时,如果方法有返回值,可以接受或处理返回值结果,当然也可以不接收,那么此时返回值就丢失了。如果方法的返回值类型是void,不需要也不能接收和处理返回值结果。

方法调用内存分析

java 程序开始执行的时候先通过类加载器子系统找到硬盘上的字节码 (class)文件,然后将其加载到 java 虚拟机的方法区当中,开始调用 main 方法,main 方法被调用的瞬间,会给 main 方法在“栈”内存中分配所属的活动空间,此时发生压栈动作,main 方 法的活动空间处于栈底。

也就是说,方法只定义不去调用的话,只是把它的代码片段存储在方法区当中,java 虚拟机是不会在栈内存当中给该方法分配活动空间的,只有在调用的瞬间,java 虚拟机才会在“栈 内存”当中给该方法分配活动空间,此时发生压栈动作,直到这个方法执行结束的时候,这个 方法在栈内存中所对应的活动空间就会释放掉,此时发生弹栈动作。

由于栈的特点是先进后出, 所以最先调用的方法(最先压栈)一定是最后结束的(最后弹栈)。比如:main 方法最先被 调用,那么它一定是最后一个结束的。换句话说:main 方法结束了,程序也就结束了(目前 来说是这样)。

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

方法体当中的代码是有执行顺序的,必须遵循自上而下的顺序依次逐行执行,当前行代码必须执行结束之后,下一行代码才能执行,不能跳行执行,还记得吗?现在再和栈数据结构一起联系起来思考一下,为什么要采用栈数据结构呢?是不是只有采用这种先进后出的栈数据结构才可以保证代码的执行顺序呢!

查看下列代码,分析是如何执行的

/*
    1.练习:
        设计一个方法可以获取两个int数的较大值,数据来自于参数

    2.三要素:
        (1)方法名称: getMax
        (2)参数列表: int a,int b
        (3)返回值类型: int

 */
public class Demo03GetMax {
    public static void main(String[] args) {
        System.out.println("main...start...");

        //调用方法: 传递的是常量
        int result = getMax(100,200);
        System.out.println("100和200的最大值: "+result);

        //调用方法方法: 传递变量
        int a = 10, b = 20;
        int max = getMax(a,b);
        System.out.println(a+"和"+b+"的最大值: "+max);

        System.out.println("main...end...");

    }

    //设计一个方法可以获取两个int数的较大值,数据来自于参数

    public static int getMax(int a, int b) {
        int max = (a>b) ? a : b;
        return max;//结束方法,并且把max中的数据,返还给方法的调用处/者
    }
}

图解分析

方法的调用

有返回值的方法调用方式

/*
    有返回值的方法调用方式
        1.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中              ----推荐使用----
            数据类型 变量名称 = 方法名称(参数...);

        2.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句
            System.out.println(方法名称(参数...));

        3.单独调用: 既不保存方法的结果,也没有对结果进行输出                   -----不推荐使用,没有意义-----
            方法名称(参数...);
 */
public class Demo01DYMethod {
    public static void main(String[] args) {
        System.out.println("main...start...");

        //1.赋值调用: 把有返回值的方法的调用结果保存到对应的变量中
        //数据类型 变量名称 = 方法名称(参数...);
        int result = getSum(10,20);
        //可以对结果数据做其它操作
        //result *= 100;
        System.out.println("和: "+result);

        //2.输出/打印调用: 把有返回值的方法的调用结果直接交给输出语句
        //System.out.println(方法名称(参数...));
        System.out.println(getSum(100,200));

        //3.单独调用: 既不保存方法的结果,也没有对结果进行输出
        getSum(5,10);

        System.out.println("main...end...");
    }

    //定义方法,获取2个int数字之和
    public static int getSum(int a, int b) {
        int sum = a + b;
        return sum;
    }
}

无返回值的方法调用方式

无返回值方法的调用只能直接调用。

public class Demo02 {
    public static void main(String[] args) {
        print(); //直接调用
    }
    public static void print(){
        for (int i = 0; i < 3; i++) {
            System.out.println("hello");
        }
    }
}

总结:

  • 方法没有被调用的时候,在方法区中的字节码文件中存放
  • 方法被调用的时候,需要进入到栈内存中运行

方法的参数传递机制

在传输实参给方法的形参的时候,并不是传输实参变量本身, 而是传输实参变量中存储的值,这就是值传递。

传递基本数据类型:形参值的改变不会影响实参。基本类型的参数传输存储的数据值。。

示例代码

public class ChangeValue {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println("a的值:" + a + " b的值:" + b); // a的值:1 b的值:2
        change(a, b);
        System.out.println("a的值:" + a + " b的值:" + b);// a的值:1 b的值:2
    }

    private static void change(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("a的值:" + a + " b的值:" + b);// a的值:2 b的值:1
    }
}

 传递引用数据类型:方法的形参是引用数据类型时,形参地址值的改变不会影响实参,但是形参地址值里面的数据的改变会影响实参,例如,修改数组元素的值,或修改对象的属性值。引用类型的参数传输存储的地址值。

示例代码

class Student {
    public int age;
}

public class ChangeValue2 {
    public static void main(String[] args) {
        Student student = new Student();
        student.age = 18;
        System.out.println(student.age); // 18
        changeValue(student);
        System.out.println(student.age); // 28
    }

    private static void changeValue(Student student) {
        student.age = 28;
        System.out.println(student.age);// 28
    }
}

注意事项:

在方法中,形参 = 新new对象,那么就和实参无关了

/*
陷阱1:在方法中,形参 = 新new对象,那么就和实参无关了
*/

class MyData {
    int num;
}

class Test {
    public static void change(MyData my) {
        my = new MyData();//形参指向了新对象
        my.num *= 2;
        System.out.println(my.num);//0
    }

    public static void main(String[] args) {
        MyData m = new MyData();
        m.num = 1;
        System.out.println(m.num);//1
        change(m);//调用完之后,m对象的num属性值仍然为1
        System.out.println(m.num);//1
    }
}

注意:String、Integer等特殊类型容易错。

class StringUtil{
    public void change(String str){
        str += "你好";//String对象不可变,一旦修改就会产生新对象
        System.out.println(str);//尚你好
    }
}

public class Test {
    public static void main(String[] args) {
        StringUtil util = new StringUtil();
        String str = "尚";
        System.out.println(str); //尚
        util.change(str);
        System.out.println(str); //尚
    }
}

可变参数

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

代码示例

public class Demo01 {
    public static void main(String[] args) {
        //求1-n个整数中的最大值
        int max = test(1,2,-3,45,3,4);
        System.out.println("max = " + max); //max = 45
    }

    private static int test(int... i) {
        int max = i[0];
        for (int j : i) {
            if (j > max){
                max = j;
            }
        }
        return max;
    }
}

 注意事项:

  • 一个方法最多只能有一个可变参数
  • 如果一个方法包含可变参数,那么可变参数必须是形参列表的最后一个

可变形参的本质就是数组,如下所示:

 只是后面这种定义,在调用时必须传递数组,而前者更灵活,既可以传递数组,又可以直接传递数组的元素,这样更灵活了。

下面2个方法编译器认为是一个方法,编译报错

    private static void sum(int... i) {
    }

    private static void sum(int[] i) {
    }

 下面2个方法本质是相同的,调用的时候jvm不能明确调用哪个,也会报错

   private static void sum(int... i) {
    }

    private static void sum(int i, int ... a) {
    }

方法重载

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

参数列表不同是指

  • 数据类型个数不同,数据类型不同,数据类型顺序不同。

重载方法调用

  • JVM通过方法的参数列表,调用不同的方法。

代码示例

public class Demo{
    //求两个整数的最大值
    public int max(int a, int b) {
        return a > b ? a : b;
    }

    //求三个整数的最大值
    public int max(int a, int b, int c) {
        return max(max(a, b), c);
    }

    //求两个小数的最大值
    public double max(double a, double b) {
        return a > b ? a : b;
    }
}

递归

递归:指在当前方法内调用自己的这种现象。

递归的分类:

  • 递归分为两种,直接递归和间接递归。
  • 直接递归称为方法自身调用自己。
  • 间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。

注意事项

  • 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
  • 在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

示例代码

//计算斐波那契数列(Fibonacci)的第n个值 ,
public class Demo06 {
    public static void main(String[] args) {
        int result= getResult(6);
        System.out.println("result = " + result);
    }

    private static int getResult(int i) {
        if (i == 1 || i == 2){
            return 1;
        }
        //规律:一个数等于前两个数之和,
        return getResult(i-1)+getResult(i-2);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/660605.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息安全原理与技术期末复习(如学)

文章目录 一、前言&#xff08;开卷打印&#xff09;二、选择题三、简答题1、简述端口扫描技术原理&#xff08;P136&#xff09;2、分组密码工作方式&#xff08;P61&#xff09;3、木马攻击&#xff08;P176&#xff09;4、消息认证码&#xff08;P84&#xff09;5、非对称密…

华为OD机试真题B卷 JavaScript 实现【删除字符串中出现次数最少的字符】,附详细解题思路

一、题目描述 删除字符串中出现次数最少的字符&#xff0c;如果多个字符出现次数一样则都删除。 二、输入描述 一个字符串。 三、输出描述 删除字符串中出现次数最少的字符&#xff0c;如果多个字符出现次数一样则都删除&#xff0c;如果都被删除 则换为empty。 四、解题…

机器视觉初步5-1:图像平滑专题

在计算机视觉领域&#xff0c;图像平滑处理是一个重要的任务&#xff0c;用于降低噪声&#xff0c;提高图像质量。常见的图像平滑算法有均值滤波、中值滤波、高斯滤波等。本文将介绍这些算法的原理&#xff0c;并分别给出使用Python与Halcon实现的代码。&#xff08;当前版本&a…

libface 人脸检测

于老师的项目地址GitHub - ShiqiYu/libfacedetection: An open source library for face detection in images. The face detection speed can reach 1000FPS. 关于如何使用&#xff0c;于老师写得很清楚&#xff1a; 测试代码 CMakeList.txt 和 三个face开头的cpp文件都是于老…

有趣的数学 数学建模入门一 从几个简单的示例入手

一、“变量”的概念 一个代数表达式&#xff08;通常只有一个字母&#xff1a;x&#xff0c;y&#xff0c;z…&#xff0c;如果它取代了一个未知值&#xff08;物理、经济、时间等&#xff09;&#xff0c;则称为“变量”。 变量的作用是占据一个值所在的位置&#xff0c;如果该…

设计模式之工厂方法模式笔记

设计模式之工厂方法模式笔记 说明Factory Method(工厂方法)目录UML抽象工厂示例类图咖啡抽象类美式咖啡类拿铁咖啡类 咖啡工厂接口美式咖啡工厂类拿铁咖啡工厂类 咖啡店类测试类 说明 记录下学习设计模式-工厂方法模式的写法。 Factory Method(工厂方法) 意图:定义一个用于创…

深度学习图像分类、目标检测、图像分割源码小项目

​demo仓库和视频演示&#xff1a; 银色子弹zg的个人空间-银色子弹zg个人主页-哔哩哔哩视频 卷积网路CNN分类的模型一般使用包括alexnet、DenseNet、DLA、GoogleNet、Mobilenet、ResNet、ResNeXt、ShuffleNet、VGG、EfficientNet和Swin transformer等10多种模型 目标检测包括…

Sourcetree 打开闪退怎么处理

问题描述&#xff1a;Sourcetree打开闪退&#xff0c;已管理员身份运行仍然闪退 解决方法; 在Sourcetree图标上右键&#xff0c;然后打开文件所在位置&#xff1a; 找到目录 xxxx\AppData\Local\Atlassian 删除箭头所指向文件即可。

2023年怎么移除微博粉丝 微博怎么批量移除粉丝方法

2023最新微博批量粉丝移除_手机微博粉丝怎么批量删除 使用微博粉丝移除工具&#xff1a;可以帮助用户快速批量移除粉丝。在微博管理工具中&#xff0c;用户可以根据自己的需要设置移除粉丝的数量&#xff0c;可以一键批量移除多个粉丝。此外&#xff0c;管理工具还提供了粉丝管…

Linux下使用Samba做域控

AI画妹子的工作先暂告一段落。毕竟戗行也是要有门槛的。 企业中使用Windows Server使用活动目录集中管理PC、服务器是很成熟的方案。突然想到&#xff0c;如果有一天出于某种原因不再使用微软方案了&#xff0c;AD该如何替代&#xff1f;问了一下chatGPT&#xff0c;它说&…

[Qt 教程之Widgets模块] —— QComboBox 组合框

Qt系列教程总目录 文章目录 一、创建QComboBox二、数据结构三、成员函数1. 添加选项2. 插入选项3. 删除选项4. 选项属性5. 当前选择的item6. 用户是否可编辑组合框7. 设置显示item的个数8. 组合框的item个数9. 添加重复的item10. 是否绘制边框11. 查找item12. 插入策略13. 大小…

NodeJS LocalDomainName⑩④

文章目录 ✨文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持&#x1f618;前言 L o c a l D o m a i n N a m e LocalDomainName LocalDomainName 本地域名 O p e r a t i o n P r o c e d u r e OperationProcedure OperationProced…

【MySQL】一文带你了解过滤数据

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集&#xff01; &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指…

LAMP架构搭建

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、Apache服务1.apache概述2.apache的特点3.apache的软件版本4.编译安装优点5.安装步骤 二、LAMP简介与概述1.LAMP平台概述2.构建LAMP平台顺序3.各组件的主要作用 …

KafKa 3.x(一、入门)

前置&#xff1a;熟悉javase&#xff0c;熟悉linux&#xff0c;熟悉idea&#xff0c;熟悉hadoop 1. KafKa 1.1 KafKa定义 前端埋点记录用户&#xff08;浏览&#xff0c;点赞&#xff0c;收藏&#xff0c;评论&#xff09;到日志服务器&#xff0c;然后通过Flume&#xff08…

k8s Service服务详解

1. Service 的概念&#xff1a; k8s中Service定义了这样一种抽象&#xff1a;一个pod的逻辑分组&#xff0c;一种可以访问他们的策略—通常称为微服务。这一组pod能够被Service访问到&#xff0c;通常是通过Label Selector Service能够提供负载均衡的能力&#xff0c;但是在使…

第二章 逻辑代数基础--数电(期末复习笔记)

第二章 逻辑代数基础 2.1 概述 逻辑&#xff1a;事物间的因果关系。 逻辑运算&#xff1a;逻辑状态按照指定的某种因果关系进行推理的过程。 逻辑变量&#xff1a;用字母表示&#xff0c;取值只有0和1。此时&#xff0c;0和1不再表示数量的大小&#xff0c;只代表两种不同的状…

人工智能期末复习(简答)

第1章 人工智能概述 1.什么是人工智能&#xff1f; 人工智能&#xff08;Artificial Intelligence, AI&#xff09;,又称机器智能&#xff08;MI&#xff0c;Machine Intelligence&#xff09;&#xff0c; 主要研究用人工的方法和技术开发智能机器或智能系统&#xff0c;以模…

交换机配置DHCP服务(华为交换机)

#三层交换机互联互通 配置 #进入系统视图 <Huawei>system-view #关闭系统提示信息 [Huawei]undo info-center enable #启动DHCP功能 [Huawei]dhcp enable #创建vlan 10 并配置 vlanif 地址 [Huawei]vlan 10 [Huawei-vlan10]int vlanif 10 [Huawei-Vlanif10]ip addr…

软考A计划-网络工程师-专业英语

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…