额外知识点
普通属性叫做成员变量(即属性(即实例变量)),静态属性叫做类变量。
idea项目及java文件创建和运行
idea项目创建
- Step1:File–>New–>Project
- Step2:Name为你所建的工程名,Location为工程保存位置。
- Step3:点击Create即可。
注意:
- 创建完之后会生成一个工程包Project1;其中.iml文件为该项目工程的核心配置文件;若.iml文件丢了或被删了,就需要重现建一个项目,原项目报废。
- 蓝色文件夹代表你可以在该文件夹下写java文件,由上图可知可在src文件夹下写java文件
java文件创建
- Step1:右键src文件夹–>New–>JavaClass
- Step2:输入java文件名,此处输入的为Test1,然后回车即可。
- Step3:创建完成后如下图所示
==注意:==由上图看出光标在公共类名后面,若想直接到达下一行,则按shift+回车即可。如图所示。
java代码运行
- 写完代码后,在代码页面直接右键—>Run即可。
- 代码运行成功之后Project1工程下会生成一个红色的out文件夹,其作用是生成对应的.class文件
类名更改
右键类名—>Refactor—>Rename
模块(Module)工程创建
因为练习的代码较多,但是每次都建一个工程都太浪费,所以暂时不在src中建java文件,利用工程存储每天的java文件,如下:
-
Step1:右键工程名–>New–>Module
-
Step2:输入Module名,然后Create。
-
Step3:生成名为Day5的Module文件夹,在该文件夹下的src文件夹中创建java文件进行每天的代码编写即可。
注意:
- Module不能独立存在,只能在工程下存在,即存在于Project1文件夹中
- 这样以后每天的代码都可以创建一个Module来存储当天的代码。
工程中删除和附加模块(Module)详见本章在工程中删除和附加模块(Module)
程序分析方法
-
面向过程的程序设计思想(POP):解决问题的步骤
-
面向对象的程序设计思想(OOP):哪个类有哪个方法可以解决我们的问题
注意:
(1)关注的焦点是类:OOP就是在计算机程序设计过程中,参照现实中的事物,将事物的特征、行为抽象出来,用类来表示。
(2)某个事物的一个具体个体称为实例或对象
(3)代码结构:以类为组织单位,每种事物都具备自己的属性(即表示和存储数据,在类中用成员变量表示)和行为/功能(即操作数据,在类中用成员方法表示)
(4)面向对象语言的三大特性:封装、继承、多态
(5)面向对象语言的四大特性:封装、继承、多态、抽象
类和对象
类
-
定义:
(1)类是一类具有相同特性的事物的抽象描述,是一组相关属性和行为的集合。
(2)类是一个模板,是一个规范。自己定义的类不能与系统的类重名
例子:老师讲语文课 -
类中的两大内容
(1)属性:即该事务的状态信息(对象的特征,需要结合需求去选择对象对应的特征,比如:姓名、年龄等),用来表示和存储数据,在类中用成员变量表示。说白了就是一类事物的统称。
(2)行为/功能:也叫做方法,即操作数据(也就是利用数据(属性)进行操作来实现对象的行为动作),在类中用成员变量表示。
通俗语言解释行为:在你的这个程序中,该状态信息是要做什么操作,或者基于事物的状态能做什么,这就是行为的具体要实现的内容。
属性和行为/功能的内容特点详见实体类 -
类包括测试类和实体类两种
类的成员变量、局部变量和方法
类的成员变量、局部变量
- 成员变量有两种:类的成员变量和对象的成员变量。其中对象的成员变量不需要定义,因为对应的类的成员变量已经定义过了,只需对其进行赋值即可。
- 声明类中的成员变量(即属性(即实例变量))
(1)定义格式:
(2)位置要求:必须在类中,方法外
(3)例子:
类体中的public为访问修饰符,修饰类的成员(即类体内的东西)。而class前的public为公开类。类体内都可以用访问修饰符修饰,但也可以不用。图一用了访问修饰符,图二没用。修饰符在后期会逐渐遇到。
(4)注意:
属性声明后是紫色的。
而局部变量声明在方法中,且在未使用前为灰色,在使用后为黑色。图一为未使用局部变量,图二为使用局部变量
图一
图二
- 属性可以是引用数据类型,也可以是基本数据类型
- 成员变量和局部变量的区别
(1)声明位置和方式:属性在类中方法外;局部变量在方法体中或方法的形参列表、代码块中。
(2)在内存中存储的位置不同:属性在堆中存储;局部变量在栈中存储
(3)生命周期不同:属性的生命周期和对象的生命周期一样,随着对象的创建而存在,随着对象被GC回收而消亡,且每个对象的属性都是独立的;局部变量的生命周期和方法调用的生命周期一样,每一次随着方法被调用而存在,随着方法执行的结束而消失,且每一次方法调用都是独立的。
(4)作用域不同:属性通过对象就可以使用,本类中“this.,没有歧义还可以省略this.”,其他类中“对象.”;局部变量出了作用域就不能使用。
(5)修饰符不同(后期会讲):属性:public、protected、private、final、volatile、transient等;局部变量:final
(6)默认值:属性有默认值;局部变量没有默认值,必须手动初始化,其中的形参比较特殊,靠实参进行初始化。
类的方法
- 定义:是一组代码语句的封装,用来实现代码的重用,从而减少冗余代码。方法是一个类中最基本的功能单元。
- 完整的方法 = 方法头 + 方法体
一个方法头包括五个常规部分,如下: - 特点:
(1)必须先声明后使用(注意:类、变量、方法等都需要先声明后使用)
(2)不调用不执行,调用一次执行一次。
(3)类中可以有多个方法。
(4)方法体内不可以定义方法即方法不可以嵌套。
(5)方法也可以用static修饰,但本次只用public。static修饰在后期会详细讲解。 - 方法调用格式:对象名.非静态方法([实参列表])
定义和使用带参的方法
1、基础数据类型传参
- 特点:传递的是值
- 定义带参数的方法:
(1)方法声明时,小括号中声明的是方法的参数组
(2)参数包括参数类型和参数名,但没有参数值,所以方法声明时的参数被称为形参
(3)方法体内的局部变量和方法的形参的生命周期一样,且不能重名
(4)方法的形参可以是基础数据类型、引用数据类型。且方法的形参数量无限制,多个形参之间用逗号隔开 - 使用带参数的方法
(1)调用时实参和形参的名字可以一样可以不一样,但是形参和实参的类型必须一致。因为再调用方法传递实参时,是使用实参的值为形参赋值。
2、引用数据类型传参 - 特点:传递的是内存地址。
3、两种传参方式的区别
基础数据类型传参传的是变量值;引用数据类型传参传的是对象的地址。所以基础数据类型中的变量在进行传参后不会发生值的交换,而引用数据与类型中发生了值的交换。
方法调用的内存分析
- 当一个方法被调用时,需要在栈空间中为方法分配运行用的内存空间,该动作叫做方法入栈。
- 当一个方法运行完全部代码后,方法的内存空间释放,该动作叫方法出栈。
- 栈结构:后进先出。
方法的参数问题—可变参数
- 定义
形参的个数是可以变化的 - 格式
修饰符 返回值类型 方法名(数据类型...变量名)
------此处的变量其实是一个数组
public static int sum (int...a){}
1、利用静态数组进行可变参数传递
2、利用变长参数组(可变参数组)进行可变参数传递 - 定义:传实参时可以传任意参数,可以为0个,也可以多个。
- 特点:
(1)调用带变长参数组的方法时可以不传参也可以有几个传几个参数,多个实参间用逗号分割;
(2)一个方法的参数列表中只能出现一个变长参数组;
(3)变长参数组可以和普通参数一起使用,但其只能在形参列表的最后一项;
(4)普通参数在方法调用时必须传参,而变长参数组可以不传参;
(5)变长参数组在方法体中的使用方法与数组一致,变长参数组其实就是数组。 - 例子1:可变参数组不传参数
- 例子2:可变参数组传多个参数
- 为什么习惯不用数组而用变长参数组?
答:方便调用点调用,可直接在调用点处进行参数组的修改。
方法重载(MethodOverloading)
- 定义:指在同一类中,允许存在一个以上的同名方法,只要他们的参数列表不同即可。
- 特点
(1)方法重载只能发生在同一个类中
(2)多个方法方法名相同,但参数组不同(分为参数类型不同、参数个数不同、参数顺序不同),则构成方法重载
方法的递归调用(了解)
- 定义:方法自己调用自己的现象称为递归
- 递归分类
(1)直接递归:方法自身调用自己
(2)间接递归:A方法调用B方法,B方法调用C方法,C方法调用A方法。 - 注意事项
(1)递归一定要有条件限定来保证递归可以停下来,否则会发生栈内存溢出
(2)递归虽然有限定条件,但递归深度不能太深,否则效率低下或发生栈内存溢出
(3)能够使用循环代替的,尽量使用循环代替递归。
方法的相关问题
- 对属性进行修改,则方法中的属性用的是属性修改前的还是属性修改后的
答:修改后的 - 方法的形参和方法体内的局部变量的区别?
答:形参的值是由外界(方法调用点)传入的而局部变量的值是由方法内部决定的。 - 什么值可以作为形参、局部变量?
答:自己可以定的值可以作为局部变量;而需要外界传入的则做形参。 - 同一个类中的方法是否可以直接调用?
答:可以。调用格式:this.方法名------this可以省略不写,如图所示 - 形参和实参是否可以重名?
答:可以。 - 局部变量是否可以和形参重名?
答:不可以 - 形参和属性是否可以重名?
答:可以。一旦重名,形参拥有更高的优先级。此时若想访问属性,则需要加上t“this.属性名” - 局部变量是否可以跟属性重名?
答:可以。一旦重名,局部变量拥有更高的优先级。此时若想访问属性,则需要加上t“this.属性名”
类的相关问题及事项
1、潜规则:测试类只写main方法,实体类只写普通属性方法不写main方法。
2、是不是所有的类都有main方法?
答:并不是所有的类都有main方法,如:实体类,其主要内容为属性和方法。
对象
- 定义:对象是一类事物的一个具体个体,即对象是类的一个具体的实例。
- 特点:
(1)对象是写在测试类中的
(2)对象具备对应类的属性和行为
例子:李老师讲语文课
测试类
- 定义:只有main方法,没有其他结构或内容可以运行的类。
实体类
- 定义:有属性有方法但没有main方法,代表现实世界中的实体且不需要运行的类
- 实体类中含类的两大内容,即:
1、属性
- 特点:
- 有默认初始值,所以不需要着急赋值
- 不同元素类型的数组元素的默认初始值是什么,则属性的默认初始值就是什么
- 属性是属于类的,但属性的值是属于对象的,所以赋值需要在对象中赋值。也就是在带main方法的公共测试类中利用对象进行赋值。
2、方法
- 特点:
- 方法大括号内的东西称为方法体,方法体内写代码(利用属性进行操作来实现对象的行为动作的代码)
- 方法大括号内的东西称为方法体,方法体内写代码(利用属性进行操作来实现对象的行为动作的代码)
实体类运行方法
- Step1:创建一个带main方法的公共测试类,命名为Test+实体类名,如:TestStudents
- Step2:使用一个类的属性或方法时必须创建该运行类的对象。
创建方法: 使用对象名.属性名 和对象名.方法名()的方式调用属性或方法
注意: 仅在public修饰下时需使用使用对象名.属性名 和对象名.方法名()的方式调用属性或方法。static修饰则不同,其会在后期讲解。
- Step3:在公共测试类中用对象来对属性进行赋值,并调用实体类中的方法类运行代码程序。
包和导包
包
- 避免类重名:有了包之后,类的全名就变为了:包.类名
- 可以控制某些类型或成员的可见范围。例如:若某个类型或成员的权限修饰缺省的话,则就仅限于本包使用。
- 分类组织管理众多的类。
- 在src下建的类不能重名,而在包中不同的文件夹下建立的类可以重名。即解决了命名冲突。所以在后续学习中不仅要学习这个类还要学习该类在哪个包下,以免有重名的类
idea中导入包
src------>New------>Package,然后输入包名,注意:根据命名规范,包名全小写英文字母且只能使用字母数字(数字不能开头)
注意:
(1)此处创建了一个三级包。.只是为了给其分级,即com文件夹下的atguigu文件夹下的test文件。如图所示
(2)注意每一级的包都是独立的包,每个包下都可以创建类或子包(即包是可以嵌套的)。一般只在三级包中建java类
(3)一级包一般是项目的域名,如baidu.com;二级包一般是工程名;三级包一般是包的身份,如:业务访问包。
在包中创建java类
- 右键包------>New------>JavaClass,然后输入类名即可。此时也建立一个类名为Students类。如下图所示
- 在该包下再创建一个测试类
包的相关问题
-
在java中,一个类只能访问和自己同包的类。若希望访问其他包的类,则必须使用import关键字将需要访问的类导入当前包。详见图。
-
假设使用了Scanner方法,但未导入对应的包,则会直接标红,如下所示。可以直接选中Scanner然后alt+回车,然后选中import class即可自动导入包。import java.util.Scanner即导入java包下的util包下的Scanner类。
-
src下的类是无法导的(但是src下的类可以导别的包),因为src下的类并没有在包中。导包必须是包名.类名。而src下的类并不在包内。如果要导的话你就必须将其放在包内然后再进行导包才可以。详见图二,将src下的类都放在在atguigu中新建的test1包下。
图一
图二
鉴于该原因,所以src下不能直接建类,先建包,后在包中建类 -
若想导入其他人或国家的包(即第三方包),你需要先把包下载到本地,然后导入即可。
-
String[]和System在package java.lang包中,而任何一个java类都默认导入java.lang包中的所有类。
在工程中删除和附加模块(Module)
删除工程中的模块
-
Step1:右键工程中的模块—>Remove Module。此时该模块则仍在工程中,只是不把它当作一个模块去看。且此时模块右下角以及模块内的src会变成灰色。
-
Step2:然后再次右键工程—>Delete。此时才会从工程中消失
在工程中添加模块
- Step1:将模块复制到工程文件夹下,则idea中会自动出现该对应的模块,但此时并没有被idea当作一个模块,因为该模块右下角以及模块内的src为灰色
- Step2:File—>Project Structure—>Modules—>±–>Import Module
- Step3:找到复制到工程中的module并查看是否有src文件夹及iml文件,然后点击OK
- Step4:无脑一直点击next,然后会遇到下图所示,点击Overwrite—>Created—>OK即可
对象数组
- 定义:当数组的元素是引用数据类型时,则为对象数组。
- 由例子来理解
构造器/构造方法(Constructor)
- 解释:为new的对象,并在new对象的时候为实例变量(属性)赋值
- 作用:创建对象时调用构造器直接为类中的属性进行初始化。
- 特点
(1)在一个类中,若没有任何一个显式的构造器,则系统会为我们配备一个隐式无参的构造器。若有任何一个显式构造器的存在,则隐式无参构造器会自动消失。若不想其消失则自己再定义一个即可。
(2)构造器名必须与它所在的类同名,且命名方式也与类一样。
(3)构造器没有返回值,所以不需要返回类型,甚至不需要void
(4)构造器只能在创建对象时调用
(5)构造器可以重载,既可以定义参数也可以不定义参数。
(6)构造器的修饰符只能是权限修饰符,不能被其他任何修饰
-
定义格式:
-
例子
-
同一个类中的构造器可以互相调用
this():调用本类的无参构造器
this(实参列表):调用本类的有参构造器
this()和this(实参列表)只能出现在构造器首行
不能出现递归调用
静态------类中的静态
静态关键字(static)
- 作用:
(1)可以修饰类的成员,比如属性、方法、代码块。不能修饰构造器
(2)修饰的属性叫静态属性,修饰的方法叫静态方法 - 静态属性
(1)静态属性可以不创建对象,直接由类名调用。其也可以由对象名调用,但是不推荐。
(2)静态属性也叫作类变量,静态属性全类用一个,任何一个对象对静态属性的修改或通过类对静态属性的修改,都会影响其他对象看到的属性值。而普通属性则没有该特点。
- 问题:为什么任何一个对象对静态属性的修改,都会影响其他对象看到的属性值?
答: - 普通属性随着对象的创建在堆空间中分配内存空间而静态属性随着类的加载在方法区创建内存空间
- 类存在于.class文件中。.class文件的信息通过加载被读取到了内存中,当被读取到内存中后.class文件会在方法区形成一块内存空间
-
- 该空间记录了对应的类信息(即Student类信息)(此处以Student类文件为例);Student类信息包括普通属性的签名(即只记录普通属性的信息但不给其分配空间,如:stuName为public限制符,String类型)和静态属性。
- 类加载完之后,在栈中创建对象名(对象名就是引用,引用就是对象名)来保存在堆中用new创建分配的对象的内存地址(即普通属性在堆中分配内存空间),然后根据方法区中普通属性的签名就可为普通属性进行赋值。
- 静态属性随着.class文件被读取到内存中时(随着类的加载)就已经在方法区分配了内存空间。方法区中的属性被共用。
静态方法(StaticMethod)
- 定义:由static修饰的方法叫做静态方法,静态方法不需要创建对象,由类名直接调用,静态方法也可以由对象名调用,但是不推荐。
- 特点:
(1)静态方法的传参、返回、方法入栈和出栈等都与普通方法一样。
(2)静态方法和普通方法一样,都在栈中分配内存空间
(3)静态方法由类名调用入栈,也可以由对象名调用入栈;而普通方法只能由对象名调用入栈
(4)静态方法不能被重写。静态方法属于类,而不是类的实例。因此,即使在子类中定义了与父类中静态方法同名的方法,也不会覆盖父类中的静态方法。
(5)类中的静态成员只能访问静态成员,不能访问普通成员;而普通成员既能访问静态成员也能访问普通成员。如图所示
静态成员不能访问普通成员
静态方法通过创建对象后可访问普通成员,但是不推荐