类和对象
一、定义类
- 所谓类,即对象的模板。类通常含有两部分元素,一个是属性(成员变量),一个是方法(成员方法)。
public class Date{
private int day, month, year;
public String formate(){
return year + month + day;
}
}
- 含有
class
关键字的是类头,后面大括号包含的是类体(无需加;作为结尾) class
前的修饰符可以有多个,用来限定类的使用方式。- 权限修饰符一共有3个,可以用来修饰类,也可以用来修饰类中的成员。
- public表示公有,可以被任何对象访问
- protect表示受保护的,只可以被同一个package的类或者子类的实例对象访问;
- private表示私有的,只在类本身访问;
- 默认不写,无修饰符的情况,表示包内可以访问;
类型 | 无修饰符 | private | protected | public |
---|---|---|---|---|
同一类 | 是 | 是 | 是 | 是 |
同一包的子类 | 是 | 否 | 是 | 是 |
同一类的非子类 | 是 | 否 | 是 | 是 |
不同包的子类 | 否 | 否 | 是 | 是 |
不同包的非子 | 否 | 否 | 否 | 是 |
- 类的成员变量可以有多个,变量需要声明其类型。类的成员方法也可以有多个,方法需要声明其返回值类型和参数列表。
二、类的构造方法
- 构造方法是特殊的方法,它必须和类名相同,没有返回值。在new实例化的时候自动调用。
- 可以声明多个同名方法,但定义不同的参数列表,来实现构造方法的重载。
public class Xyz {
int x;
// 默认构造函数
public Xyz() {
this.x = 0;
}
// 不同参数的构造函数
public Xyz(int num) {
this.x = num;
}
}
- 每个类都应该至少定义一个构造方法,用于对成员变量的初始化。如果类没定义构造方法,系统会自动为该类生成默认的构造方法。但方法的参数列表以及方法体都是空的,所实例化对象的各个成员变量也是零或空。
- this关键字用来执行对象自身,除了在构造方法中使用,亦可在成员方法中使用。(当然,不指定this,Java也会从类中寻找成员变量)
三、对象的创建和初始化
- 如上述所说,类的定义,相当于对象的模板。而获取真正的实例对象,要通过模板的实例化来进行,也就是通过
new
关键字来执行对象的创建。 - 值得注意的是,某个类型的变量刚声明之际,只是创建了一个应用,并未分配内存空间。需要用
new
创建对象实例后,才分配响应的内存空间。
// 创建对象实例
private Xyz xyz = new Xyz();
// 访问对象成员
System.out.println(xyz.x);
方法
- 通过成员方法实现对类的操作。比如private的成员变量,外部不能直接访问,只能通过对外暴露的成员方法来访问/操作,这也就是封装的思想。一般来讲,我们也应该尽量把成员变量声明成private的。
- 方法的定义
- 方法名必须是合法的标识符;
- 需要明确方法的返回值,如果无返回值,则应声明成void;
- 方法的修饰符可以含有多个不同的修饰符;
- 方法的参数列表称为形参,每个参数都有类型,参数之间用逗号分隔;
- 用大括号包含起来的是方法体/方法块,里面是实际要执行的代码段。最后一般使用return语句表示方法的结束。
- 方法定义完后,需要进行调用。调用时传递的值称为实参。
- Java实参的赋值是根据数据类型而定的,这点和JavaScript一样,如果是基础数据类型,在方法内对参数的修改不会影响原数据,因为传递时进行了数据的复制。而如果参数是引用,则会影响原数据。
- 与构造方法一样,成员方法也允许进行重载(Overload),即多个方法使相同的方法名,调用时通过参数列表来调用具体的方法。
- 具体通过参数个数、每个参数的类型以及参数的顺序来确定,这称为方法签名
静态成员
- 在类中还可以定义一种特殊的成员,用static修饰的静态成员,或者成为类成员。
- 类是对象的模板,模板是可以互相继承的,静态成员就是为了方便在继承中共享特性和方法
一、静态变量
public class Count {
private int serialNumber;
static int counter = 0;
public Count() {
counter ++;
serialNumber = counter;
}
public int getSerialNumber(){
return serialNumber;
}
}
public class UseCount {
public static void main(String args[]){
System.out.println("Count.counter is:" + Count.counter);
Count one = new Count();
Count two = new Count();
System.out.println("one serialNumber is:" + one.getSerialNumber());
System.out.println("two serialNumber is:" + two.getSerialNumber());
System.out.println("Count.counter is:" + Count.counter);
}
}
输出结果为:
Count.counter is:0
one serialNumber is:1
two serialNumber is:2
Count.counter is:2
- 由于Java中没有全局变量的概念,静态变量从某种意义上讲就是全局变量,只不过是基于继承链上的共享变量
二、静态方法
- 与静态变量类似,使用static可以声明静态方法或者类方法
- 静态方法的调用有两个限制需要注意:
- 静态方法与实例对象无关,所以不存在this值,也就无法使用非静态的变量,只能使用静态变量或方法定义的参数;
- 静态方法不能被重写,也就是说子类中不允许使用相同方法名、相同参数列表的方法;
public class GeneralFunction {
public static int addUp(int num1, int num2){
return num1 + num2;
}
}
public class UserGeneral {
public static void main(String args[]){
int num1 = 5, num2 = 10;
int result = GeneralFunction.addUp(num1, num2);
System.out.println("result:" + result);
}
}
执行结果:result:15
包装类
- Java的数据类型分为基础数据类型和引用数据类型,当我们希望像对象一样操作基础数据类型时,可以把它“包装”为一个对象,Java为几个基本数据类型都提供了对应的包装类
基础数据类型 | 包装类 |
---|---|
byte | Byte |
double | Double |
short | Short |
char | Character |
int | Integer |
boolean | Boolean |
long | Long |
void | Void |
float | Float |
- 基础数据类型的包装类,提供一系列静态方法和静态变量。比如Integer类有MIN_VALUE/MAX_VALUE,表示int型的最小值最大值
- 自动将基础数据类型,转换为对应的包装类的过程,称为自动装箱(Autoboxing),而逆向的操作称为自动拆箱(Unboxing)