类的定义和对象
类的定义
类是用来描述现实世界的事物 是一组相关属性和行为的集合 ,是java语言最基本的单位,所以一般把描述相同的事物写在一个类中。
例如 学生类 Student.java 汽车类 Car.java
事物:
-
属性:事物的描述信息 也称为成员变量(全局变量)
-
行为:事物能做什么 也称为成员方法
类的组成:属性+行为 或 成员变量+成员方法(统称成员)
例如:猫 、狗
-
属性:名字、体重、年龄、颜色。
-
行为:走、跑、叫。
对象
对象是该类事物的具体体现。对象是类的一个 实例 ,必然具有该类事物的属性和行为。
学生类: 学习委员是一个对象 班长是一个对象 团支书也是一个对象
类和对象的关系
类是对一类事物的描述,是 抽象的 。
对象是一类事物的实例,是 具体的。
类是对象的模板,对象是类的实体 。
英雄就是类,具体的英雄,如盖伦、提莫就是对象
成员变量和成员方法
成员变量和以前定义变量是一样的,只不过位置发生变化了
成员变量:在类中,方法外
成员变量也叫做全局变量,可以不需要给初始化值
定义成员变量格式:
数据类型 变量名;
定义在方法里面的叫做局部变量
成员变量的特点:
成员变量有默认初始化值,当一个对象被创建后,会对其中各种类型的 成员变量 自动进行初始化赋值。除了基本数据类型之外的变量类型都属于引用数据类型。
成员方法和以前定义的方法一样的,只不过把static去掉
创建一个类格式
访问修饰符 class 类名{
// 成员变量
// 成员方法
}
-
定义类 :就是定义类的成员,包括 成员变量 和 成员方法 。
-
成员变量 :和以前定义变量几乎一模一样,只不过位置发生了改变。 在类中,方法外 。
-
成员方法 :和以前写的 main 方法类似,只不过功能更加丰富了。
创建对象格式
类名 对象名 = new 类名();
如何去使用类成员
使用成员变量:对象名.成员变量
使用成员方法: 对象名.成员方法
定义成员方法格式
// 有返回值
修饰符 返回值类型 方法名(参数类型 参数名,......){
完成特定功能的代码快;
return 返回值
}
// 无返回值
修饰符 void 方法名(参数类型 参数名,......){
完成特定功能的代码快;
}
这里的修饰符用:public 、 private 、 protected 、默认的(不写)
修饰符
public 公开的 可以修饰类、属性、方法等
private 私有的 可以修饰类、属性、方法等
如果修饰成员变量和成员方法只能在本类中使用
默认修饰符(不写)
protected 半公开的修饰符
定义标准类
private修饰的成员变量提供public修饰的getter/setter()
方法一:用快捷键 Alt + insert 出现
方法二:用鼠标右击==》Generater==>选择Getter and Setter提供构造方法 无参构造方法和带参数的构造方法
构造器
构造方法的作用
构造方法Constructor类,有无参构造方法和有参构造方法
构造方法的格式
// 无参构造方法
public 类名(){
}
// 有参构造方法
public 类名(参数类型 参数名,.....){
}
构造方法名与类名相同,构造方法也是个方法,没有返回值类型,连void也没有,相应的没返回值(无return 值),构造方法是重载的
创建对象格式:
类名 对象名 = new 构造方法;
构造方法的注意事项
如果类中自己不写构造方法,系统会默认提供一个无参的构造方法xxx()是空的 ,没有参数但是如果自己写了构造方法,系统就不会提供无参构造方法当创建对象时,根据参数不同调用哪个构造方法,如果调用的是全参,注意参数类型和顺序
this关键字
this:代表所在类对象引用
记住:方法被哪个对象调用,this就代表这个对象
public static void main(String[] args) {
// 创建Person对象
Person p1 = new Person();
p1.setName("张三");
p1.setAge(18);
Person p2 = new Person();
p2.setName("李四");
p2.setAge(20);
System.out.println(p1.getName());// this代表
p1这个对象
System.out.println(p2.getName());// this代表
p2这个对象
}
成员变量和局部变量的区别
在类中的位置不同
成员变量:在类中,方法外
局部变量:在方法内(大括号内{})或形式参数上(方法的申明上)
初始值不同
成员变量:有默认的初始值,可以直接使用
局部变量:没有默认的初始值,当使用时,必需要先赋值,才能使用
在内存中的位置不同
成员变量:在堆heap内存中
局部变量:在栈stack内存中
生命周期不同
成员变量:随着对象的存在而存在,随着对象消失而消失
gc:java的垃圾回收器,运行线程上一个守护线程,自动触发
局部变量:随着方法的调用而存在,随着方法调用结束而消失
对象内存图
实例变量的内存分析
Java 对象保存在内存中时,由以下三部分组成:
对象头:Mark Word:记录了和当前对象有关的 GC、锁等信息。指向类的指针:每一个对象需要记录它是由那个类创建出来的,而 Java 对象的类数据保存在方法区,指向类的指针就是记录创建该对象的类数据在方法区的首地址。该指针在 32 位的 JVM 中的长度是 32bit,在64 位的 JVM 中的长度是 64 bit。数组长度:只有数组对象才有。
实例数据:实例变量的值。
对齐填充:因为 JVM 要求 Java 对象占用的内存大小应该是
8bit 的倍数,所以如果不满足该大小,必须补齐至 8bit 的倍
数。
一个对象内存图
public class Phone {
String brand;
double price;
public void call(){
System.out.println("打电话");
}
}
public static void main(String[] args) {
// 创建Phone对象
Phone p = new Phone();
System.out.println(p);
p.brand = "华为";
p.price = 2999.9;
p.call();
}
两个对象指向两个对象地址内存图
public static void main(String[] args) {
Phone p1 = new Phone();
p1.brand = "华为";
p1.price = 2999.9;
p1.call();
System.out.println(p1.price);
Phone p2 = new Phone();
p2.brand = "锤子";
p2.price = 888;
p2.call();
System.out.println(p2.price);
System.out.println("========分别改变两个对象的
价格======");
p1.price = 1000.0;
p2.price = 500;
// 改变价格 互不影响
System.out.println(p1.price);
System.out.println(p2.price);
}
结论:连个对象值的改变 互不影响
两个对象指向同一个对象地址内存图
public static void main(String[] args) {
Phone p1 = new Phone();
p1.brand = "华为";
p1.price = 2999.9;
p1.call();
System.out.println(p1.price);
System.out.println("========分别改变两个对象的价格和品牌======");
Phone p2 = p1;
p1.brand = "锤子";
p2.price = 888;
System.out.println(p1.price);
System.out.println(p2.price);
System.out.println(p1.brand);
System.out.println(p2.brand);
}
类名作为形式参数
格式:
public class Student {
// 自定义的成员方法
public void study(){
System.out.println("好好学习,天天向上");
}
}
public class Teacher {
// 成员方法 自定义的类作为形式参数
public void test(Student s){
s.study();
}
public void add(String name){
System.out.println(name);
}
}
public static void main(String[] args) {
// 创建Teacher对象
Teacher t = new Teacher();
// 调用Teacher类中的test()
String name = "张三";
t.add(name);
// 创建Student对象
Student student = new Student();
t.test(student);
}
方法名(int a,int b){} 其中a,b就是形参
方法名(int[] arr){}
方法名(String s){} 方法名(Student s){} 方法名
(Person p){}
其实要的就是该类的对象名 要的 s p对象名
类名作为返回值类型
格式:
修饰符 自定义类 方法名(){
........;
return 自定义类对象名;
}
如果方法的返回值是自定的类名,其实返回的就是改自定义类对象名
对象数组
回顾之前定义数组:
(1)基本数据类型 作为数组的元素类型
int[] arr = new int[元素长度]
boolean[] brr = new boolean[元素长度];
(2)引用数据类型
String[] srr = {“字符串1”,“字符串2”,…};
Student[ ] sturr = new Student[3]
Student代表的是自己定义的类,存入的元素是Student的对象
例如 Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
sturr[0] = s1 sturr[1] = s2 sturr[2] = s3
这时候sturr数组中的元素类型都是Student类型,都可以指向一个\Student对象
public static void main(String[] args) {
// 创建学生数组
Student[] srr = new Student[3];
// 数组赋值 数组要存放Student对象
Student s1 = new Student();
s1.setName("张三");
s1.setAge(18);
Student s2 = new Student("李四",20);
Student s3 = new Student("王五",22);
srr[0] = s1;
srr[1] = s2;
srr[2] = s3;
System.out.println(Arrays.toString(srr));
// 遍历对象数组
for (int i = 0; i < srr.length; i++) {
Student s = srr[i];
System.out.println(s.getName()+":"+s.getAge());
}
}