学生交学费案例:
学生类(Student)有两个字段:name(名字)和sFee(是否缴费的状态)。有一个方法:交学费(fees)。每一个学生是通过Student类new出来的一个对象,现在创建一个数组存放多个学生对象,再判断数组中的学生是否已经缴费,如果没有,则调用学生的交费方法。
//描述学生对象
class Student
{
String name;//学生姓名
boolean isFee = false;//学生缴费状态,默认是未缴费
void fees(){//交学费的方法
isFee = true;//设置为已缴费
}
}
//学生缴费系统测试
class StudentFeesDemo
{
public static void main(String[] args)
{
//创建学生对象
Student s1 = new Student();
s1.name = "花菜";
s1.isFee = true;
Student s2 = new Student();
s2.name = "白菜";
s2.isFee = false;
Student s3 = new Student();
s3.name = "酸菜";
s3.isFee = false;
Student s4 = new Student();
s4.name = "泡菜";
s4.isFee = true;
//创建一个数组,用于存储所有学生对象
//数组元素类型[] arr = new 数组元素类型[]{s1,s2,s3,s4};
Student[] arr = new Student[]{s1,s2,s3,s4};
//使用循环来迭代数组中的每一个元素
for(Student ele : arr){
System.out.println(ele.name + "," + ele.isFee);
//判断当前学生是否缴费,如果没有则调动交费方法
if(!ele.isFee){
ele.fees();//如果未缴费,调用缴费方法
System.out.println("缴费完成");
}
}
}
}
构造器
创建一个学生对象时,代码如下:
Student s1 = new Student();
此代码特别像是在调用一个方法名为student的无参数方法。
我们把这种特殊的方法称之为构造方法、构造器。
但在类中找不到构造方法,却不报错,说明其是存在的。原因是编译器在编译源文件的时候会默认船舰一个缺省的构造器。
构造器的作用:(创建对象并作初始化)
- 创建对象,但是必须和new一起使用;
- 完成对象的初始化操作;
构造器的特点: - 构造器的名称和当前所在类的名称相同;
- 在构造器名前没有任何返回类型的声明;
- 在构造器中不能使用return语句返回一个值。
编译器创建的默认构造器的特点: - 符合构造器特点;
- 无参数;
- 无方法体;
- 如果类A没有使用public修饰,则编译器创建的构造器也没有public修饰;如果使用了public修饰,则编译器创建的构造器也使用了public修饰;
自定义构造器
构造器:如果我们没有显示体用构造器,则编译器在编译时会创建一个缺省的构造器;如果我们显示定义了一个构造器,则编译器不再创建默认构造器。由此推论:某一个类至少存在一个构造器。
//表示人类
class Person
{
String name;
//自定义构造器
Person(){
System.out.println("调用了无参构造器!");
};
Person(String n){
System.out.println("调用了有参构造器!");
//初始化操作
//可以给字段设置初始值,也可以调用初始化方法
name = n;//把n参数赋给name(初始化name变量)
};
}
//演示自定义构造器
class PersonDemo
{
public static void main(String[] args)
{
//创建对象,其实是在调用构造器
new Person();//表示调用Person类中无参数的构造器
Person p = new Person("菜");//表示调用Person类中有参数的构造器
System.out.println(p.name);
}
}
构造器的重载
方法的重载:避免在同一个类中,相同功能的方法名字不同的问题。
判断依据:两同一不同。
构造器是一种特殊的方法,也可以重载。
//自定义构造器
Person(){
System.out.println("调用了无参构造器!");
};
Person(String n){
System.out.println("调用了有参构造器!");
//初始化操作
//可以给字段设置初始值,也可以调用初始化方法
name = n;//把n参数赋给name(初始化name变量)
};
ststic修饰符
static的作用: 用来区别字段、方法、内部类、初始化代码块是属于对象还是属于类本身。
static修饰符的特点:
1):static修饰的成员(字段/方法),随着所在类的加载而加载
当JVM把字节码加载进JVM的时候static修饰的成员已经在内存中存在了。
2):优先于对象的存在,
对象是我们手动通过new关键字创建出来的。
3):satic修饰的成员被该类型的所有对象所共享
根据该类创建出来的任何对象都可以访问static成员。(狗天生就吃尿)
剧透:表面上通过对象去访问static成员,其本质依然使用类名访问,和对象没有任何关系。通过反编译看到的。
4):直接使用类名访问static成员
因为static修饰的成员直接属于类不属于对象,所以可以直接使用类名访问static成员。
class Person
{
String name;//名称
int age;//年龄
//不属于对象,属于人类
static int totalNum = 5;//人类总数
//自定义构造器
Person(String n,int a){
name = n;
age = a;
totalNum ++;
}
//死,属于对象的行为
void die(){
totalNum --;
System.out.println("某人死球掉!");
}
//毁灭不属于对象,属于人类具有的行为 (static修饰)
static void destory(){
System.out.println("世界末日人类毁灭!");
totalNum =2 0;
}
}
//演示static 修饰符
class PersonDemo
{
public static void main(String[] args)
{
System.out.println(Person.totalNum);//用类名调用static修饰的变量
Person p1 = new Person("Will",17);//创建一个类型为Person的对象
System.out.println(Person.totalNum);//6 总数加1
p1.die();//通过对象调用方法
System.out.println(Person.totalNum);//5 总数减1
p1.destory();//本质上是使用类名访问
System.out.println(Person.totalNum);//0 总数为0
Person.destory();//和上一个结果一样
System.out.println(Person.totalNum);//0
}
}
成员和实例成员的访问:
类中的成员:字段、方法、内部类;
类成员:使用static修饰的成员;
实例成员:没有使用static修饰的成员。
类成员只能访问类成员,实例成员只能访问实例成员。
类成员直接属于类,可以通过类来访问static字段和static方法。
实例成员只属于对象,通过对象来访问非static字段和非static方法。
(对象其实可以访问类成员,但是底层依然是使用类名访问的。》
在static方法中,只能调用static成员。否则错误信息为: 无法从静态上下文中引用非静态变量。
非static方法,可以访问静态成员,也可以访问实例成员。
什么时候定义成static的字段和方法:
如果这个状态/行为属于整个事物(类),就直接使用static修饰。
被所有对象所共享。
在开发中,往往把工具方法使用static修饰.
如果不使用static修饰,则这些方法属于该类的对象,我们就得先创建对象再调用方法。在开发中,工具对象只需要一份即可,可能创建N个对象,此时我们往往把该类设计为单例的,但是还是有点麻烦。
所以,一般的在开发中设计工具方法,为了调用简单,我们使用static修饰。
类成员的使用:
利处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份,可以直接被类名调用。
弊端:生命周期过长。