方法
声明的格式:
arduino
public class 类名{
【修饰符】 返回值类型 方法名(【形参列表】){
方法体语句;
}
}
//【】表示可选
方法调用过程内存分析
- 入栈:当方法被调用执行时,JVM会给这个方法在"栈"内存开辟一块独立的内存空间,用于存储这个方法的局部变量等信息。
- 出栈:当这个方法调用结束,JVM会自动释放这个方法占用的栈内存空间。
- (栈:先进后出)
方法的参数传递机制
- 参数是基本数据类型 结论:参数是基本数据类型时,实参把数据值copy给形参之后,它们就没关系了。形参无论怎么修改,都与实参无关。
- 参数是引用数据类型 Java的类,数组等都是引用数据类型,参数是引用数据类型(8种基本数据类型以外),实参给形参的是首地址的副本,意味着形参和实参指向同一个对象,所以形参的修改会影响实参。
- 凡是new操作的都在堆。
- 出栈释放的是栈内存空间,不会自动释放堆内存空间。
快捷键
- 生成main方法
main
+ 回车psvm
+ 回车
- 变量大于
- soutv: 默认输出离它最近的变量的值
- 变量.soutv:输出对应变量的值
方法的重载
- 方法的重载:
在同一个类中,出现两个方法的名称相同,形参列表不同,这样的形式称为方法的重载。方法重载与修饰符、返回值类型、方法体无关。
形参列表不同:可以是个数不同,类型不同,顺序不同,不看形参名
- 为什么要重载?
方法名见名知意,如果两个方法的功能是相同的,那么它的名称就应该一样
- 重载方法的调用原则
先找实参的个数、类型、顺序与形参完全匹配的,如果找到了,就可以确定了 如果没找到完全匹配的,要找可以兼容的,大的类型可以兼容小的类型,例如double可以兼容int
调用重载的方法时,光标至于括号中,Ctrl+P 可查看所匹配的方法参数类型。
可变参数
可变参数是指参数的个数不确定,可以是0~n个参数值。
可变参数的标记符号:...
可变参数的使用方式,用使用数组的方式使用它即可。
可变参数 | 数组类型 | |
---|---|---|
形式(以int为例) | int... | int[] |
调用时 | 可以传入0~n个元素,也可以直接传入数组 | 只能传入数组 |
限制 | 一个方法最多只能有1个可变参数,而且必须是最后一个形参 | 没有限制 |
面向对象的基本概念
1.1 什么是面向对象?
面向对象是一种编程的思想,编程的方式。
面向过程是另一种非常经典的编程思想。
面向过程是以步骤/过程为中心,面向对象是以类和对象为中心。
举例:把大象装进冰箱的代码实现
面向过程:
- 第一步:把冰箱门打开
- 第二步:把大象装进去
- 第三步:把冰箱门关上
面向对象:
角色/对象:人、冰箱、大象
每一个角色需要完成什么事,能干什么事,或具有什么功能:
- 人:推和拉的能力
- 大象:走
- 冰箱:打开,关上,冷冻...
java
public class 人{
public void 推(东西){
//....
}
public void 拉(东西){
//....
}
}
java
public class 大象{
public void 走(){
//...
}
}
java
public class 冰箱{
public void 打开(){
//...
}
public void 关上(){
//...
}
public void 冷冻(){
//...
}
}
java
public class 主类{
public static void main(String[] args){
人 ren = new 人("张三");
大象 e = new 大象("亚洲", 10 );
冰箱 b = new 冰箱("格力", 5,10,10);
ren.拉(b);
ren.拉(e);
ren.推(e);
ren.推(b);
}
}
1.2 类与对象的概念
1、什么是类
生活中把事物也会进行分"类"。
Java中也要进行"分类",把一类具有相同特性/特征
的事物用一个Java来描述。例如:
要做一个学生考试管理系统,学生:张三、李四、王五等,他们的共同特征:
- 数据特征:姓名、年龄、性别、身份号码.... => 类的属性
- 行为特征:注册、登录、考试、查看成绩... => 类的方法
总结:一类具有相同特性的事物的抽象
描述。
2、什么是对象
对象是指这类事物的一个具体
的个体,实体。
3、类与对象的关系
类是创建对象的模板,设计图。比喻:造汽车,先有汽车的设计图。设计图中体现了这里车的所有特征/构造/结构和功能。
对象是具体的实例,个体。比喻:对象是具体的一辆车,能开的车。
1.3 如何声明类和创建对象?
先有类还是先有对象?
从需求分析/设计项目的角度:先观察对象,才能总结有哪些类?
从代码实现的角度来说:先声明类,后创建对象。
1、声明类的格式
java
【修饰符】 class 类名{
}
public的类有一个要求,类名与xx.java的源文件名必须一致。
类名:见名知意。遵循大驼峰命名法,即每一个单词首字母大写。
java
public class Student {
}
2、创建对象的格式
java
类名 对象名 = new 类名();
new是用来创建实例对象的关键字,实际意义是在堆中开辟一块内存用于存储对象的信息。例如:创建数组对象时,在堆中开辟一块空间,用来存储数组的元素。
java
public class TestStudent {//主类,包含主方法的类
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
System.out.println(s1);//Student@4eec7777
System.out.println(s2);//Student@3b07d329
System.out.println(s3);//Student@41629346
//s1,s2,s3都是引用数据类型的变量,s1,s2,s3中都是存储对象的首地址。
//这一点与数组一样
int[] arr = {1,2,3,4};
System.out.println(arr);//[I@404b9385
}
}
Student是一个类,也是一种数据类型,称为类类型。它与String是一样的。只不过String是JRE核心类库中已经提前写好的类,Student是咱们自己写的类。同理,数组类型,例如:int[],String[],double[]也是数据类型,是数组类型。它们统统都是引用数据类型。
1.4 包
1.4.1 包的作用
- 可以通过不同的文件夹/包帮我们管理众多的类,分门别类进行管理,便于后期的维护
- 可以避免类的重名,有了包之后,类的全名称就是包.类名
- 包结合权限修饰符(public,protected,缺省,private等)来限定类或成员可见性范围。关于权限修饰符后面再讲。
1.4.2 如何声明包?
java
package 包名;
- 这句代码必须在源文件的首行。
- 包名的命名规范:所有单词都小写,单词直接使用.分割。习惯上用公司域名倒置的写法,例如:com.123vwu.xxx
1.4.3 如何跨包使用类
- 如果是同一个包,类之间互相使用,不需要import
- 如果是跨包(不同包),类之间互相使用,必须import 或 使用类的全名称
- 只有public修饰的类才能跨包使用
- java.lang包的类,在任意地方使用都不需要导包,例如:String,Math,System 它们都是java.lang包的类
- 如果需要导入不同包中的相同类名,只能一个是 import,一个是全名称,或者两个都全名称
1.5 类的成员之一:成员变量
1.5.1 成员变量的声明格式
java
【修饰符】 class 类名{
【修饰符】 数据类型 变量名;
}
成员变量的声明位置:类中方法外。
如果把变量定义/声明到方法里面,那就是局部变量,不是成员变量。
【修饰符】:暂时都是public
1.5.2 成员变量的分类
1、静态变量
静态变量不依赖于对象,不属于对象,属于类。跨类使用它,建议通过"类名.静态变量"。也可以通过"对象.静态变量"。
2、实例变量/非静态成员变量
实例变量依赖于对象,属于对象。跨类使用它,必须通过"对象.实例变量"。
对于静态变量的跨类访问,建议用
类名.静态变量
如果用对象.静态变量
,编译能通过,不会报错。 但是:1. 容易误导其他开发人员,错误理解成访问的是实例变量。2. 给编译器增加工作量,编译器最终还是需要翻译成类名.静态变量
.
1.5.3 成员变量的特点
1、成员变量有默认值
类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
char | '\u0000' |
boolean | false |
String等类、数组等引用数据类型 | null |
2、是否共享性特点
静态变量
的值是所有对象共享的
,因为它属于类,而类是创建对象模板。
实例变量
的值是每一个对象独立的
,因为它属于某个对象。
问:成员变量该不该加static?
原则:看这个成员变量的值是不是所有对象共享的,只存一份的,如果是,就应该是静态的,否则就不能是静态的。
1.5.4 示例代码
java
package com.test.field;
public class Teacher {
//静态变量,静态成员变量,学校名是所有老师共享的
public static String school;
//实例变量,非静态成员变量,姓名、年龄、薪资是每一个老师独立的
public String name;//姓名
public int age;//年龄
public double salary;//薪资
}
java
package com.test.field;
public class TestTeacher {
public static void main(String[] args) {
// System.out.println("姓名:" + name);//错误,name在Teacher类中
// System.out.println("姓名:" + Teacher.name);//错误,因为name没有static
System.out.println("学校:" + Teacher.school);//null
Teacher t1 = new Teacher();//创建对象,创建实例
System.out.println("t1的姓名:" + t1.name);//null
System.out.println("t1的年龄:" + t1.age);//0
System.out.println("t1的薪资:" + t1.salary);//0.0
// int a;//局部变量
// System.out.println("a = " + a);//报错,因为a没有初始化
System.out.println("赋值之前:");
Teacher.school = "大学";
t1.name = "张三";
t1.age = 23;
t1.salary = 16500;
Teacher t2 = new Teacher();
t2.school = "微客鸟窝";//推荐用 Teacher.school = "微客鸟窝";
System.out.println("t1的学校:" + t1.school);//推荐用 Teacher.school
System.out.println("t1的姓名:" + t1.name);
System.out.println("t1的年龄:" + t1.age);
System.out.println("t1的薪资:" + t1.salary);
System.out.println("t2的学校:" + t2.school);//推荐用 Teacher.school
System.out.println("t2的姓名:" + t2.name);
System.out.println("t2的年龄:" + t2.age);
System.out.println("t2的薪资:" + t2.salary);
}
}
java
package com.test.field;
public class Chinese {//中国人
//国家名是所有中国人共享的,所以是静态的
private static String country;
//每一个中国人的名字是独立的,所以是非静态的
private String name;
}
java
package com.test.field;
public class Account {//银行账号
//银行利率是大家统一的,所以是静态的
private static double rate;//利率
//余额是每个人不同的,所以是非静态的
private double balance;//余额
}
1.5.5 引用数据类型的成员变量
java
package com.test.field;
public class Husband {//丈夫
//以下是两个引用数据类型的实例变量
public String name;
public Wife wife;
}
java
package com.test.field;
public class Wife {//妻子
//以下是两个引用数据类型的实例变量
public String name;
public Husband husband;
}
java
package com.test.field;
public class TestHusbandWife {//主类,测试类
public static void main(String[] args) {
Husband h = new Husband();
h.name = "张三";
Wife w = new Wife();
w.name = "翠花";
h.wife = w;//给h.wife变量赋值一个Wife类型的对象
w.husband = h;
System.out.println("丈夫的姓名:" + h.name +",他妻子的姓名:" + h.wife.name);
System.out.println("妻子的姓名:" + w.name +",她的丈夫的姓名:" + w.husband.name);
}
}
1.6 类的成员之二:成员方法
1.6.1 成员方法的声明格式
java
【修饰符】 class 类名{
【修饰符】 返回值类型 方法名(【形参列表】){
方法体语句;
}
}
1.6.2 成员方法的分类
- 静态方法
- 态方法中,只可以访问本类的静态成员,包括本类的静态方法和静态变量。
- 跨类调用静态方法,建议使用"类名.静态方法",当然也可以通过"对象.静态方法"。
- 实例方法/非静态方法
- 实例方法中,可以访问本类的所有成员,包括本类的静态成员和非静态成员。
- 跨类调用非静态方法/实例方法,只可以通过"对象.非静态方法"的方式。
问:什么时候用静态方法,什么时候用非静态方法呢?
答:原则,如果在方法体中,需要访问本类的非静态成员,那么这个方法只能是非静态的。