写点什么

JAVA 面向对象 (七)-- 类的属性和方法详讲

用户头像
加百利
关注
发布于: 2 小时前

引言:上节课通过 java 对象的创建和使用学习,我们知道类的组成为属性和方法,那么这两者具体使用是如何的呢?本次课程我们就类的属性和方法进行详细介绍。


类的组成由属性和方法组成,属性可以称为成员变量,方法可以称为成员函数。


创建对象的过程称之为实例化。当一个对象被创建后,包含三个方面的特性:对象句柄,属性,方法,句柄用于区分不同的对象,对象的属性和方法与类中的成员变量和成员函数对应。


在类里面的属性和方法叫做成员变量和成员函数,在实例化后,调用这些变量和函数,就叫做对象属性和对象方法。

一、成员变量和局部变量:

在实际使用中,我们知道变量可以定义在类中的不同位置而有不同的作用,一般根据变量定义位置我们可以将其分为成员变量和局部变量。

1.成员变量:

直接在类中定义的变量我们成为成员变量,成员变量可以在类中的所有方法中调用,如下代码:


package cn.hz;
/** * @author hz * @version 1.0 */public class Demo1 { public String name; //定义成员变量 public void method1(){ System.out.println(name); } public void method2(){ System.out.println(name); }}
复制代码


name 属性为成员变量,可以在 method1 和 method2 中使用;

2.局部变量:

顾名思义,局部变量指定义在方法体中的变量,局部变量只能在定义的方法体中调用,如下代码:


package cn.hz;
/** * @author hz * @version 1.0 */public class Demo1 { public void method1(){ String name="zs"; System.out.println(name); //可以调用name变量 } public void method2(){ System.out.println(name); //错误:直接无法通过编译,name为局部变量,该方法不能调用 }}
复制代码


name 为 method1()的局部变量,只能在 method1()中使用

3.成员变量和局部变量对比:

  • 作用域不同:

  • 局部变量的作用域仅限于定义它的方法

  • 成员变量的作用域在整个类内部都是可见的

  • 初始值不同:

  • Java 会给成员变量一个初始值:int 初始值为 0;double 初始值为 0.0;boolean 值为 false 等

  • Java 不会给局部变量赋予初始值,所以我们在定义局部变量时一定要赋值,否则编译错误。

  • 在同一个方法中,不允许有同名局部变量;在不同的方法中,可以有同名局部变量

  • 两类变量同名时,局部变量具有更高的优先级

4.成员变量与局部变量使用注意事项:

案例一:


package cn.hz;
/** * @author hz * @version 1.0 */public class Demo1 { public String name; //定义全局变量; public void method1(){ String name="zs"; //定义局部变量 System.out.println(name); //可以调用name变量 } public void method2(){ String name="zs"; //定义局部变量 System.out.println(name); //可以调用name变量 }
}
复制代码


结果: 编译运行均没有错误,打印结果都为"zs";


分析:


  • 局部变量可以同全局变量同名,使用时为局部变量,同时存在时,如何使用全局变量呢?(后面章节 this 关键字)

  • 两个不同的方法的局部变量可以同名,使用时互不影响,但是在同一个方法中的局部变量不能同名;

二、类的方法:

1.方法定义:

<权限修饰符> 返回值类型 方法名(<参数列表>){    方法体    <return 返回值>}
复制代码

权限修饰符:public 指定类与类之间的调用范围,可省略

返回值类型:指定返回值的具体数据类型,void 为无返回值的返回值类型

方法名:指定当前方法的名称,用于后期调用,严格按照命名规则

参数列表: 参数个数和类型,可省略

return :如果有返回值,表示指定返回值,return 只能出现在该方法体的最后一句

如:在学生类中定义一个学习的方法:

public class{    public void study(){         System.out.println("好好学习");    }}
复制代码

返回值和参数列表根据实际情况确定是否存在。

2.方法的调用:

方法之间允许相互调用,不需要知道方法的具体实现,只知道方法调用方式,从而实现重用,提高效率,而方法在类中调用和类外调用又不同:

同一个类中调用方法:

public void a(){    b();}
复制代码

如在学生类中考试方法需要调用学习方法,代码如下

package cn.hz;/** * 定义学生的类 * @author hz * @version 1.0 */public class Student {    //属性省略...        //学生学习方法   public void study(){       System.out.println("好好学习");   }   //学生考试方法   public void exam(){       //调用学习方法       study();   }}
复制代码

当前类调用其他类的方法:

需要先将其他调用类的对象创建以后才能进行调用:

public void a(){    B b=new B();    b.b();}
复制代码

如在老师的类需要调用学生的考试方法,代码如下

//学生类同上,省略...package cn.hz;/** * 定义学生的类 * @author hz * @version 1.0 */public class Student {    //属性省略...        //学生学习方法   public void study(){       System.out.println("好好学习");   }   //学生考试方法   public void exam(){       //调用学习方法       study();   }}
复制代码

3.方法的参数:

在很多场合,需要执行相似操作,将相似操作作为一个方法编写,不同的内容作为参数传入执行,从而达到一个方法体输出不同结果

定义:

<权限修饰符> 返回值类型   方法名 (<形式参数列表>){    方法体}
复制代码

调用:

方法名(实参列表)
复制代码

形参:方法的参数列表没有实际值

实参:在调用执行该方法的时候传入的参数才有实际值

注意事项:

  • 在调用方法的时候实参列表要一一对应(变量可以不一样,但是数据类型必须一致,一般开发中形参与实参名相同)。

  • 调用方法参数列表的顺序也一定要对应(后面章节方法重载具体讲解)

4.方法的具体使用演示:

首先我们举个例子来说明方法的使用场景,比如现在我们用某同学去吃饭这么一件事来模拟,可能会有几种情况:

情景一:

某同学直接去食堂吃饭,不需要带东西去,也不需要带东西回来,所以我们可以写基本方法没有返回值,也没有参数,如方法 eat1();

//直接吃饭,不需要带东西去,也不需要带东西回来public void eat1(){    System.out.println("执行吃饭");}
复制代码

情景二:

某同学直接食堂去吃饭,但是不想用食堂的餐具,所以自己带了餐具,那么作为方法来说,需要有参数传入以供方法使用,如方法 eat2();

//自己带餐具去食堂吃饭public void eat2(String tableware){    System.out.println("执行吃饭,使用自己带的餐具"+tableware);}
复制代码

情景三:

某同学直接去食堂吃饭,但是不想用食堂的餐具,所以自己带了餐具,并且吃饭还需要带钱支付,所以需要两种不同的参数传入使用,,而参数的使用在不同的场合可以根据自己需要传入不同个数和不同的类型,如方法 eat3();

//自己带餐具去食堂吃饭,并需要带钱public void eat3(String tableware,double money){    System.out.println("执行吃饭,使用自己带的餐具"+tableware+",吃饭总共花费"+money);}
复制代码

情景四:

某同学直接去食堂吃饭,朋友让帮忙带一份饭,注意该同学吃完饭需要将一份饭带回,所以定义该方法时便有返回值了,,当然返回值类型可以根据我们实际情况制定到底返回什么类型,不过注意的事一定是吃完饭再给朋友带饭回去,所有返回值 return 一定要写在方法的最后,如方法 eat4()

//吃完饭需要给朋友带一份饭回去public String  eat4(){    System.out.println("执行吃饭");    return "给朋友带的饭";}
复制代码

情景五:

如果现在需求升级,某同学直接去食堂吃饭,但是不想用食堂的餐具,所以自己带了餐具,并且吃饭还需要带钱支付,吃完饭以后需要给朋友带一份饭回家,那么对于该需求我们又该如何定义呢?首先带东西去吃饭所以有参数,吃饭需要带东西回家,所以有返回值,如方法 eat5();

//自己带餐具去食堂吃饭,并需要带钱,吃完饭再给朋友带回一份饭public String eat5(String tableware,double money){    System.out.println("执行吃饭,使用自己带的餐具"+tableware+",吃饭总共花费"+money);    return "给朋友带的饭";}
复制代码

根据以上的例子,我们可以看出方法参数和返回值并没有直接关系,至于参数和返回值是否需要就根据我们实际情况而定。

5.方法的重载:

在上述的方法具体使用过程,我们发现一个问题,对于使用比较相似的场合我们可以通过方法参数列表控制从而达到不同的效果,但是问题在于每定义一个场合我们就需要定义一个方法名,这样使我们代码过于累赘,java 提供一张机制用于解决这个问题,称为方法的重载。

定义:

在同一个类中,方法名相同,参数列表(参数个数,参数类型,类型顺序)不同都为重载,和返回值与修饰符无关;

案例分析 1:

public void  eat(){}   public void eat(String tableware){}public void eat(double money){}
复制代码

结果:以上三个方法构成重载,参数列表(参数类型)不同

案例分析 2:

public void  eat(){}   public void eat(String tableware){}public void eat(String tableware,dobule money){}
复制代码

结果:以上三个方法构成重载,参数列表(参数个数)不同

案例分析 3:

public String  eat(String tableware){}   public void eat(String tableware){}public int eat(String tableware){}
复制代码

结果:以上三个方法不构成重载,编译不通过,参数列表一样,都为一个 String 类型,重载与返回值类型无关

案例分析 4:

public void eat(String tableware,double money){}pubic void eat(String money,dobule tableware){}
复制代码

结果:以上两个方法不构成重载,参数个数和类型都相同,重载和形参名无关。

案例分析 5:

public void eat(String tableware,double money){}public String eat(dobule money,String tableware){}
复制代码

结果:以上两个方法构成重载,参数类型不同(顺序改变,类型也改变了),构成重载,和返回值类型无关

注意:

  • 方法中的参数顺序改变,参数列表也改变了,构成重载

  • 方法中的形参名改变,数据类型不改变则参数列表不改变,不构成重载

  • 方法的重载与方法的返回值和权限修饰符无关

  • 方法的重载在 java 中最多体现为构造方法

6.构造方法:

在前面我们学习属性和方法的使用时,我们发现需要先将 java 对象创建出来然后再进行赋值,比较麻烦,是否能直接在创建 java 对象的时候直接完成对象的赋值呢,答案是肯定的,java 提供了构造方法用于对象的初始化赋值。

定义:

  • 构造方法名必须与其类名称相同

  • 构造方法必须没有显式返回类型

代码如下:定义一个学生类,并添加一个构造方法

package cn.hz;/** * 定义学生的类 * @author hz * @version 1.0 */public class Student {    public String  name;  //定义属性:学生姓名    public Student(){        //执行初始化代码       }    public Student(String name){        //执行初始化内容    }}
复制代码

执行的初始化代码可以完成对象的初始化相关内容。

作用:

  • 创建对象

  • 完成使用该构造方法创建对象的初始化

代码如下:通过构造方法完成对象创建时的赋值:

定义学生类:

package cn.hz;/** * 定义学生的类 * @author hz * @version 1.0 */public class Student {    public String  name;  //定义属性:学生姓名    public String address;    public Student(){        //执行初始化代码        address="北京";    }    public Student(String name){        //执行初始化内容        address="北京";        this.name=name;     //完成外部参数传入进行初始化效果    }}
复制代码

创建学生对象,并打印信息:

package cn.hz;/** * @author hz * @version 1.0 */public class StudentTest {    public static void main(String[] args) {        //创建学生对象1        Student student1=new Student();        System.out.println("学生1信息"+student1.name+","+student1.address);        //创建学生对象2        Student student2=new Student("ls");        System.out.println("学生2信息:"+student2.name+","+student2.address);    }}
复制代码

结果显示:



学生 1 创建调用无参构造方法,该方法只完成 address 属性的初始化,学生 2 对象调用参数为 String name 的构造方法,即完成对 address 属性初始化,又在创建对象时通过参数传递到达对 name 的初始化效果.

小结:

  • 一个类中,可以有多个构造方法,多个构造方法形成方法的重载

  • 构造方法名一定同类相同,没有返回值

  • 构造方法主要完成对象创建,也可以在创建的同时完成对象的初始化,后期会同方法赋值结合使用

  • 如果一个类中没有编写构造方法,则系统会自动提供一个无参的构造方法,但是一旦编写,则系统不再提供。

总结:



`

用户头像

加百利

关注

还未添加个人签名 2021.06.08 加入

还未添加个人简介

评论

发布
暂无评论
JAVA面向对象(七)--类的属性和方法详讲