zoukankan      html  css  js  c++  java
  • 0008方法传递机制、重载、可变参数、对象数组、封装、构造器

    001方法的参数传递机制-------------------------------------------------------------

    /*
    方法的参数传递机制:
    实参-->形参

    (1)形参是基本数据类型
    实参赋值给形参的是数据值,形参值的修改不影响实参,因为实参是“copy,复制”了一份数据值给形参
    (2)形参是引用数据类型
    */

    /*

    class Test02_PassParamValue{
    public static void main(String[] args){
    int x = 1;
    int y = 2;
    //本类同级别的方法调用
    swap(x,y);

    System.out.println("x = " + x + ",y = " + y);
    }
    //public static修饰符
    public static void swap(int a,int b){
    System.out.println("a = " + a + ",b = " + b);
    int temp = a;
    a = b;
    b = temp;
    System.out.println("a = " + a + ",b = " + b);
    }
    }


    方法的参数传递机制:
    实参-->形参

    (1)形参是基本数据类型
    实参赋值给形参的是数据值,形参值的修改不影响实参,因为实参是“copy,复制”了一份数据值给形参


    (2)形参是引用数据类型
    实参赋值给形参的是对象的地址值,如果形参修改了对象的属性值,那么实参对象的属性值也会修改。
    */

    class Test02_PassParamValue_2{
    public static void main(String[] args){
    Circle yuan = new Circle();
    yuan.radius = 1.0;

    doubleRadius(yuan);

    System.out.println("半径:" + yuan.radius);
    }
    //方法的功能:可以把c这个圆对象的半径,变为原来的2倍
    public static void doubleRadius(Circle c){
    c.radius *= 2;
    }

    }
    class Circle{
    double radius;
    }

    -----------------面试时的陷阱-----------------------------------------------------------

    /*
    面试时的陷阱:
    当形参是引用数据类型,实参给形参地址值之后,
    形参修改了地址值,那么和实参就无关了
    */

    实际上,就是你new了一个新的对象之后,之前的地址就不是这个了,那么你所改的都不存在了,相当于没有调用这个方法,因为这个方法改变不了任何东西

    ------------------方法的重载------------------------------------------------

    /*
    方法的重载:
    在同一个类中,出现了两个或多个的方法名称相同,形参列表不同,称为方法的重载。
    形参列表不同:形参的个数、数据类型不同
    方法的重载和返回值类型无关。

    为什么要有方法的重载?或者换句话说,为什么要声明多个方法名称相同呢?
    (1)方法名代表方法的功能,这几个方法的功能是一样的,例如:都是找最大值
    (2)为了调用者的方便,功能相同的方法取名一样的话,对于调用者来说就减少了学习和记忆的成本
    */

    class test08_4Overload{
    public static void main(String[]args){

    System.out.println( max(1,2));
    }
    //写一个方法,可以找2个整数的最大值
    /*
    public static int max(int a, int b){
    return a>b ? a : b;
    }
    */
    //方法重载时,不去看返回值类型是否一致,只看方法名和形参列表
    public static double max(int a,int b){
    return 0.0;
    }
    //写一个方法,可以找2给小数的最大值
    public static double max(double a, double b){
    return a>b ? a : b;
    }
    //写一个方法,可以找3个整数的最大值
    public static int max(int a, int b, int c){
    int max = a > b ? a : b;
    max = max > c ? max : c;
    return max;
    }
    }

     -----------命令行参数--------------------------------------------------

    /*
    命令行参数:(了解)
    给main方法传的实参,叫做命令行参数
    格式:
    java main所在的类名 实参1 实参2 ...
    例如:
    java Test04_CommandParam hello java atguigu
    */

    /*
    因为main也是一个有参无返回值的方法,那么如何给main传参数呢?
    */

    【注意】命令行参数虽然简单但是不会的人也是完全不会

    下面说一下,操作办法,非常简单

    只要在命令行输入 比如:  java 类名(包含主方法的类) hello java atguigu

     ----------------------可变参数---------------------------------------

    /*
    可变参数:JDK1.5之后引入的
    形参列表中出现了“数据类型... 形参名”形式的形参,就是可变参数。
    包含可变参数的方法的调用原则:
    (1)可变参数的形参部分,可以传入0~n个对应类型的实参,也可以传入对应类型的数组对象
    (2)非可变参数的形参部分,原来该怎么传,现在还怎么传

    可变参数的声明的原则:
    (1)一个方法只能包含一个可变参数
    (2)可变参数必须是形参列表的最后一个
    参数:
    (1)形参
    (2)实参
    (3)命令行参数
    (4)可变参数
    (5)...
    */

    其实C#里面也有可变参数,叫做params,java中也有这个概念,概念相同,关键字不同,写法稍微有点变化

    1、可变参数当数组使用

     

     完整代码:

    class test08_6VarParam可变参数{
    /*
    因为main也是一个有参无返回值的方法,那么如何给main传参数呢?
    */
    //java test08_5CommandParam hello java atguigu;
    public static void main(String[]args){
    //args是形参,是String[]类型,是一个一维数组
    for(int i=0;i<args.length;i++){
    System.out.println("第"+(i+1)+"个参数的值是:"+args[i]);
    }
    //开始可变参数部分
    System.out.println("这里面的数的和" + sum(2,4,1));

    System.out.println("这里面的最大值是" + max(2,4,6,7,8));

    int [] arr1 = new int[0];
    System.out.println("0个元素的累加和:" + sum(arr1));//可变参数部分,传入了对应类型的数组对象

    int[] arr2 = {1,2,3,4,5};
    System.out.println("5个元素的累加和:" + sum(arr2));//可变参数部分,传入了对应类型的数组对象

    System.out.println("0个元素的累加和:"+sum());//可变参数部分,传入0个实参int的值

    //注意点
    System.out.println("1个元素的最大值:"+max(5));//5赋值给了非可变参数的形参
    System.out.println("5个元素的最大值"+max(5,1,5,6,8));//第1个5赋值给了非可变参数的形参,剩下的给了可变参数

    //错误写法示例(如果要运行无错,请注释这段)
    System.out.println("1个元素的最大值:"+max());////错误的,因为max方法有一个非可变参数的形参,必须传值
    }

    //声明一个方法,功能:可以求两个整数的和
    public static int sum(int a,int b){
    return a + b;
    }
    //声明一个方法,功能:可以求0-n个整数的和
    public static int sum(int...nums){
    //1、nums当成数组用
    int sum=0;
    for(int i=0;i<nums.length;i++){
    sum+=nums[i]; //实际上可变参数是一个一维数组
    }
    return sum;
    }
    //如果是以前的做法
    public static int sum2(int[]nums){
    int sum=0;
    for(int i=0;i<nums.length;i++){
    sum+=nums[i]; //实际上可变参数是一个一维数组
    }
    return sum;
    }
    //声明一个方法,功能:可以求1-n个整数的最大值
    //int num1 就是非可变参数部分
    //int... nums是可变参数
    public static int max(int num1,int...nums){
    int max=num1;
    for(int i=0;i<nums.length;i++){
    if(nums[i]>max){
    max=nums[i];
    }
    }
    return max;
    }
    }代码截图

     错误示例的运行效果(看我代码里面写了,错误示例)

     --------什么叫做方法签名---------------------------

    方法 = 方法签名/方法头 + 方法体

    方法签名:【修饰符】 返回值类型 方法名(【形参列表】)
    方法体:{}

    -------------------- 练习:声明一个数学工具类,包含如下方法-------------------------------

    /*
    (1)可以求0~n字符串的拼接结果
    (2)可以求1~n整数的乘积

    */

    -----------成员变量和局部变量--------------------------------------------

    /*
    变量的分类:
    1、成员变量:今天讨论的都是非静态的成员变量
    2、局部变量
    
    (1)声明的位置不同
    成员变量:
    	类中方法外
    	类{
    		【修饰符】 数据类型  成员变量;
    	}
    局部变量
    	方法中:(1)形参,也是局部变量(2)方法体{}中声明的变量
    	后面可能还要加上代码块中。
    	类{
    		【修饰符】 返回值类型  方法名(【形参列表】){
    			数据类型  局部变量;
    		}
    	}
    (2)运行时在内存中的位置也不相同
    成员变量:堆
    局部变量:栈
    (3)初始化不同
    成员变量:
    	如果没有初始化,有默认值
    局部变量:
    	如果没有初始化,就会报错,不能用
    
    (4)生命周期
    成员变量:
    	随着对象的创建而分配,随着对象被垃圾回收器回收而结束
    局部变量:
    	方法被调用,开始分配,方法执行结束就结束
    
    (5)可用的修饰符
    成员变量:有很多修饰符,具体哪些后面再讲
    局部变量:唯一的一个就是final,具体什么意思再讲
    */
    class Test07_Variable{
    	public static void main(String[] args){//args是局部变量
    		String ming = "张三";//ming局部变量
    		int nian = 23;//nian局部变量
    		
    		Student s1 = new Student();//s1局部变量
    		s1.name = ming;//s1.name不是在这里声明的,只是使用它
    		s1.age = nian;
    	}
    }
    class Student{
    	String name;//name是成员变量
    	int age;//age是成员变量
    	
    	void set(String n, int a){//n和a是局部变量
    		name = n;
    		age = a;
    	}
    }

      

     -------数组对象----------------------

    /*
    数组是用来存一组数,这组数可以是基本数据类型,也可以是引用数据类型
    例如:
    int[] arr; 存了一组整数
    char[] arr;存了一组单字符

    String[] arr; 存了一组字符串对象
    Student[] arr; 存了一组学生对象
    Circle[] arr; 存了一组圆对象

    当我们数组中存储了一组对象时,那么我们称为对象数组。
    */

     1 class test08_9ObjectArray数组对象{
     2     public static void main(String[]args){//args是局部变量
     3         //要用一个数组,存储5个圆对象,半径分别为1-5
     4         //(1)声明一个数组
     5         //数组的元素的类型是Circle
     6         Circle [] arr=new Circle[5];    //这new是创建数组对象
     7         
     8         //(2)为数组元素赋值
     9         for(int i=0;i<arr.length;i++){
    10             //元素:数组名[下标]
    11             //arr[i].radius=i+1;
    12             arr[i]=new Circle();     //创建圆对象
    13             arr[i].radius=1+i;
    14             
    15         }
    16         //(3)、遍历数组
    17         for(int i=0;i<arr.length;i++){
    18             //现在的数组的元素arr[i]就是一个圆对象,既然是圆对象,就可以调用圆的属性和方法
    19             arr[i].printInfo();
    20             
    21         }
    22     }
    23 }
    24 class Circle{
    25     double radius;
    26     double getArea(){
    27         return 3.14*radius*radius;
    28     }
    29     void printInfo(){
    30         System.out.println("半径"+radius+",面积:"+getArea());
    31     }
    32 }

     

    ---数组对象练习---------------------------------------------------------

    /*
    练习2
    (1)声明一个学生类Student,包含姓名name和成绩score属性
    (2)在测试类TestStudentArray中创建一个长度为3的学生数组
    (3)从键盘输入为学生对象的姓名和成绩属性赋值
    (4)遍历显示学生信息
    (5)使用冒泡排序对数组按照学生成绩从低到高排序
    (6)再次遍历显示学生信息
    */

     1 class test08_10数组对象实例{
     2     public static void main(String[]args){//args是局部变量
     3         //(2)在测试类TestStudentArray中创建一个长度为3的学生数组
     4         Student[] all=new Student[3];
     5         //(3)从键盘输入为学生对象的姓名和成绩属性赋值
     6         java.util.Scanner input=new java.util.Scanner(System.in);
     7         for(int i=0;i<all.length;i++){
     8             System.out.println("请输入第"+(i+1)+"个学生的信息:");
     9             
    10             //创建这个学生对象
    11             all[i]=new Student();
    12             System.out.print("姓名:");
    13             all[i].name=input.next();
    14             
    15             System.out.print("成绩:");
    16             all[i].score=input.nextInt();
    17         }
    18         //(4)遍历显示学生信息
    19         System.out.println("-------遍历如下-------------");
    20         for(int i=0;i<all.length;i++){
    21             System.out.print(all[i].name+":");
    22             System.out.println(all[i].score);
    23         }
    24         //(5)使用冒泡排序对数组按照学生成绩从低到高排序
    25         for(int i=0;i<all.length;i++){
    26             for(int j=0;j<all.length-1;j++){
    27                 if(all[j].score<all[j+1].score){
    28                     //如果第1个小于第2个就不替换,否则就替换他们
    29                     
    30                 }else{
    31                     Student temp=new Student();
    32                     temp=all[j];
    33                     all[j]=all[j+1];
    34                     all[j+1]=temp;
    35                 }
    36             }
    37         }
    38         System.out.println("-------从低到高排序后遍历如下-------------");
    39         for(int i=0;i<all.length;i++){
    40             System.out.print(all[i].name+":");
    41             System.out.println(all[i].score);
    42         }
    43     }
    44 }
    45 //(1)声明一个学生类Student,包含姓名name和成绩score属性
    46 class Student{
    47     String name;
    48     int score;
    49     void printInfo(){
    50         System.out.println("姓名:" + name + ",成绩:" + score);
    51     }
    52     String getInfo(){
    53         return "姓名:"+name+",成绩:"+score;
    54     }
    55 }

    ----------面向对象的基本特征之一 封装-------------------------------------

    面向对象的基本特征:
    (1)封装
    (2)继承
    (3)多态

    一、封装

    1、封装的意义:
    (1)隐藏实现细节
    (2)安全

    2、封装的类型:
    (1)属性的封装、方法的封装等
    (2)组件的封装
    (3)系统的封装

    3、封装的实现,靠权限修饰符来控制可见的范围。
    权限修饰符:
    (1)可见范围
    本类 本包 其他包子类 任意位置
    private: √ × × ×
    缺省/省略: √ √ × ×
    protected: √ √ √ ×
    public √ √ √ √

    (2)哪些可以加权限修饰符
    类、属性、方法、构造器、内部类

    (3)分别可以加什么权限修饰符
    类:缺省或public
    如果类前面有public,那么必须与源文件名相同
    属性:四种都可以
    方法:四种都可以

    4、属性的封装
    大多数情况下,属性都是private
    如果属性私有化了,我们会提供get/set方法
    get/set的标准写法:
    public void set属性名(数据类型 形参名){
    属性名 = 形参名;
    }
    public 属性的数据类型 get属性名(){
    return 属性名;
    }

    5、方法的封装
    大多数情况下,方法都是public

    */

     

    class test08_11Encapsulation封面向对象的基本特征_封装{
        public static void main(String[]args){
            //1、创建对象
            Circle c1=new Circle();
            //2、为属性赋值
            //c1.radius=1.2;//这种方式是错误的
            c1.setRadius(2);
            
            System.out.println("半径:"+c1.getRadius());
        }
    }
    class Circle{
        private double radius;    //仅限与本类中访问
        
        //radius属性的set方法,用于在其它类中修改radius的值
        public void setRadius(double r){
            if(r > 0){//使得赋值可控
                radius=r;
            }
        }
        //radius 属性的get方法,用于在其它类中获取radius的值
        public double getRadius(){
            return radius;
        }
    }

    练习:

    /*
    1、声明学生类,
    (1)有属性:姓名,年龄,成绩,并且私有化,
    (2)提供公共的get/set。
    (3)提供getInfo()方法,返回学生对象的信息
    2、在测试中用set方法赋值,用getInfo()返回学生信息
    */

     1 class test08_12getset封装练习{
     2     public static void main(String[]args){
     3         Studnet stu=new Studnet();
     4         stu.setName("张三丰");
     5         stu.setAge(80);
     6         stu.setScore(100);
     7         
     8         System.out.println(stu.getInfo());
     9     }
    10 }
    11 
    12 class Studnet{
    13     private String name;
    14     private int age;
    15     private double score;
    16     //提供公共的get/set。
    17     public String getName(){
    18         return name;
    19     }
    20     public void setName(String n){
    21         if(n!=""){
    22             name=n;
    23         }
    24     }
    25     
    26     public void setAge(int a){
    27         age = a;
    28     }
    29     public int getAge(){
    30         return age;
    31     }
    32 
    33     public void setScore(double s){
    34         score = s;
    35     }
    36     public double getScore(){
    37         return score;
    38     }
    39      
    40      public String getInfo(){
    41          return "姓名:"+name+"; 年龄"+age+";成绩:"+score;
    42      }
    43 }

    ------------------------构造器---------------------------------------------------------------

    构造器就是C#中的构造方法(想一想是不是)

    /*
    类的第三个组成部分:
    构造器,也称为构造方法,因为(1)它长的像方法(2)它编译后是一个实例初始化方法

    1、构造器的作用
    (1)构造对象,创建对象
    和new一起使用,每次调用它就是在创建新的对象
    (2)可以在创建对象的同时,给属性赋值

    2、构造器的特点
    (1)所有类都有构造器
    (2)如果一个类没有显式声明构造器,那么编译器将会自动生成一个默认的无参构造
    (3)如果一个类显式声明了构造器,那么编译器将不会自动生成默认的无参构造了
    (4)构造器的名称必须与类名相同
    (5)构造器没有返回值类型,也不写void
    (6)构造器可以重载

    重载:在同一个类中,方法名相同,形参列表不同的两个和多个方法,和返回值类型无关

    3、构造器的语法结构
    【修饰符】 类名(){

    }
    【修饰符】 类名(形参列表){

    }

    回忆:
    java.util.Scanner input = new java.util.Scanner(System.in);//调用的是有参构造
    int num = input.nextInt();//从键盘输入一个整数
    java.util.Random rand = new java.util.Random();//调用的是无参构造
    int num = random.nextInt(10);//产生一个[0,10)的整数
    */

     1 class test08_13Constructor构造器{
     2     public static void main(String[]args){
     3         //创建对象 
     4         //类名 对象名 =new 类名();
     5         Circle c=new Circle();
     6         Circle cc=new Circle(1.2);//调用的是有参构造函数  1.2给半径赋值,在创建对象的时候同时给属性赋值了
     7         
     8         cc.setRadius(2.5);//创建对象之后,修改属性值用的
     9         cc.printInfo();
    10         
    11         Circle c2=new Circle();//先创建对象,不给半径赋值
    12         c2.setRadius(3.6);
    13         c2.printInfo();
    14     }
    15 }
    16 class Circle{
    17     private double radius;
    18     //double r:构造器的形参列表
    19     public Circle(double r){//有参构造
    20         radius=r;//给班级赋值
    21     }
    22     
    23     public Circle(){//无参构造函数
    24         
    25     }
    26     
    27     public void printInfo(){
    28         System.out.println("半径:"+radius);
    29     }
    30     
    31     public void setRadius(double r){
    32         radius=r;
    33     }
    34 }

    我们习惯上:
    类{
    属性列表;

    构造器列表;

    方法列表;
    }
    */

     

    ----------注意点-:有参构造器里面赋值操作不能漏掉-----------------

    看下面这段构造器代码

     1 /*
     2 1、声明学生类,
     3 (1)有属性:姓名,年龄,成绩,并且私有化,
     4 (2)提供有参和无参构造
     5 (3)提供公共的get/set。
     6 (4)提供getInfo()方法,返回学生对象的信息
     7 2、在测试中
     8 (1)用有参和无参构造分别创建对象
     9 (2)用set方法修改属性值
    10 (3)用getInfo()返回学生信息
    11 
    12 习惯上:
    13 类{
    14     属性列表;
    15     
    16     构造器列表;
    17     
    18     方法列表;
    19 }
    20 */
    21 class test08_14Exer5构造器练习{
    22     public static void main(String[]args){
    23         //1、无参构造函数创建对象
    24         Student s1=new Student();
    25         //s1.setName="张三";//错误的
    26         s1.setName("张三");
    27         //s1.name="111";//也是错误的,因为private是私有的,访问不到
    28         s1.setAge(23);
    29         s1.setScore(89);
    30         System.out.println(s1.getInfo());
    31         
    32         //2、有参数构造函数创建对象
    33         Student s2=new Student("李四",24,80);////相对来说有参有时候好像还方便一些
    34         System.out.println(s2.getInfo());
    35         s2.setScore(74);//修改成绩的值
    36         System.out.println(s2.getInfo());
    37     }
    38 }
    39 class Student{
    40     private String name;
    41     private int age;
    42     private double score;
    43     
    44     //创建无参和有参的构造函数
    45     public Student(){
    46         
    47     }
    48     
    49     public Student(String n,int a,double s){    //特别注意这里,
    50         name=n;                                    //有参构造函数(有参构造器)里面要赋值操作
    51         age=a;
    52         score=s;
    53     }
    54     
    55     //提供公共的get/set。
    56     public String getName(){
    57         return name;
    58     }
    59     public void setName( String s){
    60         name=s;
    61     }
    62     
    63     public int getAge(){
    64         return age;
    65     }
    66     public void setAge( int a){
    67         age=a;
    68     }
    69     
    70     public double getScore(){
    71         return score;
    72     }
    73     public void setScore( double s){
    74         score=s;
    75     }
    76     
    77     public String getInfo(){
    78         return "姓名:" + name + ",年龄:" + age +",成绩:" +score;
    79     }
    80 }

  • 相关阅读:
    分布式
    pytest+allure+jenkins
    Pytest-参数化和unittest-ddt的对比(两种数据驱动的对比)
    pytest- fixture个人理解总结
    os路径拼接时,比如os.path.join(base_dir,"Outputslogs")后半段斜杠请小心被识别为转义字符,所以请用/,因为windows都能识别到此路径。
    python中如何获取当前时间,并计算时间差
    Web UI自动化测试-滚动条操作
    java 基础 1.什么是Java?2.Java语言的特点?
    java 排序3 插入排序
    java 排序2 冒泡排序
  • 原文地址:https://www.cnblogs.com/liliang07/p/13358478.html
Copyright © 2011-2022 走看看