Java教程专栏:https://blog.csdn.net/qq_41806966/category_9929686.html
hello,I'm shendi
本节将会带大家认识什么是类,什么是对象,本节知识点较多.
建议零基础的花三四天学习理解本节,多练习.
目录
什么是类?
我们在之前就接触过类了,之前理解的,class就是类.
类可以理解为一个人,人有五脏六腑等各种器官(属性),以及说话,吃饭等各种动作(行为).
我们以前写的代码是这样的
public class Hello {
public static void main(String[] args) {
//这里写操作
}
}
在之前讲过,class为类,后面的为类的名字, 上面代码则为 Hello类(名称为Hello的类)
举例子 class A {} 称为类 A(就算里面什么都没有 也是一个类,就像一个柜子,里面什么都没有,但它还是一个柜子)
需要注意的是
- 类名后面紧跟花括号 花括号里面是这个类的内容.
- 我们在一个 java 文件中可以有多个类
- 例如
- public class A {} class B {}
- 我们在一个 java 文件中,只能有一个被 public 修饰的类(也就是 public class 在一个文件内只能出现一次)
- 被 public 修饰的类与文件名对应.
经过以前的学习,我们知道类里面有个 public static void main(String[] args) {}. 这个是什么呢? 类里面还能有别的东西吗?
方法(也叫函数)
方法是在类里面的,我们之前用的都是main方法(main是一个特别的方法)
方法和类不同的是,类的名称后面是花括号,并且类里可以有方法以及别的东西,而方法名称后面跟的是括号,方法里面只能写实际操作
如何定义一个方法?
语法为: 修饰符 返回类型 方法名(参数) {}
修饰符我们后面章节会讲到
以下都是方法
- void a() {} 方法 a
- void b() {} 方法 b
- public void c() {} 方法c
- public static void d() {} 方法d
我们目前用到下面这两种就可以了
- void a() {}
- public void a() {}
那么,方法有什么用呢?
我们写程序的时候(比如之前写的练习)会把代码都放到main方法里,这就造成了main方法里的代码很多很多.导致很乱,而且复用性不好.
复用性是指重复利用...
举个例子
- 我们要写一个程序,程序功能是接收用户输入的两个数字,计算最大数.
- 我们正常情况下肯定是直接在main方法里写接收,然后判断数字大小.
- 这个时候如果需求改变了,我们要在接收两个数字,并计算最大数,这个时候我们可能就要把代码复制一遍,这个时候可能有人想到使用循环就可以了,不会增加很大的代码量,但是我们如果又增加需求,增加一个计算接收的四个数字的最大值呢?这个时候使用方法就显得很明智了(轻松加愉快).
- 如果我们使用方法,则可以将计算最大数的功能提取出来,然后直接调用就可以了.(有返回值的方法)
通过代码来实践一下.
在实践之前,我们要知道方法的返回值
方法的返回值
什么是返回值?
返回值可以理解成 我吃了饭,饭给我了能量(执行了吃饭的行为,吃饭的行为返回了能量给你)
方法有两种返回值,一种是有返回,一种是无返回
无返回值的方法
我们之前使用的都是无返回值的方法.(被 void 修饰的)
例如 void a(); void b(); 等这种被 void 修饰的方法是无返回值的
无返回值的方法可以理解成,我吃了饭,饭只做了自己的事情,什么都没给我.
那么,问题来了,我们应该怎么调用方法?
方法只能在方法内被调用.
使用 方法名() 的形式来调用指定方法
通过上面的例子我们应该知道,方法的返回值修饰是放在 方法名的前面的
有返回值的方法
方法可以有返回值,想返回啥就返回啥(前提是有),所以我们必须设置方法的返回类型,这样可以限制方法返回值是什么类型的.
例如
- int a(); 这个是返回 int 类型的方法,也就是这个方法必须返回一个数字给你
- String b(); 这个方法返回的是 String 类型,返回一个字符串给你
我们该如何使用呢?
我们定义一个方法 b,这个方法返回一个字符串
String b() {}
使用关键字 return 来进行返回.
我们的方法 b 必须返回一个字符串,所以需要使用到 return 关键字
例如我们返回一个 hello world
String b() {
return "hello world";
}
我们在别的方法内可以调用这个方法来获取这个方法的返回值.例如
void a() {
String text = b();
System.out.println(text);
}
String b() {
return "hello world";
}
上面的代码就会输出 hello world
返回类型可以为基础数据类型,也可以为类型(可以为一个类,String就是一个类)
注意:
- 有返回值的方法必须返回指定类型的参数(值) 否则编译出错.
- 要在 main 里能直接使用的方法需要在方法返回值前面加 static,例如 static void a(); 后面章节会讲到static关键字
- 方法名称不能重复,否则编译出错
- 有返回值的方法必须使用 return 值 来进行返回
- 有返回值的方法在调用的时候可以不赋值,像无返回值方法那样调用
在学习了方法的返回值之后,我们可以编写之前的例子了
方法实践
在之前的文件夹内新建...(自己领会)
先创建好类和main方法
定义一个方法用于计算最大值
定义好了求最大值的方法后,我们在main里面就可以直接调用了,我们先调用输出试一下.
注: 我们的max括号里的称为参数,打个比方,参数就等于我们吃饭时候的饭(我们做吃饭动作,饭到我们嘴里)...
参数就是将指定类型的数据传给方法,让方法能直接使用或对其进行修改.
可以看出我们上面的max函数的括号内有两个参数,多个用逗号隔开,参数类型都为int类型,这个函数的功能是获取最大的那个数返回.
所以我们调用的时候应该传递两个数字,并且接收到的值为这两个数中比较大的那个值(等于当然是直接返回其中随便一个啦)
运行结果
通过上面的结果我们知道了,我们的函数是正确的(获取到了两个数中大的那个).
接下来开始实现之前说的那个功能,接收用户输入四个数字,然后获取前两次输入的最大数和后两次输入的最大数,以及四个数中最大的那个数.
代码如下
import java.util.Scanner;
public class TestFunction {
public static void main(String[] args) {
// 需要接收用户输入 当然要先创建Scanner(别忘记引入了)
Scanner sc = new Scanner(System.in);
// 接收四次输入
System.out.println("请输入四次数字");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
int num4 = sc.nextInt();
// 获取前两个数 和 后两个数的最大值(我这里直接进行输出调用了(现在不用纠结太多))
// 因为 max 函数返回的是求取我们传递的两个数中大的那个,所以我们可以直接进行输出.
// 字符串连接使用 加号(+) 以前讲过.
System.out.println("前两次最大的数:" + max(num1,num2));
System.out.println("后两次最大的数:" + max(num3,num4));
// 在完成前面两个功能后,如何获取四个数中最大的那个呢?
// 很简单,我们只需要获取前面和后面最大的数,然后在求这两个数中最大的数就可以了!
// 这里理解很容易,我们的max函数求最大值,接收两个int类型,max函数本身返回int类型.
System.out.println("四个数中最大的数:" + max(max(num1,num2),max(num3,num4)));
}
/**
* 我现在使用的是文档注释,文档注释在方法和类的上方使用(现在只做了解,后面会详细介绍).
* 下面是我们定义的方法,功能为获取 num1和num2中大的那个.
* 这个地方要加 static 是因为我们需要在main方法中使用(不要纠结为什么).
*/
static int max(int num1,int num2) {
// 这里我们要执行判断 num1和num2 谁大
// 我提供两种思路,第一种使用 if else,第二种使用之前学运算符的三元运算符
// 第一种,使用if else的,三元运算符比if else性能高(速度快),所以我把if else注释了
// 这里代码的内容是,如果 num1 大于 num2 我们就返回num1(调用的地方获取的值就为num1)
// 返回可能有点难理解,不过多动手敲代码试一试就自然懂了.
/* 多行注释
if (num1 > num2) {
return num1;
} else {
retrun num2;
}*/
// 使用三元运算符,代码量更少,并且性能更高.
// 一行代码完成判断,意思与上方的if else一致
return num1 > num2 ? num1 : num2;
}
}
运行起来,结果如下(我这里使用 javac 命令演示)
可以尝试一下,如果我们不用方法,会增加多少行代码? 可读性会变得很差.
main方法
我们将这一个方法单独讲一下,这个方法是我们使用的最多的方法.
public static void main(String[] args) {} 是固定写法,除了args可以改变,其余的变了就失去了这个方法的意义了.
因为我们的方法只有 main 方法会被调用.其余的默认不会被直接调用的.
我们的程序都是从main方法开始执行,main方法是主函数,没有main则程序运行不起来.(可以试一下,会报错)
这个方法是由 JVM(Java虚拟机) 调用的,我们知道Java是跨平台的,代码只要写一次,就可以在Windows,Linux等操作系统上跑起来.
前提是那台电脑上有 JVM(我们在安装JDK的时候其实就自带了JVM).
JVM部分是很底层的东西了,我们后面再讲,现在只用知道
- main 方法是固定写法.
- 程序运行从main方法开始执行,没有main则不能被执行.
属性
在一个类中,不仅有行为(方法),还有属性(变量)
我们以前定义变量都是在方法内定义.当学习了方法后,难免会出现,我们想要在另一个方法中使用这个方法的变量的这个问题.
解决方法就是使用类的属性.
属性是什么? 如果把类比作一个人,方法比作一个人的行为举止,那么属性就可以是这个人的姓名,性别,年龄等(只要不是行为的,其余的都是属性).
属性与我们之前学的变量是一样的,不同的是,属性可以加修饰符(修饰符后面讲).
属性的语法为:
修饰符 变量类型 变量名 = 值(可以不赋值,与变量使用方法一模一样)
我们通过下面一个例子就可以知道属性的用处了.
public class TestFunction {
// 这里的属性也加上 static 因为要在 main 中使用
static int num = 0;
public static void main(String[] args) {
// num 现在等于 0
a();
// 输出num的值
System.out.println(num);
}
static void a() {
num = 1;
}
}
运行后 结果为 1
为什么会是1 ? num不是0吗,原因就在于我们输出num的值之前,使用了方法 a,a方法里将num改为了1
所以属性的好处就是可以在不同方法内被使用.
对象
在学习了类之后,我们知道了类里面有属性和行为(变量和方法)
那么对象是什么呢?
我们在刚开始学习Java的时候说过,Java是面向对象的语言,所以,对象是非常重要的.(基础部分都重要...)
我们列举一个例子来简单理解一下什么是对象.并解释一下类和对象的关系.
人类(对所有人的统称 可以理解为一个class),每个人都有一样的行为,属性,有时候会出现新的行为属性,但是这些新的,别的人类一定可以学习使用.
那么对象,其实就是每一个人,人类有新增的行为或属性,对象也会跟着新增.只不过你可能还没有学习而已.
在举一个例子.
我们如果把对象就当成对象(男女朋友),那么你的对象必须是 男 或者 女(统称)
可以发现,我们学习的东西都会和生活挂钩(特别是别人设计出来的)
总结,什么是一个对象?
- 对象是一个类的实例.比如人是类,那么我们就是人的对象(必须是实际存在的).
类和对象的关系就显而易见了.
- 类拥有属性和行为(例如人类,有行为吃饭睡觉 和属性姓名性别).
- 对象则是实际应用这些属性和行为.(我们每个人都有一个对应的名字,很少改动,吃饭睡觉每个人每个时候都可能会不一样)
- 没有对象的类(一般都是工具类,他们不需要对象)
- 打个比方,我们有一个类,这个类里面属性方法都有.并且不需要任何改动.那么这个类就不需要对象
- 例如工具类.我们算数类(用于计算),不需要对象,因为这个类创建出来不需要什么条件...
- 我们在写代码的时候很多地方都用到对象,但他们就像上面说的,是工具类(例如之前学的Random类),但是为什么也需要对象呢?
- 因为类中除了属性和行为,还有一些东西(后面讲到),在被创建对象的时候会进行一系列操作.
- 可以理解为,我们需要 受精卵 才能创造出人的对象...
在知道了什么是对象后,我们来学习在Java中如何创建使用对象
语法为: 类 对象名 = new 类(参数);
- 例如我们之前学的Scanner,Random,我们都使用过它们的对象.
- 我们创建的代码为
- Scanner sc = new Scanner(System.in);
- Random r = new Random();
创建对象的传递参数涉及到构造方法(后面讲解)
那么,我们有了对象后,如何使用呢?
- 根据之前我们使用,比如 Scanner 的对象,我们是这样使用的
- sc.next();
- sc.nextInt();
- Random对象.
- r.nextInt(3);
可以得出,对象之间调用是通过英文点(.) 来调用的.
语法: 对象.对象的属性或者行为;
我们上面调用的都是对象的行为(类的方法),下面演示调用对象的属性(和使用变量是一致的)
public class Test {
// Test类有一个属性 名称
// 我们之前给属性加了 static,但是我们使用对象的话就不需要使用static了
// 没有加 static 的属性 不能直接在main里面使用 需要用对象
String name = "张三";
public static void main(String[] args) {
// 创建 Test 对象 我们没有写构造方法,所以创建对象都是不需要传参数的.
// 构造方法后面学
Test t = new Test();
// 直接打印对象里的name对象 会输出 张三
//(与直接使用变量是一致的,但是我们使用的是对象的属性)
System.out.println(t.name);
// 为了深入了解,我们将 t 的 name 改成李四 并且在新建一个这个类的对象
t.name = "李四";
// 对象名与变量名一样 不能重复,对象本质其实就是一个变量
// (只不过这个变量存的是内存地址(后面学))
Test t1 = new Test();
// 这里的输出结果还是张三? 我们不是将name改为李四了吗?
// 原因就在于我们使用的对象不一样,t中的name是李四,t1的name是张三.
System.out.println(t1.name);
}
}
我们来练习一下类和对象
就拿之前的例子来敲代码,有人类,人类有对象.
新建一个java文件,我们起名为 Person (中文是人的意思)
注: 可以一个文件多个Java类,但是 public 的类只能有一个且与文件名一致.
人类有 吃饭,睡觉的行为, 以及姓名,性别,年龄的属性
变成代码就是下面这样
接着我们新建一个Java文件用于创建人类对象和使用
这个类需要被执行,所以要用main方法.
我们创建两个人,并给他们都设置姓名 性别 年龄
接下来我们实现,白天,中午,晚上 他们的行为动作.
新建一个方法 operation 来执行操作,我们这个方法需要两个参数,第一个就是执行操作的人,第二个就是执行操作的时间(白天,中午,晚上)
代码如下
我们将代码完成, 白天的时候,人执行吃饭的行为,中午的时候,也是吃饭,晚上的时候,吃饭+睡觉
接下来我们在 main 方法里使用
编译,运行看结果
注: 因为我们使用的 Person 类是一个独立的文件,所以我们需要先编译Person才能编译Test,不然出错
编译成功,运行
从上面的结果可以看出,我们的程序都是从上往下执行的,我们晚上的时候,张三完成吃饭睡觉才调用李四的吃饭睡觉.
接下来我们来试一下将多个类写一个文件里(将文件 Person.class 和 Test.class 删除)
然后将Person类里的内容复制到Test里.代码如下
public class Test {
public static void main(String[] args) {
// 第一个人 就叫张三吧
Person p1 = new Person();
p1.name = "张三";
p1.sex = "男";
p1.age = 22;
// 第二个 李四,注意,别把对象名搞混了
Person p2 = new Person();
p2.name = "李四";
p2.sex = "女";
p2.age = 21;
// 早上了 我们需要让张三和李四都执行早上的操作
System.out.println("早上了!");
operation(p1,0);
operation(p2,0);
// 中午
System.out.println("中午了!");
operation(p1,1);
operation(p2,1);
// 晚上
System.out.println("晚上了!");
operation(p1,2);
operation(p2,2);
}
/**
* 执行操作,这里的 person 传递的是 Person 类的对象.
* time 则为分辨白天还是中午还是晚上.
* 我们定义 time=0 则是白天,=1则是中午,=2 则是晚上
* 因为要在main里使用,所以需要加上 static(不使用我们当前类的对象)
*/
static void operation(Person person,int time) {
// time 来分辨白天中午晚上
if (0 == time) {
// 这里的 person 是传递进来的,比如我传递的是p1,那么person就是p1对象
// 早上吃饭
person.eat();
} else if (1 == time) {
// 中午吃饭
person.eat();
} else if (2 == time) {
// 晚上 吃饭 睡觉
person.eat();
person.sleep();
}
}
}
// 别放在 Test 类里了.看清楚花括号的结尾
public class Person {
// 姓名
String name;
// 性别
String sex;
// 年龄
int age;
// 吃饭 eat中文意思是吃的意思.
void eat() {
// 吃饭被调用我们就输出当前人的名字 吃饭
System.out.println(name + ": 吃饭了");
}
// 睡觉 sleep是睡觉的意思
void sleep() {
System.out.println(name + ": 睡觉了");
}
}
接下里我们只编译Test.java试一下
这个错误就是之前说到的,一个文件里只有与文件名相同的类 才能为 public,并且只能为public
我们将 pbulic Person 的public去掉,在进行编译(记得写完代码要保存)
编译通过,也就是说,我们将类放到一个文件内,可以只编译这一个文件
实际上会自动帮你吧两个类都编译了,不信看文件夹,多出了Person.class和Test.class
运行结果与上面一致
练习
通过本节学习,我们知道了类,方法,属性,对象
上一节我们制作了一个掷骰子的游戏,代码非常非常多(main里的)
所以,我们可以试着使用方法来将一些重复代码提取出来,来试一下效果.
将上节的掷骰子游戏代码优化.熟悉使用方法和对象.以及注释
注释是非常重要的.可以这么说,当代码量超过50行,你自己写的代码,没有注释,过一段时间你再去看自己都看不懂了...
下一节我们会学习一个很重要的东西,数组
请点个赞加个关注再走吧~