java04 对象与类
对象的两大属性
-
特征(域)
-
动作(方法)
例如,一辆车可以有以下特征:
有颜色,轮胎数量,方向盘数量,阀门数量等等。
可以有以下几种动作:
行驶和刹车
类
如何创建对象?需要模板,这个模板就是类。如果你有Car类,就可以创建数个Car对象。一个类有什么域和方法,他的对象就有什么域和方法,不多不少。
类的组成
类由三部分组成:类名
、域
、方法
。
类的基本结构
域
域就是一些变量,这些变量 可以是基本数据类型,也可以是引用类型。域的名称一般采用驼峰命名
方式。
引用Address
方法
方法包括方法声明
和方法体
两部分。
方法声明包括,返回值类型
,方法名
,参数列表
。
方法的返回值可以是基本数据类型
、引用类型
或void
.
方法体是方法的具体内容。
方法的定义:
带返回值的方法:
带参数和返回值的方法:
不定个数参数方法:
使用…表示不定个数参数
构造器
构造器是用于生产对象的方法,每个类需要包含至少一个构造器。这个方法结构:
构造器的参数可以 有多个,也可以一个没有。构造器的参数用于初始化对象的域。
有参构造函数存在时,编译器不会自动添加无参构造函数,若没有构造函数,则默认添加一个无参构造函数。
类的UML表示方法
域采用名称+类型的方式表示,方法采用名称和参数列表+返回值类型的方式表示。
创建对象
如何创建对象?有了模板,就可以根据模板创建对象了:
我们可以使用一个变量来引用这个对象(类型要一致):
有了对象,就可以调用类的方法和域了:
对象创建内部操作:
对象的引用:
多个变量引用同一个对象
Null
创建一个全局的对象的变量,而没有赋值初始化的时候,他默认是null:
局部变量需要手动赋初值,否则出现编译错误:
对于空对象,你是无法访问它的域或者方法的:
需要在调用前做好判断:
内存分配
程序运行时,分为两个部分存储:栈和堆。
基本数据类型
的变量空间分配在栈
空间上,引用类型
变量空间分配在堆
内存。
定义一个引用变量,对象的数据
存储在堆
空间,对象的引用地址
存储在栈
空间上。
同一个对象,可以被多个变量引用
:
这个时候,两个变量引用的是同一个对象:
若分别创建对象,则引用的是不同的对象:
现在存在两个对象:
Java包
Java的包主要用于将功能模块进行划分,便于区别和管理。同时,不同的包的类名不会发生冲突。
包的定义:
使用package+包名将类包含在指定的包内。包名通常以域名倒置开始。
类的全限定名称:
包名 + 类名
com.brainysoftware.common.MathUtil
在包含在包内的类的编译、运行,需要使用全限定名称:
运行
类的访问修饰符
类的访问修饰符:public
和default
public类在任何位置
都可以访问:
没有访问修饰符就是default:
只有在相同的包内
才可以访问。
类成员访问修饰符
类成员修饰符,指的是对域
、方法
、构造器
的修饰符,包括public
、private
、protected
、default
四种。
public在任意
位置都可以访问
private只有类内
可以访问
default可以在包内
,类内
访问
protected可以在包内
,类内
,子类
访问
UML的表示方法
public使用+
private使用-
protected使用#
default没有标记
this关键词
this可以调用本类的域或方法:
使用this可以明确是域还是参数,避免混淆。
使用其他类
使用其他类,如果是相同的包内,可以直接使用,不同的包的时候需要导包:
导包语句需要在类声明之前,在package之后。
一次性导入同一个包下的多个类时,使用*
:
不导包,可以使用全限定名称
代替:
当出现引用不同的包出现类名冲突
时,需要使用全限定名称。
常量
常量使用final定义,可以是局部常量也可以是全局常量:
一旦赋值,将不可再赋值,否则会编译失败。
静态成员
类似于System.out,类的静态成员可以在不创建实例
的情况下直接通过类名
调用。那么,入口函数,main方法就是在未创建任何实例之前,直接执行的方法。
静态成员的定义使用static关键字,与访问修饰符顺序可变:
也可以定义一个静态方法:
调用时,直接使用类名调用:
在静态方法中,只能调用静态方法
和静态域
,不可以调用实例方法
和实例域
。
静态对象可以创建,一般用于共享同一个对象。
UML表示法
在uml中,使用下划线表示静态方法:
静态常量
静态常量常用于存储数据,一般可以用枚举代替
静态常引用:
它的引用地址不能再发生变化,它的域值可以改变。
值可以变:
方法重载
两个方法功能类似,方法名称相同,参数列表不同,可以构成重载:
如果仅返回值不同,不构成重载:
值引用&地址引用
基本类型的变量和引用类型变量均可以传递给方法作为参数使用,区别是基本类型的变量传递给函数时,jvm会拷贝
一份给函数,而不是变量本身。引用类型传递的是地址
,函数操作了引用变量的域后,原来变量也会随之改变。
类的加载、链接、初始化
加载:
当你使用命令运行程序时,jvm首先加载class文件到内存中,并进行缓存。若找不到class,将抛出异常。
链接:
链接阶段有三个步骤:验证、准备、处理。
验证阶段主要是对class文件的有效性进行验证。
准备阶段为静态变量分配内存,准备运行class所需要的其他数据结构。
处理阶段主要对运行类文件所需的其他类或接口进行查找和处理。
初始化:
类的初始化优先初始化父类,对静态变量进行赋值,没有赋值语句的赋默认值。
静态代码块也会依次执行:
类的初始化
-
为对象分配内存,包含自身的域和父类的域。
-
调用构造器。为构造器的参数分配空间,赋值。
-
如果引用其他构造器,将调用其他构造器。
-
实例初始化及实例域初始化。
-
返回实例的引用。
实例的比较
两个实例使用==比较,对于引用类型比较的是地址
,对于基本数据类型比较的是值
,这个需要注意区分。如果想改变默认的比较方式,需要重写equals
方法和hashCode
方法。
垃圾回收
对于不再有引用的变量,或超出变量域作用范围的,将由垃圾回收机自动回收内存。
内部类
非静态内部类
非静态内部类可以访问外部类的所有字段和方法
,而静态内部类只能直接使用静态方法和静态字段
,对实例字段和方法需要通过外部类的对象
调用。
外部类不能直接访问内部类的方法和字段!