类与对象

  • 类与对象是整个面向对象之中最为基础的组成单元;类是共性的集合,对象是个性的产物。
    所有的类都是用来描述出对象的结构,例如:每一个人的的姓名、年龄、身高等等
  • 类是不能直接使用的,对象是可以直接使用的,对象是通过类产生的。

类与对象的基本定义

  1. 如果要在成语之中定义类可以使用"class 类名称{}"的语法结构,而类之中的组成主要有两点:
  • Field(属性、成员、变量),也就是一堆变量的集合
  • Method(方法、行为) ,之前定义的方法,但此时的方法是由对象调用的
class Book{   //定义 一个新的类
   String title ;   //书的名字
   double price ;  //书的价格
   public void getInfo(){  //此方法由对象调用
     System.out.println(title + price);
  }
}

这个类里面定义了两个属性,一个方法;
类虽然已经产生了,但是如果要使用类,必须要有对象,对象的定义格式有个两种:

  • 声明并实例化对象:
    类名称 对象名称 = new 类名称();
  • 分步定义:
    • 声明对象:类名称 对象名称 = null ;
    • 实例化对象: 对象名称 = new 类名称();

引用数据类型与基本数据类型最大的不同在于需要内存的创建与使用,所以关键字 new 的主要功能就是创建内存空间,即:只要是引用数据类型的使用,就必须使用关键字 new 来创建内存空间。

当一个对象实例化之后就可以安装如下的方式利用对象来操作类的结构:

  • 对象.属性:表示要操作类中的属性内容;
  • 对象.方法(): 表示要调用类中的方法;

范例:使用类 -- 在主类中使用Book类

class Book{
    String title ;
    double price ;
    public void getInfo() {
        System.out.println("Title: " + title + "; Price: " + price);
    }
}


public class TestDemo {
    public static void main(String[] args) {
        Book bk = new Book(); //声明并实例化对象
        bk.title = "Java"; //操作属性内容
        bk.price = 98.9; //操作属性内容
        bk.getInfo(); //调用类中的getInfo()方法
    }
}

两块内存空间的概念:

  • 堆内存:保存每一个对象的属性内容,堆内存需要用关键字new才可以创建;
  • 栈内存:保存的是一块堆内存的地址,但为了分析方便,可以简单的理解为栈内存保存的是雕像的名字。


    类与对象
    声明并实例化对象_内存分析图
class Book{
    String title ;
    double price ;
    public void getInfo() {
        System.out.println("Title: " + title + "; Price: " + price);
    }
}


public class TestDemo {
    public static void main(String[] args) {
        Book bk = null; //声明对象
        bk = new Book(); //实例化对象(创建了堆内存)
        bk.title = "Java"; //操作属性内容
        bk.price = 98.9; //操作属性内容
        bk.getInfo(); //调用类中的getInfo()方法
    }
}

分布定义和之前的声明并实例化对象的结果没有区别,但是通过内存来分析
任何情况下只要看到关键字new,都表示要创建新的堆内存空间,一旦堆内存空间创建了,里面就一定会有所有类中定义的属性,当然所有的属性内容都是其对应数据类型的默认值。


类与对象
分布定义_内存分析图

以上代码是分两布实现了对象的实例化(创建了堆内存的对象称为实例化对象),那么使用没有实例化的对象会出现什么现象呢?

public class TestDemo {
    public static void main(String[] args) {
        Book bk = null; //声明对象
        //bk = new Book(); //实例化对象(创建了堆内存)
        bk.title = "Java"; //操作属性内容
        bk.price = 98.9; //操作属性内容
        bk.getInfo(); //调用类中的getInfo()方法
    }
}

此时由于使用了没有实例化的Book类对象,所以程序在运行的时候出现了"NullPointerExcepption"(空指针异常),此类异常只要是引用数据类型都有可能出现。

引用数据的初步分析

引用是整个Java开发只用的核心精髓,在所有的引用分析里面,最关键是new关键字,一定要注意,每一次使用new都一定会创建新的堆内存空间,如果代码里面声明两个对象,并且使用了new分别为两个对象进行实例化操作,那么一定是各自占有各自的内存空间,并且互不影响。

public class TestDemo {
    public static void main(String[] args) {
        Book bookA = new Book(); //声明并实例化对象
        Book bookB = null; //声明对象
        bookA.title = "Java"; //操作属性内容
        bookA.price = 89.8; //操作属性内容
        bookB = bookA;  //引用传递
        bookB.price = 69.8; 
        bookA.getInfo(); //调用类中的getInfo()方法
    }
}

严格来讲bookA 和 bookB里面保存的是对象的地址信息,所以上面的引用过程就属于将bookA的地址传递给了bookB。


类与对象
内存地址传递

由于此时两个对象指向的是同一块堆内存空间,所以任何一个对象修改了堆内存中的数据后,都会影响到其它对象。在引用的操作过程中,一块堆内存可以同时被多个栈内存所指向,但一筐栈内存只能保存一块堆内存的地址。

范例:垃圾产生

class Book{
    String title;
    double price;
    public void getInfo() {
        System.out.println("Title: " + title + "; Price: " + price);
    }
}


public class TestDemo {
    public static void main(String[] args) {
        Book bookA = new Book(); //声明并实例化对象
        Book bookB = new Book(); //声明并实例化对象
        bookA.title = "Java"; //操作属性内容
        bookA.price = 89.8; //操作属性内容
        
        bookB.title = "JSP"; //操作属性内容
        bookB.price = 69.8; //操作属性内容
        bookB = bookA;  //引用传递
        bookB.price = 100.1; 
        bookA.getInfo(); //调用类中的getInfo()方法
    }
}
类与对象
垃圾产生

通过内存分析发现,在引用数据类型关系里面,一块没有任何栈内存指向的堆内存空间就将成为垃圾,所有的垃圾会不定期的被垃圾收集器(GC)回收,回收之后会释放掉其占用的内存空间。

总结

  1. 类描述的是公共特征,类必须通过对象才可以使用;
  2. 声明对象指的是未创建堆内存的对象,如果直接使用此对象会出现"NullPointerExcepption"异常;对象可以通过关键字new来进行堆内存空间的创建,有了堆内存引用的对象才成为实例化对象;
  3. 堆内存保存的是对象中所有属性的内容,而栈内存保存的是堆内存的地址数值
  4. 垃圾空间指的是没有任何栈内存指向的堆内存空间,会被GC不定期回收;
  5. 要熟练掌握内存图的分析方法。