类、对象、属性、方法综述
一、综述
(一)Java的核心思想是:OOP,面向对象编程
- 上帝视角,面对一个复杂的项目/问题,从宏观角度进行分类,建模剖析,从而产生不同种类的类;
- 不同的类,会根据对该细分领域的分析构造出对应的属性和方法 ,相当于一个模板;
- 在对某一类进行引用时,需要将该类的模板具体化,形成一个个的能产生实际功效的分身,将其中的属性进行具体定义,从而形成对象。
(二)面向过程和面向对象的区别
- 面向过程(执行者)
强调的是功能行为,以函数为最小单位,考虑怎么做 - 面向对象(指挥者)
强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
① 根据问题需要,选择问题所针对的现实世界中的实体
② 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
③ 把抽象的实体用计算机语言进行描述,形成计算机世界中的定义。即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构
④ 将类实例化成计算机世界中的对象,对象时计算机世界中解决问题的最终工具。
(三)面向对象的实现
- 设计类,其实就是设计类的成员
属性 = 成员变量
方法 = 成员方法 - 思想落地实现
① 创建类,设计类的成员
② 创建类的对象(new)
③ 通过“对象.属性” 或 “对象.方法” 调用对象的结构 - 如果创建了一个类和多个对象,则每个对象都独立拥有一套类的属性(针对非static型的)。意味着,如果我们修改一个对象的属性a,则不影响另外一个属性a的值
Perpon p2 = p1;
那么p2 和 p1任意一个对象有过更改,都会在对方那产生相应的改变,因为上面的赋值运算时内存地址的赋值,相当于两个实例对象指向的时同一片内存。
(四)万事万物皆对象
- 在Java语言范畴中,我们将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
① Scanner、String等
② 文件,File
③ 网络资源,URL - 涉及到Java语言与前端Html、后端的数据库交互,前后端的结构在Java层面交互时,都体现为类、对象
二、类
概念:
是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物。
比如:动物、植物、手机、Person类、Car类等
初始化/启动
(1)一个类中,包含属性、构造器、代码块、方法、内部类
(2)一个项目中应该只存在一个main方法
构造器
在新建了一个类之后,即使里面什么都不写,里面也会存在一个没有参数的方法,即构造器
- 它有下面的特点
① 必须和类的名字相同
② 必须没有返回类型,也不能写void - 定义构造器的格式:
权限修饰符 类名(形参列表){
功能体
} - 默认构造器的权限和类的权限相同
- 作用一:创建对象
Person p = new Person();
- 作用二:给对象的属性进行初始化
通过方法体,初始化一些属性的值。 - 作用三:可以定义多个构造器,也叫做构造器的重载,此时系统不再提供默认的构造器,且必须把无参的构造器显性写出。
public class Constructor {
String name;
//无参构造器
public Constructor(){
this.name = "qingjia";
}
//有参构造器
public Constructor(String name){
this.name = name;
}
}
代码块(初始化块)
① 代码块的作用:用来初始化类、对象;
② 修饰符:只能用static修饰
③分类:静态代码块 vs 非静态代码块
静态代码块
- 内部可以有输出语句
- 随着类的加载而执行,而且**只执行一次**
- 作用,初始化类的信息
- 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
- 静态代码块的执行,优先于非静态代码块的执行
- 静态代码块内只能调用静态的属性和静态的方法,不能调用非静态结构
非静态代码块
- 内部可以有输出语句
- 随着对象的创建而执行
- 非静态代码块随着**每创建一个对象,就执行一次**
- 作用:可以在创建对象时,对对象的属性等进行初始化
- 既可以调用静态结构,也可以调用非静态结构
三、对象
在抽象的概念内,能够体现出特点,展现出功能的是具体的每个个体,也称为实例。
如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的非静态属性(静态属性为所有对象共有)。意味着,如果我们修改一个对象的属性a,则不影响另一个对象属性a的值。
创建对象
使用 new 关键字创建来对象,同时会给对象分配一些默认的值和空间(内存)
内存解析
① 堆(Heap)
唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配内存空间
对象:是一个广义上的对象,即包括类实例化后的对象,也包括数组(数组的定义也要new)
② 栈(Stack)
指虚拟机栈,用于存储局部变量等。局部变量表存放了编译器可知长度的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference类型,它不等同与对象本身,是对象在堆内存的首地址)。方法执行完,自动释放。
③ 方法区(Method Area)
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
- 创建对象型数组
Student[ ] arr = new Student[20] ;
package oop;
import java.util.Arrays;
/**
* 功能
* 1.创建20个学生对象,学号为1-20,年级和成绩都有随机数确定
* 2.打印3年级的学生的信息
* 3.使用冒泡排序法个学生排序,并遍历所有学生的信息
* 提示
* 1.生成随机数:Math.random(),返回值类型double
* 2.四舍五入取整:Math.round(double d),返回值类型long
*/
public class StudentArray {
public static void main(String[] args) {
// 1.引用类型数组
Student[] arr = new Student[20];
// 2.为每一个数组元素进行Studentl实例化赋值
for (int i = 0; i <arr.length ; i++) {
arr[i] = new Student();
arr[i].number = i+1;
arr[i].state = (int)(Math.random()*(6-1+1)+1);
arr[i].score = (int)(Math.random()*(100-0+1)+0);
}
// 3.输出某一年级学生的信息如下:
for (int i = 0; i < arr.length; i++) {
if (arr[i].state == 3){
System.out.println("学号:" + arr[i].number + ",成绩:" + arr[i].score);
}
}
// 4.输出学生成绩排布情况:
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-i-1; j++) {
if (arr[j].score < arr[j+1].score){
Student m = arr[j];
arr[j] = arr[j+1];
arr[j+1] = m;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println("学号:" + arr[i].number + ",年级:" +
arr[i].state + ",成绩:" + arr[i].score);
}
}
}
// 定义student类,包含三个属性:学号number(int)、年级state(int)、成绩score(int)
class Student{
int number;
int state;
int score;
}
- 匿名对象的使用
① 理解:我们创建的对象,没有显示的赋给一个变量名,即为匿名对象
② 特征:匿名对象只能调用一次
③ 使用:也可以赋值给一个形参
四、方法
定义
描述类应该具有的功能 (Method == 成员方法 == 函数)
① 方法的声明:
权限修饰符 返回值类型 方法名(形参列表){
方法体
return
}
② 权限修饰符说明
关于权限修饰符:public private default protected,在封装性上展开说明
③ 返回值类型
有返回值:必须在方法声明时,指定返回值的类型。同时,方法中,需要使用return关键字类返回指定类型的变量或常量。
无返回值: 在方法声明时,使用void表示,方法体中return可以使用,也可以不使用
该不该有返回值:根据项目要求 / 经验
④ 方法名
属于标识符,遵循标识符的规则和规范,见名知意
⑤ 形参列表
方法可以声明0个、1个、多个形参
格式:(数据类型1 形参1,数据类型2 形参2,········)
⑥ return关键字的使用
作用1:结束一个方法
作用2:针对有返回值类型的方法,使用return返回所要的数据。
return后面不可以声明执行语句
方法分类
静态方法:可以通过类名直接调用
非静态方法:必须将类实例化成对象之后才可以调用
package com.oop.ReviewMethod;
public class Student {
public static void main(String[] args) {
//静态方法的调用
Student.patrol();
// 非静态方法的调用
Student a = new Student();
a.say();
}
//静态方法
public static void patrol(){
System.out.println("巡查谁上课说话");
}
//非静态方法
public void say(){
System.out.println("上课说悄悄话");
}
}
形参
参数类型:限定了以后调用方法时可以使用的数据类型
参数名:给调用方法时传入的数据占个位置
值传递机制
① 如果形参是基本数据类型:那么实参赋给形参的是实参存储的具体数值
package com.oop.ReviewMethod;
public class PassByValue {
public static void main(String[] args) {
int a = 1;
// 将局部变量 a 的值作为实参传递给了change的形参,方法内的操作不会改变a的值
PassByValue.change(a);
// 输出1
System.out.println(a);
}
public static void change(int a){
a = 10;
}
}
② 如果形参是引用数据类型:实参赋给形参的是地址值
package com.oop.ReviewMethod;
//引用传递,本质还是值传递
public class PassByReference {
public static void main(String[] args) {
// 实例化Person类,实例化出一个具体的对象a
Person a = new Person();
// 将对象a的地址值作为实参传入change方法中,方法中的操作会改变a地址值的数据
PassByReference.change(a);
// 输出为:秦疆
System.out.println(a.name);
}
public static void change(Person person){
person.name = "秦疆";
}
}
class Person{
String name;
}
```
- 方法的使用
① 可以调用类的属性和方法(该类不一定是当前类)
② 方法中不可以定义另一个方法
五、属性
Field == 成员变量 == 域/字段
属性与局部变量
相同点:
① 定义变量的格式一致:数据类型 变量名 = 变量值
② 先声明,后使用
③ 变量都有其对应的作用域
不同点:
① 在类中声明的位置不同
属性:定义在类的大括号{ }下的变量
局部变量:声明在方法内、方法形参、代码块、构造器内、构造器形参的变量
② 关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符(public、private、protected、default(默认))
局部变量:不可以使用权限修饰符
③ 默认初始化的情况不同
属性:类的属性,根据其类型,都有默认初始化值
局部变量:没有默认初始化值,我们在调用局部变量之前,必须要显式赋值(形参除外)
④ 在内存中加载的位置不同
属性:加载到堆空间中(非static型)或方法区(static型)
局部变量:加载到栈空间中
public class Variable {
//属性(成员变量)
public String name;
private int age;
protected boolean isMale;
public void talk(String language){ //language:形参,局部变量
System.out.println("我们用" + language + "进行交流");
}
public void eat(){
String food = "烙饼"; //food,局部变量
System.out.println("北方人喜欢吃" + "food");
}
}
``
属性赋值的先后顺序
① 默认初始化
② 显示初始化
③ 代码块中赋值
④ 构造器中赋值
⑤ 通过”对象 . set方法“ 或 ”对象 . 属性“的方式赋值
注:显示初始化和代码块中赋值属于同一层次,看先写哪个,就先执行哪个
六、package
- 为了更好的实现项目中类的管理,提供包的概念
- 使用package声明类或者接口所属的包,声明在源文件的首行
- 包,属于标识符,遵循标识符的命名规则、规范(全小写)、见名知意
- 每 “ . ”一次,就代表一层文件目录。
- 同一个包下,不能命名同名的接口或类;不同的包下,可以命名同名的接口、类
- JDK 下主要的包介绍
① java.lang:包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用的功能。
② java.net:包含执行与网络相关操作的类和接口
③ java.io:包含能提供多种输入/输出功能的类
④ java.util:包含一些使用工具类,如定义系统特性、接口的集合框架类,使用与日期日历相关的函数
⑤ java.text:包含一些java格式化相关的类
⑥ java.sql:包含了Java进行JDBC数据库编程的相关类/接口
⑦ java.awt:包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)
七、import
- 在源文件中显示的使用import结构导入指定包下的类、接口
- 声明在包的声明和类的声明之间
- 如果需要导入多个结构,就并列写出即可
- 可以使用 * ,表示可以导入该包下的所有结构
- 如果使用的类和接口是java.lang包下定义的,则可以省略import结构
- 如果使用的类或接口是本包下定义的,则可以省略import结构
- 如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account;
- 使用“xxx.*”方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显示导入
- import static 导入指定类或接口中的静态结构。落脚点必须是类中的静态属性或者静态方法
八、UML类图