一、初识类和对象
类就是一类对象的统称。对象就是这一类具体化的一个实例。
这一类对象所具备的行为和方法都在类中定义。拿我和彭于晏举例子,首先我们两都是实实在在存在的人类,各自都能被当成一个对象,那我和彭于晏有啥相同和区别呢?首先我们都有五官,他有的东西,我也有,其他任何人类也是都有的,他能呼吸,我也能呼吸,其他人类也能呼吸,但是区别是在我们都有的属性但是我们的属性值不同,我们虽然都有五官,但是我的五官比彭于晏帅,但是我们呼吸这种行为的属性值是不同的。
1.1类的实例化
基本语法如下:
// 创建类
class <class_name>{
field;//成员属性
method;//成员方法
}
// 实例化对象
<class_name> <对象名> = new <class_name>();
具体实例如图,并且注意成员变量在类中有默认值
默认值规则:
对于各种数字类型, 默认值为 0.
对于 boolean 类型, 默认值为 false.
对于引用类型(String, Array, 以及自定制类), 默认值为 null
1.2类和对象以及存储情况
类是如何产生对象的:
所有类的对象都是引用数据类型
如何使用对象的属性和方法:
调用per1时因为改变了类中的属性值,所以调用.print
方法时是打印属性值。per2没有改变属性值,所以打印出对应的默认值。
存储情况(了解即可)
第一步:在堆中开辟空间,Person类new了一个对象。每个成员变量,在每一个new的对象中都有,都在堆中存储。
第二步:per1是在主方法中定义的局部变量,所以在栈中存储。存储的是一个堆中对象内存地址。
第三步:per1访问了堆内存中的地址,将属性值给改变了。
注意:如果此时执行per1=per2,相当于是栈中指向per1的地址变为指向per2
1.3类的引用
关于特殊值null
null 在Java中表示 “ 空引用 ” ,只有名字没有去保存任何堆内存中的地址,如果直接使用值为 null 的引用去操作 “.” 任何成员属性或方法,将会产生编译错误。
class Person {
public String name;
public int age; }
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name.length()); // 获取字符串长度
}
}
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:9)
引用它的成员方法name.length时,因为name此时是默认值null,所以空指针异常。类似C 语言中的空指针. 如果对 null 进行 . 操作就会引发异常.
注意,但也不是所有null都报错,如图所示
class Test {
public static void hello() {
System.out.println("hello");
}
}
public class MyApplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=null;
test.hello();
}
这个代码运行起来,并不会发生错误,为什么呢,因为hello这个方法是静态的,所以是属于Test这个类的,test.hello,发挥作用的还是Test.hello(),所以并不会发生空指针异常。
二、构造方法
2.1 定义
构造方法是非常特殊的一类方法,使用关键字new实例化对象实际上就是调用的该类的构造方法。
使用关键字new产生一个对象时,大概分为以下两步:
1.为对象在堆中分配空间。
2.调用对象的构造方法为对象成员变量赋值。
构造方法语法规则
1.方法名与类名称完全相同
2.构造方法没有返回值声明(不是void)
3.一个类至少存在一个构造方法,若没有显示定义,编译器会生成一个默认的无参构造。
无参构造
注意只是new了一个对象,并没有调用该方法。说明当我们new对象时默认产生一个构造方法。
当我们没有定义无参构造时(实质就是给成员变量赋值)
在没有进入无参构造时,成员变量还是默认值
有参构造
调用new Person()中的无参构造时没有定义变量,但是类中只有一个有参构造,所以默认的无参构造没了
2.2构造方法的内存分析
实质就是给成员变量赋值(方便理解)
1.先在堆上开辟一块空间(大小由该类中成员变量的属性决定)
2.调用对象的构造方法为所有成员变量赋值
成员变量的就是构造方法中进行赋值的,还没进入构造方法之前是默认值。
有初值的成员变量同样是在构造方法中赋值。其实new Person()就是调用了一下构造方法。(下图中红色方框内可以理解为一回事)
2.3构造方法重载
定义:构造方法是为了类中的成员变量赋值的,此时的重载只可能是参数的个数不同,不可以是类型不同。
代码如下
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
this.name = "xx";
this.age = 10;
this.sex = "男";
}
//带有3个参数的构造函数
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show