定义和使用类
Java中所有代码都必须是类的一部分, 大部分代码都是在方法中编写的
错误示范
|
|
如果我们运行以上代码, 会收到报错:
|
|
- 定义的
Dog
类并不执行任何操作, 只是定义了Dog
的一些功能 - 要运行该类, 需要添加一个
Main
方法, 来运行Dog
中的方法
修正后
我们通过创建一个单独的 DogLaucher
来运行 Dog
中的方法
|
|
|
|
- 使用另一个的类有时被称为它的客户端(client)
- 即
DogLauncher
是Dog
的客户端
- 即
实例变量与对象实例化
当 Dog 类需要向下细分时, 我们不需要从头编写一些重复的代码, 而是可以选择通过继承+修改等方式, 实现新的类
创建单独的类别
|
|
创建 Dog 类实例
|
|
这里我们给 Dog
类定义一个属性, 是其体重
然后根据不同的体重, 决定其不同的行为
|
|
这里, 我们将 Dog
类实例化, 得到一个实例
并为 d
的属性赋值, 然后观察其执行的行为
- Java 中的
Object
是任何类的实例 Dog
类有自己的变量,也称为实例变量或非静态变量 。这些必须在类内声明- 我们在
Dog
类中创建的方法没有static
关键字。我们将此类方法称为实例方法或非静态方法 - 要调用
makeNoise
方法,我们必须首先使用new
关键字实例化Dog
,然后制作特定的Dog
吠叫- 我们调用了
d.makeNoise()
而不是Dog.makeNoise()
- 我们调用了
- 一旦对象被实例化,就可以将其分配给适当类型的声明变量
- 例如
d = new Dog();
- 例如
- 类的变量和方法也称为类的成员(members)
- 使用点表示法访问类的成员
我的问题: 为什么感觉 d 被定义了两遍
我觉得
Dog d;
和d = new Dog();
都是在定义 d
这涉及到 java 中对象和引用的区别
Dog d;
这句话的意思是:
- 定义了一个 变量
d
,类型是Dog
- 但是此时
d
只是一个引用(reference),它还没有指向任何对象 - 就像是声明了“我有一只狗的指针”,但实际还没给它拴上一只真正的狗
如果你此时直接写d.makeNoise();
,会报错NullPointerException
,因为d
还没有指向任何对象。
2. d = new Dog();
这句话才是 真正创建了一只狗(在堆里 new 出一个 Dog
对象),然后让 d
指向它
new Dog()
会在内存里开辟空间,构造一只狗对象d = ...
是把这个对象的地址赋值给d
- 之后你就可以通过
d
来访问这只狗,比如d.weightInPounds = 20;
- 合并写法
上面两步经常合并成一步:
Dog d = new Dog();
等价于:
Dog d; d = new Dog();
在 Java 中构造函数
|
|
这里, 实例化是参数化的(实例化过程中直接传入参数), 能够节省一些赋值时的混乱
但如果想这样做, 需要在 Dog
类中添加一个构造函数
|
|
- 每当我们尝试使用
new
关键字和单个整数参数创建Dog
时,都会调用具有签名public Dog(int w)
的构造函数 - 和 python 中的
__init__
方法非常相似
关于构造函数
- 构造函数必须和类名完全相同(包括大小写)
- 构造函数不能有返回类型, 连 void 都不行
- 构造函数可以有多个(重载)
- 如果不写构造函数, java 会自动生成一个无参构造函数
非静态的方法
这里的 makeNoise 在定义的时候并没有加 static, 也就是这个并不是一个静态方法
这种也被称为实例方法
通俗来讲, 如果一个方法需要调用一个实例的变量, 那这个方法必须是非静态的
数组实例化, 对象数组
数组实例化
|
|
这里数组也是用 new
这个关键字进行实例化的
对象的数组
|
|
new 有两种不同的使用方式:
- 一次创建可以容纳两个
Dog
对象的数组 - 第二次创建每个实际
的 Dog
类方法与实例方法
Java 允许定义两种类型的方法:
- 类方法, 又称为静态方法
- 类本身执行的操作
- 实例方法, 又称为非静态方法
- 只能由类的特定实例执行的操作
举例与比较
现在有一个 Math 类, 其提供一个 sqrt 方法
若 sqrt 是静态的:
|
|
若 sqrt 是非静态的:
|
|
同时具有实例和静态方法
当我们想比较两只狗的能力时, 可以添加一个静态方法:
|
|
然后通过以下方法调用:
|
|
因为我们使用类名调用, 因此这个方法是一个静态方法
实现成一个功能相同的非静态方法:
|
|
通过调用实例来调用此方法:
|
|
静态变量
- 静态变量是类本身固有的属性
- 静态变量通过类名, 而非特定实例来访问
|
|
Dog.binomen
public static void main(String[] args)
用于 main 方法的声明:
public
:到目前为止,我们所有的方法都以这个关键字开头static
:它是一个静态方法,不与任何特定实例相关联void
:它没有返回类型main
:这是方法的名称String[] args
:这是传递给 main 方法的参数
命令行参数
由于 main 是由 Java 解释器本身而不是另一个 Java 类调用的,因此解释器的工作是提供这些参数。它们通常引用命令行参数
|
|
|
|