文章目录
成员变量与局部变量
成员变量与局部变量的区别
1. 访问方式不同
- 位置不同
- 成员变量在方法外部,直接写在类中
- 局部变量在方法的内部
2. 作用范围不同
- 成员变量的作用域在类中,整个类全部都可以使用
- 局部变量的作用域在方法中,出了方法就不能再用
3. 默认值不同
- 成员变量有默认值
- 局部变量没有默认值,必须要赋值过后才能使用
4. 内存的位置不一样(了解)
- 成员变量位于内存堆当中
- 局部变量位于内存栈当中
5. 生命周期不一样(了解)
- 成员变量:随着对象的创建而诞生,随着对象被垃圾回收机制回收而消失(会被gc机制处理)
- 局部变量:随着方法的出栈而消失
public class Test_V {
int num;
public static void main(String[] args) {
Test_V t = new Test_V();
System.out.println(t.num);
int num2 = 0;
System.out.println(num2);
}
}
private、setter/getter方法
面向对象三大特征:封装、继承、多态。
封装性在Java当中的体现:
- 方法就是一种封装
- 关键字private也是一种封装
封装就是将一些细节信息隐藏起来,对于外界不可见。
/*
问题描述:定义Person的年龄时,无法阻止不合理的数值被设置进来。
解决方案:用private关键字将需要保护的成员变量进行修饰。
一旦使用了private进行修饰,那么本类当中仍然可以随意访问。
但是!出了本类就不能再直接访问了!!!
间接访问private成员变量,就是通过一对儿getter/setter方法
必须叫setXxx或者是getXxx命名规则。
对于Getter来说,没有参数,返回值和成员变量对应;
对于Setter来说,没有返回值,参数和成员变量对应。
*/
/*
对于基本类型当中的boolean值,Getter方法最好要写成___Xxx的形式,而setXxx规则不变(命名规范)。
*/
this关键字
/*
当方法的局部变量和类的成员变量重名的时候,根据“就近原则”,优先使用局部变量。
如果需要访问本类当中的成员变量,需要使用格式:
this.成员变量名
“通过谁调用的方法,谁就是this。”
*/
public class Person {
String name;
public void sayHello(String name) {
//this指向调用方法的对象,存储的是地址值
System.out.println(name + ",你好。我是" + this.name);
System.out.println(this);
}
}
构造方法
/*
构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。
格式:
public 类名称(参数类型 参数名称...) {
方法体
}
public Student() {
super();
}
注意事项:
1. 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
2. 构造方法不要写返回值类型,连void都不写
3. 构造方法不能return一个具体的返回值
4. 如果没有编写任何构造方法,那么编译器将会默认赠送一个空的构造方法(没有参数、没有方法体)。
public Student() {}
5. 一旦编写了至少一个构造方法,那么编译器将不再赠送。
6. 构造方法也是可以进行重载的。
重载:方法名称相同,参数列表不同。
*/
标准类JavaBean
一个标准的类通常要拥有下面四个组成部分:
- 所有的成员变量都要使用private关键字修饰
- 为每一个成员变量编写一对儿Getter/Setter方法
- 编写一个无参数的构造方法
- 编写一个全参数的构造方法
这样标准的类也叫做Java Bean
public class Student {
private String name; // 姓名
private int age; // 年龄
public Student() {
}
public Student(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;
}
}
Scanner类
Scanner类的功能:可以实现键盘输入数据,到程序当中。
引用类型的一般使用步骤:
-
导包(eclipse可以自动导包)
import 包路径.类名称;
如果需要使用的目标类,和当前类位于同一个包下,则可以省略导包语句不写。
只有java.lang包下的内容不需要导包,其他的包都需要import语句。 -
创建
类名称 对象名 = new 类名称(); -
使用
对象名.成员方法名()
获取键盘输入的一个int数字:sc.nextInt();
获取键盘输入的一个字符串:sc.next();
*/
public class Demo01Scanner {
public static void main(String[] args) {
// 2. 创建
// 备注:System.in代表从键盘进行输入
Scanner sc = new Scanner(System.in);
// 3. 获取键盘输入的int数字
int num = sc.nextInt();
System.out.println("输入的int数字是:" + num);
// 4. 获取键盘输入的字符串
String str = sc.next();
System.out.println("输入的字符串是:" + str);
}
}
练习题目:
键盘输入两个int数字,并且求出和值。
思路:
- 既然需要键盘输入,那么就用Scanner
- Scanner的三个步骤:导包、创建、使用
- 需要的是两个数字,所以要调用两次nextInt方法
- 得到了两个数字,就需要加在一起。
- 将结果打印输出。
public class Demo02ScannerSum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数字:");
int a = sc.nextInt();
System.out.println("请输入第二个数字:");
int b = sc.nextInt();
int result = a + b;
System.out.println("结果是:" + result);
}
}
匿名对象
创建对象的标准格式:
类名称 对象名 = new 类名称();
匿名对象就是只有右边的对象,没有左边的名字和赋值运算符。
new 类名称();
注意事项:
匿名对象只能使用唯一的一次,下次再用不得不再创建一个新对象。
使用建议:如果确定有一个对象只需要使用唯一的一次,就可以用匿名对象。
public class Demo01Anonymous {
public static void main(String[] args) {
// 左边的one就是对象的名字
Person one = new Person();
one.name = "高圆圆";
one.showName(); // 我叫高圆圆
System.out.println("===============");
// 匿名对象
new Person().name = "赵又廷";
new Person().showName(); //
one.pt();
new Person().pt();
}
}
public static void main(String[] args) {
// 普通使用方式
// Scanner sc = new Scanner(System.in);
// int num = sc.nextInt();
// 匿名对象的方式
// int num2 = new Scanner(System.in).nextInt();
// System.out.println("输入的是:" + num);
// 使用一般写法传入参数
// Scanner sc = new Scanner(System.in);
// methodParam(sc);
// 使用匿名对象来进行传参
// methodParam(new Scanner(System.in));
Scanner sc = methodReturn();
int num = sc.nextInt();
System.out.println("输入的是:" + num);
}
// public static void methodParam(Scanner sc) {
// int num = sc.nextInt();
// System.out.println("输入的是:" + num);
// }
public static Scanner methodReturn() {
//Scanner对象作为返回值
// Scanner sc = new Scanner(System.in);
// return sc;
return new Scanner(System.in);
}
Random类
Random类用来生成随机数字。使用起来也是三个步骤:
-
导包
import java.util.Random; -
创建
Random r = new Random(); // 小括号当中留空即可 -
使用
获取一个随机的int数字(范围是int所有范围,有正负两种):int num = r.nextInt()
获取一个随机的int数字(参数代表了范围,左闭右开区间):int num = r.nextInt(3)
实际上代表的含义是:[0,3),也就是0~2
public class Demo01Random {
public static void main(String[] args) {
Random r = new Random();
int num = r.nextInt();
System.out.println("随机数是:" + num);
}
public static void main(String[] args) {
Random r = new Random();
for (int i = 0; i < 100; i++) {
int num = r.nextInt(10); // 范围实际上是0~9
System.out.println(num);
}
}
}
猜数字小游戏
练习题目:
用代码模拟猜数字的小游戏。
思路:
- 首先需要产生一个随机数字,并且一旦产生不再变化。用Random的nextInt方法
- 需要键盘输入,所以用到了Scanner
- 获取键盘输入的数字,用Scanner当中的nextInt方法
- 已经得到了两个数字,判断(if)一下:
如果太大了,提示太大,并且重试;
如果太小了,提示太小,并且重试;
如果猜中了,游戏结束。 - 重试就是再来一次,循环次数不确定,用while(true)。
public class Demo04RandomGame {
public static void main(String[] args) {
Random r = new Random();
int randomNum = r.nextInt(100) + 1; // [1,100]
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入你猜测的数字:");
int guessNum = sc.nextInt(); // 键盘输入猜测的数字
if (guessNum > randomNum) {
System.out.println("太大了,请重试。");
} else if (guessNum < randomNum) {
System.out.println("太小了,请重试。");
} else {
System.out.println("恭喜你,猜中啦!");
break; // 如果猜中,不再重试
}
}
System.out.println("游戏结束。");
}
}
相关练习
-
定义一个方法,实现根据参数决定生成随机数的范围并生成一个随机数返回,如参数为20,则随机数的范围为【1-20】
-
定义一个方法,实现随机生成一个13~19的数并返回
-
定义一个方法,实现从键盘输入5个数,并按照降序排列,并使用匿名对象调用。
-
看参考中的.md文件,了解局部变量,成员变量,类变量的区别
- 定义一个方法,实现根据参数决定生成随机数的范围并生成一个随机数返回,如参数为20,则随机数的范围为【1-20】
package com.zcl.homework.D06;
import java.util.Random;
public class q1_Method {
public int q1(int r) {
Random rand = new Random();
int i = rand.nextInt(r);
return i;
}
}
package com.zcl.homework.D06;
public class q1_Test {
public static void main(String[] args) {
System.out.println(new q1_Method().q1(20));
}
}
- 定义一个方法,实现随机生成一个13~19的数并返回
package com.zcl.homework.D06;
import java.util.Random;
public class q2_Method {
public int q2() {
Random rand = new Random();
int i = rand.nextInt(7) + 13;
return i;
}
}
package com.zcl.homework.D06;
public class q2_Test {
public static void main(String[] args) {
System.out.println(new q2_Method().q2());
}
}
- 定义一个方法,实现从键盘输入5个数,并按照降序排列,并使用匿名对象调用。
package com.zcl.homework.D06;
import java.util.Scanner;
public class q3_Method {
public void q3() {
int[] arr = new int[5];
Scanner s = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
System.out.println("请输入第"+(i+1)+"个数:");
arr[i] = s.nextInt();
}
for(int i=0;i<arr.length-1;i++){//冒泡趟数
for(int j=0;j<arr.length-i-1;j++){
if(arr[j+1]>arr[j]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(int result : arr) {
System.out.print(result + " ");
}
}
}
package com.zcl.homework.D06;
public class q3_Test {
public static void main(String[] args) {
new q3_Method().q3();
}
}
- 看参考中的.md文件,了解局部变量,成员变量,类变量的区别
成员变量:定义在类中,方法体之外。变量在创建对象时实例化。成员变量可被类中的方法、构造方法以及特定类的语句块访问。
public class ClassName{
int a;
public void printNumber(){
// 其他代码
}
}
类变量:定义在类中,方法体之外,但必须要有 static 来声明变量类型。静态成员属于整个类,可通过对象名或类名来调用。
public class ClassName{
static int a;
public void printNumber(){
// 其他代码
}
}
局部变量:在方法、构造方法、语句块中定义的变量。其声明和初始化在方法中实现,在方法结束后自动销毁
public class ClassName{
public void printNumber(){
int a;
}
// 其他代码
}
成员变量和类变量的区别:
1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
特点:
1、想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。
2、被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。
3、静态随着类的加载而加载。而且优先于对象存在。
弊端:
1、有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。
也就是可以理解为静态表现出来的就是数据的共享!!!
2、静态方法只能访问静态成员,不可以访问非静态成员。
因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
3、静态方法中不能使用this,super关键字。
因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。
什么时候定义静态成员呢?或者说:定义成员时,到底需不需要被静态修饰呢?
成员分两种:
1、成员变量。(数据共享时静态化)
该成员变量的数据是否是所有对象都一样:
如果是,那么该变量需要被静态修饰,因为是共享的数据。
如果不是,那么就说这是对象的特有数据,要存储到对象中。
2、成员函数。(方法中没有调用特有数据时就定义成静态)
如果判断成员函数是否需要被静态修饰呢?
只要参考,该函数内是否访问了对象中的特有数据:
如果有访问特有数据,那方法不能被静态修饰。
如果没有访问过特有数据,那么这个方法需要被静态修饰。