1. 概述
△Java语言就是基于类的语言,许多术语与C++稍有区别
C++ | Java |
---|---|
函数 | 方法 |
构造函数 | 构造器 |
析构函数 | 析构器 |
类中的数据 | 实例域 |
静态数据 | 静态域 |
例如
String a;
C++ 称String
为类,而a
为对象,C++ 在此时就分配了内存,构建了对象
Java 称String
为类,a
为引用,而当使用new
请求,分配了空间,构建出的数据块称为对象
类对象必须使用new来构建,单纯的声明类仅仅只是声明了类的引用,并没有分配空间
2. 自定义类
一个源文件只能拥有一个
public
类,且必须与文件名一致通过在类的
class
前缀上public
获得这一特性包含
main()
方法的类才能成为启动类,每个类都可以拥有main()
方法
通常用作类的普通测试Java不支持析构函数,反之,会自动进行垃圾回收
所有的方法都要在类的内部进行定义
实际上,任何一个Java程序都是从类开始的
如果需要返回一个可变对象的引用,应该对其进行克隆(clone)
※这是由于变量都是一个指向对象的“类似指针的”引用,有可能会使得数据封装性遭到破坏
final
修饰符在使用时大多应用于不可修改的类,当应用在可变的类的时候,并不意味着类的内容不可修改1
2
3
4
5
6
7
8
9
10
11class Employee
{
private final String name;
private final Date hiredate: 2017-03-16
}
/**
* 此时,name引用和对象都不能被修改【String类是不可变的类】
* hiredate: 2017-03-16
* 这里的hiredate: 2017-03-16
*/-
通过
static
声明静态域和静态方法
-
静态域和 C++ 类中的静态变量没有什么区别
-
静态公有常量可以通过类名来直接调用,由于有
final
限制,所以不会造成封装性破坏如Math.PI就是一个静态公有变量
其实也可以通过对象引用来调用,不过一般通过类名调用使得易读性更强
静态方法可以通过类名和对象引用直接调用,但一般使用类名调用增强易读性
如 Math.pow(x,y) -
静态方法只能对对象静态域实施操作,而不能对实例域实施操作
-
通常只有在接受外来参数和调用静态域的时候才使用静态方法
-
对象的构造
-
可以直接在构造器内初始化实例域,即使是包含关系
-
通过使用this来实现传参和实例域同名,甚至调用另一个构造器
1
2
3
4
5
6
7
8
9
10
11public Class(String name, double salary)
{
this.name = name;
this.salary = salary;
}
public Class(double s)
{
this("Class * " + nextId, s);
nextId++;
} -
默认将所有数值初始化为0,布尔值初始化为false,引用初始化为null
如果没有提供显式构造器,则系统自动生成隐式(无参)构造器完成上述工作
如果提供了显式构造器,则系统将不再自动生成无参构造器,上述操作将被视为非法
-
初始化块
※这个不常用,通常使用构造器完成工作
可以使用一个代码块对实例域进行初始化操作1
2
3
4
5
6
7
8
9
10class Class
{
private int id;
....
{
id = 1;
}
}初始化块在所有构造器执行之前执行。
通过标记关键字static可以对静态域进行初始化块操作1
2
3
4static
{
id = 1;
}
-
-
类的基本结构
- 数据域
- 构造器(constructor)
- 访问器(getter)
- 更改器(setter)
3. 方法参数
-
Java总是按值传参,对象引用也是一个值
-
方法不能修改传递给它的实参
-
方法可以通过调用传入对象引用的对象的方法,实现对对象的修改
-
方法不能让对象参数引用一个新的对象
-
方法能够直接访问和修改相同类作为参数的对象实例的私有域
1
2
3
4
5
6
7class Foo {
private String text;
public void doStuff(Foo f) {
System.out.println(f.text);
}
}
4. 包(package
)
※类似于C++的名称空间
-
通过import语句来导入Java包
-
添加static指令可以直接导入静态方法和静态域,使用的时候就无需使用类名来调用【UnRecommended】
-
通过使用包名来具体访问一个类
-
通过package语句来将类放入包中,通常在开头加入
1
package com.myapp.corejava;
注意包名的命名要与目录树相匹配,即上述类文件必须位于
com/myapp/corejava
中,否则,最终的程序将无法运行 -
包作用域
-
如果实例域没有指定访问控制符,则这一个部分可以被同一个包的所有方法访问
在编写类的时候,必须为实例域添加上访问控制符
-
-
类路径(※好像只有使用Shell编译才会遇到这个问题?)
-
javadoc文档注释
- 以
/**
开头,以*/
结尾 - 可以使用
HTML
修饰符 - 还有各种注释,这里不一一说明
- 以
5. 类设计技巧
-
保证数据私有
-
一定要对数据初始化,可以直接提供默认值,也可以在构造器中提供
-
不要在类中使用过多的基本类型,可以通过一个封装类来减少使用
1
2
3private String street;
private String city;
private String state;这个可以通过一个
Address
类来解决 -
并不是所有的数据都需要访问器和更改器
-
将职责过多的类进行分解
如果一个类能被拆分成两个或者多个独立的概念,那就进行拆分
注意这里是概念的拆分,而不是单纯将方法拆分 -
类名和方法名要能够体现它们的职责
类名常用一个名词或者有定语修饰的名词
访问器使用小写的get开头
更改器使用小写的set开头