在使用类之前,必须先声明它,然后才可以声明变量,并创建对象。
类声明的语法如下:
[标识符] class 类名称
{
//类的成员变量
//类的方法
}
在上面的语法格式中,[标识符] 可以是public、private、protected或者完全省略这个修饰符。
类名称遵循标识符命名规则与规范,这里不再赘述,有兴趣的可以去标识符命名规则与规范看看。
Java提供了一系列的访问控制符来设置基于类(class)、变量(variable)、方法(method)及构造方法(constructor)等不同等级的访问权限。
Java的访问权限主要有4类:
在默认模式下,不需为某个类、方法等不加任何访问修饰符。这类方式声明的方法和类,只允许在同一个包(package)内是可访问的。
这是Java语言中对访问权限控制最严格的修饰符。如果一个方法、变量和构造方法被声明为“私有”访问,那么它仅能在当前声明它的类内部访问。
类和接口(interface)的访问方式是不能被声明为私有的。
这是Java语言中访问权限控制最宽松的修饰符。如果一个类、方法、构造方法和接口等被声明为“公有”访问,那么它不仅可以被跨类访问,而且允许跨包访问。
如果需要访问其他包里的公有成员,则需要事先导入(import)那个包含所需公有类、变量和方法等的那个包。
介于public 和 private 之间的一种访问修饰符。如果一个变量、方法和构造方法在父类中被声明为“保护”访问类型,只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
类和接口(interface)的访问方式是不能声明为保护类型的。
类的标识符除了上述的4个访问控制符,还可以是final。
关键字“final”有“无法改变的”或者“终态的”含义。
一个类一旦被声明为final,那这个final类不能被继承,因此final类的成员方法没有机会被覆盖,默认情况下类都是default的。
在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会再被扩展,那么就设计为final类。
【示例】
class Person
{
String name;
int age;
void talk()
{
System.out.println("我是:"+name+",今年:"+age+"岁");
}
}
在声明一个类后,还需要对类进行定义。
构造方法(constructor,又称构造器或构造函数)、属性和方法是三种最常见的成员
定义类的语法如下:
class 类名称
{
// 定义属性
数据类型 属性; //零到多个属性
// 定义构造函数
类名称(参数,…) //零个到多个构造方法
{
}
// 定义方法
返回值的数据类型 方法名称(参数1,参数2…) //零到多个方法
{
程序语句 ;
return 表达式 ;
}
}
类中各个成员之间,定义的先后顺序没有任何影响。
各成员可相互调用,但值得注意的是,static修饰的成员不能访问没有static修饰的成员。
public class Static {
private int i;
public static void f() {
i++; // 错误,静态方法 f() 无法访问非静态属性 i
}
}
属性用于定义该类或该类的实例所包含的各种数据。
方法则用于定义类中的行为特征或功能实现(即对数据的各种操作)。
构造方法是一种特殊的方法,专用于构造该类的实例(如实例的初始化、分配实例内存空间等),Java语言通过new关键字来调用构造方法,从而返回该类的实例。
定义一个类后,就可以创建类的实例了,创建类实例通过new关键字完成。如下:
public class Static {
private int i; // 属性
public Static() {} // 构造方法
public void f() { //普通方法
i++;
}
public static void main(String[] args) {
Static s = new Static(); // 生成Static类的实例s
System.out.println(s.i);
s.f(); // 调用f()方法,i++
System.out.println(s.i);
}
}
类的基本组成部分包括属性和方法。
类的属性也称为字段、域或成员变量,不过习惯上将它称为属性。类的属性是变量。
定义属性的语法如下:
[修饰符] 属性类型 属性名 [=默认值];
private int age [= 30];
属性语法格式的详细说明如下。
修饰符可省略(省略,即为默认default),也可是访问控制符public、protected、private及static、final。
其中三个访问控制符public、protected和private只能使用其中之一, static和final则可组合起来修饰属性。
属性类型可以是Java允许的任何数据类型,包括基本类型(int、float等)和引用类型(类、数组、接口等)。
属性名遵循标识符命名规则与规范,这里不再赘述,有兴趣的可以去标识符命名规则与规范看看。
定义属性还可以定义一个可选的默认值。
下面通过一个例子来看下属性的使用:
public class usingAttribute {
/* 定义两个静态String属性
* 由于它们是静态的,所以它们是属于类的,
* 也就是这个类定义的所有对象共有的,
* 所有的对象看到的静态属性值都是相同的
*/
static String a="string-a";
static String b;
/* 定义两个非静态的String属性,
* 由于是非静态的,所以它们是属于这个类所定义的对象私有的,
* 每个对象都有这个属性,且它们各自的属性值可不同
*/
String c="stirng-c";
String d;
/* 使用static + {} 括起来的代码称为静态代码块,
* static语句块用于初始化static成员变量,是最先运行的语句块
* 在此用来初始化静态变量b
*/
static
{
System.out.println("static语句块开始执行!");
printStatic("before static");
b="string-b";
printStatic("after static");
}
/* 定义一个构造方法,并用来初始化非静态属性d
* 构造方法的主要目的是创建对象
*/
public usingAttribute() {
System.out.println("构造方法开始执行!");
print("before constructor");
d="string-d";
print("after constructor");
}
/* 定义一个静态方法
* 输出静态成员变量
*/
public static void printStatic(String title) {
System.out.println("---------"+title+"---------");
System.out.println("a=\""+a+"\"");
System.out.println("b=\""+b+"\"");
}
/* 定义一个普通公有的方法
* 打印所有属性,包括静态成员
*/
public void print(String title) {
System.out.println("---------"+title+"---------");
System.out.println("a=\""+a+"\"");
System.out.println("b=\""+b+"\"");
System.out.println("c=\""+c+"\"");
System.out.println("d=\""+d+"\"");
}
// 方法main()
public static void main(String[]args) {
System.out.println();
System.out.println("---------创建usingAttribute对象---------");
System.out.println();
new usingAttribute();
}
}
由输出结果可以看出,Java类属性和对象属性的初始化顺序如下:
⑴ 类属性 (静态变量)定义时的初始化,如范例中的 static String a = “string-a”。
⑵ static 块中的初始化代码,如范例中的 static {} 中的 b = “string-b”。
⑶ 对象属性 (非静态变量) 定义时的初始化,如范例中的 String c = “stirng-c”。
⑷ 构造方法 (函数) 中的初始化代码,如范例构造方法中的 d = “string-d”。
当然这里只是为了演示Java类的属性和对象属性的初始化顺序。在实际的应用中,并不建议在类中定义属性时实施初始化,如例子中的字符串变量“a”和“c”。
注:被static修饰的变量称为类变量(class’s variables),它们被类的实例所共享。也就是说,某一个类的实例改变了这个静态值,其他这个类的实例也会受到影响。
成员变量(member variable)则是没有被static修饰的变量,为实例所私有,也就是说,每个类的实例都有一份自己专属的成员变量,只有当前实例才可更改它们的值。
static是一个特殊的关键字,它不仅用于修饰属性(变量),成员,还可用于修饰类中的方法。被static修饰的方法,同样表明它是属于这个类共有的,而不是属于该类的单个实例,通常把static修饰的方法也称为类方法。