1、目标
方法的参数传递
会使用构造方法
掌握方法重载
会使用成员变量和局部变量
2、方法
2.1 如何使用带参数的方法
定义带参数的方法:
<访问修饰符> 返回类型 <方法名>(<形式参数列表>) {
//方法的主体
}
调用带参数的方法
对象名.方法名(参数1, 参数2,……,参数n)
常见错误:
调用方法时不能指定实参类型!
形参和实参数据类型不一致!数量也要一致!
2.2 方法传参
基本数据类型和引用数据类型数据在传参时的区别
基本数据类型,操作传递的是变量的值,改变一个变量的值不会影响另一个变量的值。引用数据类型(类、数组和接口),赋值是把原对象的引用(可理解为内存地址)传递给另一个引用
2.3 构造方法
为什么要叫做构造方法,是因为在对象创建的时候,需要公共构造方法去初始化值,去描述对象的那些状态,去对应对象中的字段。
声明:
访问修饰符 构造方法名 ( ) {
//初始化代码
}
//无参构造
public people() {
}
//有参构造方法
public people(String name, int age) {
this.name = name;
this.age = age;
}
作用:对象初始化
系统提供默认无参构造方法
2.3.1 无参构造方法
每个类都有个默认无参构造方法
默认构造方法:构造方法中没有参数,就说明他就是一个默认构造方法,也称为无参构造方法。
创建构造方法的规则
- 构造方法的名字必须和类名一致
- 构造方法没有返回值,返回的是一个类
- 构造方法不能是抽象的,静态的,最终的,同步的也就是说,他不能通过abstract,static,final,synchronized关键字修饰
- 由于构造方法是不能被继承的,所以final和abstract是没有意义的,而且他是用于初始化一个对象的,所以static也是没有用的,多个线程也不会同时去创建内存地址相同的对象,所以锁也是没有意义的
无参构造方法在对象被声明的时候就会默认被调用
无参构造方法的作用就是给对象里面的值进行初始化。
比如:
这里people的name,age都会给初始化。
作用:给值赋予一个默认的片段。这里就是初始化了people俩属性的值,String的默认值为null,而int类型为0。
这里不写无参构造方法也会被初始化:这是因为当我们创建对象的时候,编译器会默认生成无参构造方法,当我们手动写入构造方法后,默认生成的构造方法就不会再被使用。
2.3.2 有参构造方法
有参构造方法就是有参数的构造方法。有了参数的话就可以为不同的对象供不同的值了。
在之前我们给对象赋值时,使用的基本都是setter方法或则对象名.属性值来进行赋值,而当我们使用有参构造方法后,可以直接在对象声明的时候进行初始化。
public class Test {
public static void main(String[] args) {
people p = new people("123",123);
System.out.println(p.name + " " + p.age);
}
}
class people{
String name;
int age;
// public people() {
// System.out.println("被调用了");
// }
public people(String name, int age) {
this.name = name;
this.age = age;
System.out.println("有参构造函数被调用了");
}
}
而我们在单独使用有参构造方法时,初始化对象的时候就必须写入对应的值,否则程序会报错:
2.4 构造方法重载、
自定义构造方法
方法名相同
参数项不同
与返回值、访问修饰符无关
其实当我们定义有参构造方法的时候就是对默认构造方法进行了重载。
2.4.1 this关键字的用法
this关键字的用法:
调用属性
this.health = 100;
this.name = “大黄";
调用方法:
this.print();
调用构造方法
this();
this("小黑",123);//如果使用,必须是构造方法中的第一条语句
- 方法中的变量为局部变量,存储在栈中,作用范围是方法内;我们想通过构造器初始化的是成员变量,存储在堆中,作用范围是本类内部。
当成员变量&局部变量重名时,优先使用局部变量。关键还是看有没有局部变量,有局部变量优先使用局部变量,否则属性—就近原则!
- this其实可以理解为对象的一个属性(成员变量),但是这个属性是隐藏的.即this相当于对象的一个隐藏属性。
- 和对象的其他属性一样,在
new
一个新对象的时候,会在堆内存为对象分配空间,属性就储存在这份空间中。且该this属性的值就是对象在堆内存中地址,即this指向该对象(this代表该对象).
【重点】综上:this是对象的隐藏属性(本质就是一个普通的成员变量),和其他non-static
属性一样,在创建对象的时候会为每个新对象分配该对象的专属成员变量(this就是其中一个),this这个成员变量存储在堆内存中,该变量的值是所属对象在堆内存的地址。
- this关键字可以用来区分当前类的属性&局部变量。
- 使用this关键字可以用来访问本类的实例属性、实例方法、构造器(“实例”指的就是
non-static
修饰 的)
-
- 访问本类实例属性:
this.属性
- 访问本类实例方法:
this.方法名(参数列表)
- 访问本类构造器:
this(参数列表)
- 访问本类实例属性:
- 【注意】:
this(参数列表)
来访问本类构造器需要注意以下几点
-
- 只能在构造器中使用
this(参数列表);
即在一个构造器中访问本类的另外一个构造器。(默认构造器行首是super();
,)。 - 显示使用
this()
时,默认的super()
就被覆盖 this(参数列表)
和super(参数列表)
在构造器中有且只能存在一个。- 若在构造器中使用
this(参数列表)
,则此语句只能位于构造器第一行 - 类中的静态方法
static method
中不能使用this
。很简单理解:static方法中不能出现成员变量(this依赖对象,而static不依赖于对象,类名.静态方法
时,没有对象啊,你让this情何以堪!它都不知道自己属于哪个对象!)在【JavaSE】保姆级教程|1万字+10张图学会类与对象–建议收藏这篇博文的Part4、Part5部分关于成员方法和静态方法已经做出详细解释
- 只能在构造器中使用
class Penguin {
//省略相关属性
public void Penguin() {
health=10;
sex="雄";
System.out.println("执行构造方法");
}
public void print() {
System.out.println("企鹅的名字是" + name + ",健康值是"
+ health + ",性别是" + sex);
}
}
这段代码最后输出
原因是:方法中进行的赋值只能在方法中使用,并不能作用域其他方法,除非此时我们使用this.x
3、成员变量和局部变量
变量声明的位置决定变量作用域
变量作用域确定可在程序中按变量名访问该变量的区域
这里a就只作用在for循环中。
常见错误:
局部变量超出其作用域后不可用!
二者区别:
作用域不同:
局部变量的作用域仅限于定义它的方法
成员变量的作用域在整个类内部都是可见的(可以使用)
初始值不同:
java会给成员变量一个初始值
java不会给局部变量赋予初始值
- 一个方法中不能定义两个同名的方法局部变量
- 方法中的局部变量也不能和形参同名
- 同一个方法的不同代码块可以重名
在同一个类中,成员变量和局部变量同名时,局部变量具有更高的优先级
案例
案例一、
使用带参方法实现学员信息管理增加学员姓名在保存了多个学生姓名的数组中,指定查找区间,查找某个学生姓名并显示是否查找成功
Test
package demo1;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Student stu = new Student();
String search;
Scanner sc = new Scanner(System.in);
for (int i = 0 ;i < stu.name.length;i++){
System.out.println("请输入第"+ (i+1) + "位学生的姓名:" );
stu.name[i] = sc.next();
}
for (int i = 0 ;i < stu.name.length;i++){
System.out.println(stu.name[i]);
}
System.out.println("请输入你想要找的学生姓名:");
search = sc.next();
stu.search(search);
}
}
Student
package demo1;
public class Student {
String[] name = new String[3];
public void search(String search){
for (int i = 0;i < name.length;i++){
if (name[i].equals(search)){
System.out.println("查到了");
break;
}else{
System.out.println("没有查到");
}
}
}
}
案例二
Test
package demo2;
import demo2.Student;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Student[] stu = new Student[3];
System.out.println("请输入三名学生的成绩");
Scanner sc = new Scanner(System.in);
System.out.println(stu.length);
for (int i = 0;i<stu.length;i++){
//初始化数组元素: 数组 stu 被声明并分配了大小,但没有为它的元素分配内存(即没有创建 Student 对象)。在尝试访问 stu[i].scorce 之前,应该先实例化每个 Student 对象。修正方法:
stu[i] = new Student();
stu[i].scorce = sc.nextInt();
}
addScorce(stu);
for (int i = 0;i < stu.length;i++){
System.out.println(stu[i].scorce);
}
}
public static void addScorce(Student[] sco){
int flag = 0;
for (int i = 0;i<sco.length;i++){
if (sco[i].scorce <= 60){
flag = 1;
}
}
if (flag == 1){
for (int i = 0;i<sco.length;i++){
sco[i].scorce +=2;
}
}
}
}
Student
package demo2;
public class Student {
int scorce;
}
练习
练习一、简易计算器
实现简易计算器,分别实现两个整数、三个浮点数的加法运算
Test
package exercise01;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Cal c = new Cal();
c.num1[0] = 1;
c.num1[1] = 2;
c.num2[0] = 3;
c.num2[1] = 4;
c.num2[2] = 5;
c.addInt(c.num1);
c.addDou(c.num2);
}
}
Cal
package exercise01;
public class Cal {
int[] num1 = new int[2];
double[] num2 = new double[3];
public Cal(){
}
public Cal(int[] num1, double[] num2) {
this.num1 = num1;
this.num2 = num2;
}
public void addInt(int[] num1){
int sum = 0;
for (int i = 0;i<num1.length;i++){
sum += num1[i];
}
System.out.println(sum);
}
public void addDou(double[] num2){
int sum = 0;
for (int i = 0;i<num2.length;i++){
sum += num2[i];
}
System.out.println(sum);
}
}
作业
作业一、
1.构造方法 编写Java程序模拟简单的计算器。 定义名为Number的类其中有两个整型数据成员n1和n2应声明为私有。
编写构造方法赋予n1和n2初始值再为该类定义加addition、减subtration、乘multiplication、
除division等公有成员方法分别对两个成员变量执行加、减、乘、除的运算。
在main方法中创建Number类的对象调用各个方法并显示计算结果
Test
package homework01;
public class Test {
//1.构造方法 编写Java程序模拟简单的计算器。 定义名为Number的类其中有两个整型数据成员n1和n2应声明为私有。
//编写构造方法赋予n1和n2初始值再为该类定义加addition、减subtration、乘multiplication、
//除division等公有成员方法分别对两个成员变量执行加、减、乘、除的运算。
//在main方法中创建Number类的对象调用各个方法并显示计算结果
public static void main(String[] args) {
Number n = new Number();
n.setN1(3);
n.setN2(4);
n.addition();
n.subtration();
n.multiplication();
n.division();
}
}
Number
package homework01;
public class Number {
private int n1;
private int n2;
public Number(){}
public Number(int n1, int n2) {
this.n1 = n1;
this.n2 = n2;
}
public int getN1() {
return n1;
}
public void setN1(int n1) {
this.n1 = n1;
}
public int getN2() {
return n2;
}
public void setN2(int n2) {
this.n2 = n2;
}
public void addition(){
System.out.println(n1 + "+" + n2 + "=" + (n1+n2));
}
public void subtration(){
System.out.println(n1 + "-" + n2 + "=" + (n1-n2));
}
public void multiplication(){
System.out.println(n1 + "x" + n2 + "=" + (n1*n2));
}
public void division(){
if (n2 != 0){
System.out.println(n1 + "/" + n2 + "=" + (n1/n2));
}else{
System.out.println("分母不能为0");
}
}
}
作业二、
2. 编写Java程序用于显示人的姓名和年龄。 定义一个人类Person该类中应该有两个私有属性姓名name和年龄age。
定义构造方法用来初始化数据成员。再定义显示display方法将姓名和年龄打印出来。
在main方法中创建人类的实例然后将信息显示
Test
package homework02;
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.setName("张三");
p.setAge(13);
p.display();
}
}
Person
package homework02;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void display(){
System.out.println("名字:" + name + ",年龄:" + age);
}
}
作业三
3.构造方法与重载 为“无名的粉”写一个类class WuMingFen 要求:
1.有三个属性 面码:String theMa 粉的分量(两) int quantity 是否带汤 boolean likeSoup
2.写一个构造方法 以便于简化初始化过程 如 WuMingFen f1 = new WuMingFen(“牛肉”,3,true);
3.重载构造方法 使得初始化过程可以多样化 WuMingFen f2 = new WuMingFen(“牛肉”,2);
4.如何使得下列语句构造出来的粉对象是酸辣面码、2两、带汤的 WuMingFen f3 = new WuMingFen();
5.写一个普通方法 check() 用于查看粉是否符合要求。即 将对象的三个属性打印在控制台上
Test
package homework03;
public class Test {
public static void main(String[] args) {
WuMingFen wu1 = new WuMingFen("牛肉", 3,true);
WuMingFen wu2 = new WuMingFen("牛肉", 3);
WuMingFen wu3 = new WuMingFen("酸汤面吗", 2,true);
wu1.check();
wu2.check();
wu3.check();
}
}
WuMingFen
package homework03;
public class WuMingFen {
private String theMa; //面码
private int quantity; //分量
private boolean likeSoup; //是否带汤
public WuMingFen(String theMa, int quantity, boolean likeSoup) {
this.theMa = theMa;
this.quantity = quantity;
this.likeSoup = likeSoup;
}
public WuMingFen(String theMa, int quantity) {
this.theMa = theMa;
this.quantity = quantity;
}
public String getTheMa() {
return theMa;
}
public void setTheMa(String theMa) {
this.theMa = theMa;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public boolean isLikeSoup() {
return likeSoup;
}
public void setLikeSoup(boolean likeSoup) {
this.likeSoup = likeSoup;
}
public void check(){
System.out.println(" " + theMa + "," + quantity + ", " + likeSoup);
}
}
作业四、
4.定义一个网络用户类 要处理的信息有用户ID、用户密码、email地址。
在建立类的实例时 把以上三个信息都作为构造函数的参数输入 其中用户ID和用户密码时必须的
缺省的email地址是用户ID加上字符串”
Test
package homework04;
public class Test {
// 4.定义一个网络用户类 要处理的信息有用户ID、用户密码、email地址。
//在建立类的实例时 把以上三个信息都作为构造函数的参数输入 其中用户ID和用户密码时必须的
//缺省的email地址是用户ID加上字符串”
public static void main(String[] args) {
User u = new User(10001,"123456");
u.setEmail(u.getId()+"@qq.com");
System.out.println("ID:" + u.getId() + ",密码:" + u.getPwd() + ",email:" + u.getEmail());
}
}
User
package homework04;
public class User {
private int id;
private String pwd;
private String email;
public User(int id, String pwd, String email) {
this.id = id;
this.pwd = pwd;
this.email = email;
}
public User(int id, String pwd) {
this.id = id;
this.pwd = pwd;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}