目录

  • Java开发入门
    • ● Java 概述
    • ● JDK的使用
    • ● 系统环境变量
    • ● 第一个Java程序
    • ● Java的运行机制
    • ● 教学设计
    • ● 课程讲义
    • ● 案例学习
    • ● 课后题答案
  • Java 编程基础
    • ● Java的基本语法
      • ● Java代码基本格式
      • ● Java中的注释
      • ● Java中的关键字
      • ● Java中的标识符
    • ● Java中的变量与常量
      • ● 变量的定义
      • ● 变量的数据类型
        • ● 案例导学
      • ● 变量的类型转换
        • ● 案例导学-自动类型转换
        • ● 案例导学-强制类型转换
      • ● 变量的作用域
        • ● 案例导学-作用域
      • ● Java中的常量
    • ● Java中的运算符
      • ● 案例导学-算术运算符
      • ● 案例导学-赋值运算符
      • ● 案例导学-比较运算符
      • ● 案例导学-逻辑运算符
      • ● 案例导学-位运算符
      • ● 案例导学-运算符的优先级
    • ● 选择结构语句
      • ● 案例导学-if条件语句
      • ● 案例导学-switch条件语句
    • ● 循环结构语句
      • ● 案例导学-while循环语句
      • ● 案例导学-for循环语句
      • ● 案例导学-循环嵌套
      • ● 案例导学-break语句
      • ● 案例导学-continue语句
    • ● 数组
      • ● 案例导学-一维数组的定义
      • ● 案例导学-数组最值
      • ● 案例导学-数组排序
    • ● 教学设计
    • ● 课程讲义
    • ● 课后题答案
  • 面向对象(上)
    • ● 面向对象概述
    • ● Java中的类与对象
      • ● 案例导学-类与对象
    • ● 类的封装
    • ● 案例导学-类的封装
    • ● 方法的重载和递归
    • ● 构造方法
      • ● 案例导学-构造方法与重载
    • ● this关键字
      • ● 案例导学-this
    • ● static关键字
      • ● 案例导学-静态变量
      • ● 案例导学-静态方法
      • ● 案例导学-静态代码块
    • ● 教学设计
    • ● 课程讲义
    • ● 章节测试
    • ● 课后题答案
  • 面向对象(下)
    • ● 类的继承
      • ● 案例导学-类的继承
      • ● 案例导学-方法的重写
      • ● 案例导学-super访问父类成员变量
      • ● 案例导学-super访问父类成员方法
      • ● 案例导学-super访问父类构造方法
    • ● final关键字
    • ● 抽象类和接口
    • ● 多态
    • ● 内部类
    • ● JDK8的Lambda表达式
    • ● 异常
    • ● 垃圾回收
    • ● 教学设计
    • ● 课程讲义
    • ● 章节测试
    • ● 课后习题答案
  • Java中的常用类
    • ● String类和StringBuffer类
    • ● System类与Runtime类
    • ● Math类与Random类
    • ● 包装类
    • ● 日期与时间类
    • ● 格式化类
    • ● 课后题答案
    • ● 课程讲义
  • 集合
    • ● 集和概述
    • ● Collection接口
    • ● List接口
      • ● List接口简介
      • ● ArrayList集合
      • ● LinkList集合
    • ● Collection集合遍历
    • ● Set接口
    • ● Map接口
    • ● 泛型
    • ● 常用工具类
      • ● Collections工具类
      • ● Arrays工具类
    • ● 课后题参考答案
    • ● 课程讲义
  • IO流
    • ● I/O流概述
    • ● 字节流
    • ● 字符流
    • ● File类
    • ● RandomAccessFile
    • ● 对象序列化
    • ● NIO
    • ● NIO.2
    • ● 课后题答案
    • ● 课程讲义
    • ● 章节测试
  • GUI(图形用户接口)
    • ● Swing概述
    • ● Swing顶级容器
    • ● 布局管理器
    • ● 事件处理
    • ● Swing常用组件
    • ● Swing组件的整合使用
    • ● JavaFX图形用户界面工具
    • ● 课程讲义
  • JDBC
    • ● 什么是JDBC
    • ● JDBC常用API
    • ● JDBC编程
    • ● 案例-使用JDBC实现QQ登录
    • ● 课程讲义
  • 多线程
    • ● 线程概述
    • ● 线程的创建
    • ● 线程的生命周期及状态转换
    • ● 线程的调度
    • ● 多线程同步
    • ● 多线程通信
    • ● 教学设计
    • ● 课后题参考答案
    • ● 课程讲义
  • 网络编程
    • ● 网络通信协议
    • ● UDP通信
    • ● TCP通信
    • ● 课程讲义
  • Eclipse开发工具
    • ● Eclipse概述
    • ● Eclipse的安装与启动
    • ● Eclipse进行程序开发
    • ● Eclipse程序调试
    • ● 使用Eclipse导出、导入jar文件
  • ACM大赛题库
    • ● 2027
    • ● 2028
    • ● 2024-2026
    • ● 2012-2023
    • ● 2018-2020
    • ● 2015-2017
    • ● 2012-2014
    • ● 2009-2011
    • ● 2003-2005
    • ● 2000-2002
  • PBL学生风采展示
    • ● 实验一
    • ● 实验二
    • ● 实验三
    • ● 实验四
Java中的类与对象
  • 1
  • 2


类与对象时整个面向对象中最基础的组成单元。

:是抽象的概念集合,表示的是一个共性的产物,类之中定义的是属性和行为(方法); 
对象:对象是一种个性的表示,表示一个独立的个体,每个对象拥有自己独立的属性,依靠属性来区分不同对象。

可以一句话来总结出类和对象的区别:类是对象的模板,对象是类的实例。类只有通过对象才可以使用,而在开发之中应该先产生类,之后再产生对象。类不能直接使用,对象是可以直接使用的。

类与对象的定义和使用

在Java中定义类,使用关键字class完成。语法如下:

class 类名称 {
         属性 (变量) ;
         行为 (方法) ;
}1234

范例:定义一个Person类

class Person {     // 类名称首字母大写
    String name ;
    int age ;
    public void tell() {        // 没有static
          System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}1234567

类定义完成之后,肯定无法直接使用。如果要使用,必须依靠对象,那么由于类属于引用数据类型,所以对象的产生格式(两种格式)如下:

(1)格式一:声明并实例化对象

类名称 对象名称 = new 类名称 () ;1

(2)格式二:先声明对象,然后实例化对象:

类名称 对象名称 = null ;
对象名称 = new 类名称 () ;12

引用数据类型与基本数据类型最大的不同在于:引用数据类型需要内存的分配和使用。所以,关键字new的主要功能就是分配内存空间,也就是说,只要使用引用数据类型,就要使用键字new来分配内存空间

当一个实例化对象产生之后,可以按照如下的方式进行类的操作: 
对象.属性:表示调用类之中的属性; 
对象.方法():表示调用类之中的方法。

范例:使用对象操作类

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = new Person() ;// 声明并实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}123456789101112131415161718

运行结果:

姓名:张三,年龄:301

以上完成了一个类和对象的操作关系,下面换另外一个操作来观察一下:

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}12345678910111213141516171819

运行结果:

姓名:张三,年龄:301

那么,问题来了,以上两种不同的实例化方式有什么区别呢? 
我们从内存的角度分析。首先,给出两种内存空间的概念: 
(1)堆内存:保存对象的属性内容。堆内存需要用new关键字来分配空间; 
(2)栈内存:保存的是堆内存的地址(在这里为了分析方便,可以简单理解为栈内存保存的是对象的名字)。

1

任何情况下,只要看见关键字new,都表示要分配新的堆内存空间,一旦堆内存空间分配了,里面就会有类中定义的属性,并且属性内容都是其对应数据类型的默认值。

于是,上面两种对象实例化对象方式内存表示如下: 
这里写图片描述

两种方式的区别在于①②,第一种声明并实例化的方式实际就是①②组合在一起,而第二种先声明然后实例化是把①和②分步骤来。

另外,如果使用了没有实例化的对象,结果如何? 
如下:

class Person { 
    String name ;
    int age ;
    public void get() {
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

public class TestDemo {
        public static void main(String args[]) {
            Person per = null;//声明对象
            //per = new Person() ;//实例化对象
            per.name = "张三" ;//操作属性内容
            per.age = 30 ;//操作属性内容
            per.get() ;//调用类中的get()方法
        }
}12345678910111213141516171819

运行结果:

Exception in thread "main" java.lang.NullPointerException
    at com.wz.classandobj.TestDemo.main(TestDemo.java:15)12

此时,程序只声明了Person对象,但并没有实例化Person对象(只有了栈内存,并没有对应的堆内存空间),则程序在编译的时候不会出现任何的错误,但是在执行的时候出现了上面的错误信息。这个错误信息表示的是“NullPointerException(空指向异常)”,这种异常只要是应用数据类型都有可能出现。

对象引用传递初步分析

引用传递的精髓:同一块堆内存空间,可以同时被多个栈内存所指向,不同的栈可以修改同一块堆内存的内容。

下面通过若干个程序,以及程序的内存分配图,来进行代码的讲解。

我们来看一个范例:

class Person {     
         String name ;
         int age ;
         public void tell() {        
                   System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}
public class TestDemo {
         public static void main(String args[]) {
                   Person per1 = new Person() ;         // 声明并实例化对象
                   per1.name = "张三" ;
                   per1.age = 20 ;
                   Person per2 = per1 ;  // 引用传递
                   per2.name = "李四" ;
                   per1.tell() ;
         }
}1234567891011121314151617

对应的内存分配图如下:

11

再来看另外一个:

class Person {
         String name ;
         int age ;
         public void tell() {
                   System.out.println("姓名:" + name + ",年龄:" + age) ;
         }
}
public class TestDemo {
         public static void main(String args[]) {
                   Person per1 = new Person() ;         // 声明并实例化对象
                   Person per2 = new Person() ;
                   per1.name = "张三" ;
                   per1.age = 20 ;
                   per2.name = "李四" ;
                   per2.age = 30 ;
                   per2 = per1 ;// 引用传递
                   per2.name = "王五" ;
                   per1.tell() ;
         }
}1234567891011121314151617181920

对应的内存分配图如下: 
12

垃圾:指的是在程序开发之中没有任何对象所指向的一块堆内存空间,这块空间就成为垃圾,所有的垃圾将等待GC(垃圾收集器)不定期的进行回收与空间的释放。