类与对象相关语法
字段成员的语法细则
字段初始化
private int hour = 0; // 将钟表的时间初始化为0:0:0
private int minute = 0;
private int second = 0;
空值
字段默认值:
byte/short/int/long: 0
float/double: 0.0
char: ‘\u0000’
boolean: false
引用变量默认值:null
只读字段final
private final int second = 0; // 将字段second定义成只读字段
方法成员的语法细则
方法的4大要素
1.方法名
2.形式参数列表
3.方法体
4.返回值类型
方法签名
返回值类型 方法名(形参列表)
重载方法
public void set( ) // 不带参数的方法set():从键盘输入时间
{
Scanner sc = new Scanner( System.in );
hour = sc.nextInt();
minute = sc.nextInt();
second = sc.nextInt();
}
public void set(int h, int m, int s) // 带参数的方法set():用参数设定时间
{
hour = h;
minute = m;
second = s;
}
类成员访问权限的语法细则
公有权限public
私有权限private
保护权限protected
默认权限(未指定访问权限)
对象的定义与访问
定义对象
1.使用new运算符
2.引用及引用变量:
Clock obj1;
// 预先定义一个Clock类型的引用变量obj1
// 此时obj1的引用值为null,即还未引用任何对象
obj1 = new Clock( );
//上述两条语句可简写为一条语句:
Clock obj1 = new Clock( );
3.注意:"="两边类型应当一致
访问对象
1.成员运算符"."
对象名.字段名
对象名.方法名(实参列表)
2.访问字段与方法
访问钟表对象的 公有成员
Clock obj1 = new Clock( ); // 创建一个钟表对象obj1
obj1.set( ); // 调用对象obj1的公有方法set(),输入时分秒数据
obj1.show( ); // 调用对象obj1的公有方法show(),显示其时间
可以用钟表类Clock定义 多个钟表对象
Clock obj2 = new Clock( ); // 创建第二个钟表对象obj2
obj2.set( 8, 30, 15 );
// 调用对象obj2的公有方法set(),设置时间8:30:15
obj2.show( ); // 调用对象obj2的公有方法show(),显示其时间
一个对象可以被 多次引用
Clock obj ; // 再定义一个Clock类的引用变量obj
obj = obj1;
// 赋值后,obj与obj1引用同一个对象,该对象被引用了2次
obj.set( 12, 0, 0);
// 通过引用变量obj操作钟表对象,将其时间设为12:0:0
obj.show( ); // 显示对象的时间,显示结果应为:12:0:0
obj1.show( );
// 显示obj1所引用对象的时间,显示结果也为:12:0:0
数据类型
基本数据类型
byte、short、int、
long、float、double、
char、boolean
1.Java语言中,使用基本数据类型定义变量,定义时直接为变量分配内存单元
2.后续程序将通过变量名访问变量的内存单元
引用数据类型
类类型、数组类型、接口类型、枚举类型等
1.先定义引用数据类型的引用变量
2.再用运算符new创建引用数据类型的对象,并将所返回的对象引用保存到引用变量中
3.后续程序通过引用变量访问对象及其下属成员
变量及对象的内存分配
栈内存(程序内存):基本数据类型(程序中定义的局部变量)、引用数据类型(对象的定义)
堆内存(系统内存):对象中定义的变量
三种不同的变量
1.字段:定义在类中的变量成员,用于保存属性数据。
字段相当于是类中的全局变量,可以被类中的所有方法成员访问
2.局部变量:类中方法成员在方法体中定义的变量,仅能在所定义的方法体或复合语句中访问
3.形式参数(形参):类中方法成员在头部小括号里面定义的变量,用于接收原始数据。形参仅能在所定义的方法体中访问
注:Java语言中没有全局变量的概念
数据传递
传递基本数据类型数据 时直接传递数值,即值传递。
传递引用数据类型的对象 时所传递的是对象引用(不是对象本身),这被称为是引用传递。
类与对象的编译原理
类代码的编译
public void set( int h, int m, int s )
{
hour = h;
minute = m;
second = s;
}
↓编译后
public void set( Clock this, int h, int m, int s )
{
this.hour = h;
this.minute = m;
this.second = s;
}
————————————————————————————————
public void show( )
{
System.out.println(hour +”:” +minute +”:” +second );
}
↓编译后
public void show( Clock this )
{
System.out.println(this.hour +”:” +this.minute +”:” +this.second );
}
调用对象方法成员语句的编译
Clock obj1 = new Clock( ); // 创建钟表对象obj1
obj1.set( 8, 0, 0 ); // 将obj1的时间设为8:0:0
obj1.show( ); // 显示obj1的时间,显示结果:8:0:0
set( obj1, 8, 0, 0 );
void set(Clock this, int h, int m, int s) { … }
this.hour = h; this.minute = m; this.second = s;
show( obj1 );
同类的多个对象在内存中共用一份方法代码
Clock obj1 = new Clock( ); // 创建钟表对象obj1
Clock obj2 = new Clock( ); // 创建钟表对象obj2
obj1.set( 8, 0, 0 );
obj2.set( 9, 30, 15 );
set( obj1, 8, 0, 0 );
set( obj2, 9, 30, 15 );
void set(Clock this, int h, int m, int s) { … }
1.程序员在编写方法成员代码时,形参this是隐含的,在方法体中访问其他类成员也不需要添加this引用,这些都由编译器在编译时自动添加
2.程序员可以在访问类成员时显式添加“this.”,也可以通过this获取当前对象的引用,或把this作为实参将当前对象的引用继续传递给其他方法
3.程序员还可以利用this来区分与形参或局部变量重名的字段
public void set( int hour, int minute, int s )
{
this.hour = hour; // “this.hour”指代的是字段hour
this.minute = minute; // “this.minute”指代的是字段minute
second = s; // 形参s与字段second不重名,可以不用this
}
类的构造方法
规定:
1.构造方法的名字必须与类名相同
2.构造方法通过形参传递初始值,实现对新建对象字段成员的初始化
3.构造方法可以重载,即定义多个同名的构造方法,这样可以提供多种形式的初始化方法
4.构造方法没有返回值,定义时不能写返回值类型,写void也不行
5.构造方法通常是类外调用,其访问权限不能设为private
格式:
类名( ) { } // 默认构造方法
初始化对象(带形参与无形参的构造方法)
public Clock( int p1, int p2, int p3 ) // 带形参的构造方法
{
hour = p1;
minute = p2;
second = p3;
}
public Clock( ) // 不带形参的构造方法
{
this( 0, 0, 0 ); // 调用本类重载的带形参构造方法(须为第一条语句)
// hour = 0; minute = 0; second = 0; // 或直接赋值
}
Clock obj1 = new Clock( 8, 30, 15 ); // 给了实参,将调用带形参的构造方法
Clock obj2 = new Clock( ); // 未给实参,将调用不带形参的构造方法
Clock obj = obj1; // 未实际创建对象,不会调用构造方法
拷贝构造方法
public Clock( Clock oldObj )
{
hour = oldObj.hour;
minute = oldObj.minute;
second = oldObj.second;
}
Clock obj1 = new Clock( 8, 30, 15 );
Clock obj2 = new Clock( obj1 );
显示对象的创建过程
public Clock( ) // 不带形参的构造方法
{
hour = 0;
minute = 0;
second = 0;
System.out.println( “Clock( ) called.” ); // 添加显示信息的语句
}
public Clock( int p1, int p2, int p3 ) // 带形参的构造方法
{
hour = p1;
minute = p2;
second = p3;
System.out.println( “Clock(int p1, int p2, int p3) called.” ); // 添加显示信息的语句
}
public Clock( Clock oldObj ) // 拷贝构造方法
{
hour = oldObj.hour;
minute = oldObj.minute;
second = oldObj.second;
System.out.println( “Clock( Clock oldObj ) called.” ); // 添加显示信息的语句
}
Clock obj1 = new Clock( ); // 未给实参:Clock( ) called.
Clock obj2 = new Clock( 8, 30, 15 ); // 给3个int型实参:Clock(int p1, int p2, int p3) called.
Clock obj3 = new Clock( obj2 ); // 给1个Clock型实参:Clock( Clock oldObj ) called.
类的静态成员
public class Clock { // 定义钟表类Clock
public static int totalClock = 0; // 定义一个静态字段,记录已创建的Clock对象个数
private static void plusObj( ) { totalClock ++; } // 定义一个静态方法,将计数加1
private int hour, minute, second; // 字段成员
}
Clock c1 = new Clock( ); // 创建第一个对象c1
Clock c2 = new Clock( ); // 创建第二个对象c2
System.out.println( Clock . totalClock ); // 通过类名访问静态成员totalClock
System.out.println( c1 . totalClock ); // 或通过任一对象引用(c1或c2)访问静态成员
System.out.println( c2 . totalClock );
静态变量详解析
Java语言不允许在类外定义全局变量或函数
1.关键字static:在类中定义静态字段需使用关键字static进行限定,通常放在访问权限之后,数据类型之前。定义静态字段时可以初始化
2.在本类访问静态字段:在本类的方法成员中访问静态字段,直接使用字段名访问,访问时不受权限约束。这一点与访问普通字段是一样的
3.不能通过this访问静态字段:静态字段是类字段,没有包含在对象中,因此不能使用关键字this访问静态字段。这一点与访问普通字段是不一样的。注:this是指向当前对象的引用变量
4.在类外访问静态字段:在类外其他方法(例如主方法)中访问静态字段需以“类名.静态字段名”的形式访问,或通过任何一个该类对象引用以“对象引用名.静态字段名”的形式访问。类外访问静态字段受权限约束。在类外访问静态字段时可以不创建对象,直接通过类名访问Clock. totalClock
5.静态方法访问本类其他成员:静态方法只能访问本类中的静态字段,不能访问实例字段,因为静态方法可以在没有创建任何对象的情况下直接调用,而实例字段必须在对象创建之后才会分配内存空间,因而不能访问。静态方法只能调用本类中的其他静态方法,不能调用实例方法,因为实例方法可能会间接访问实例字段
静态成员的应用
1.以类的形式管理全局变量或外部函数
2.将具有相同属性值的字段提炼出来,定义成静态字段,这样可以让所有对象共用同一个静态字段,从而减少内存占用。
3.将专门处理静态字段的方法定义成静态方法
public class MathTest { // 测试类:测试Java语言中数学类Math的静态成员
public static void main(String[] args) { // 主方法
System.out.println( "random()= " +Math.random() ); // 随机数函数(静态方法)
System.out.println( "random()= " +Math.random() );
System.out.println( "sqrt(36)= " +Math.sqrt(36) ); // 求平方根函数(静态方法)
System.out.println( "sin(30)= " +Math.sin(30 *Math.PI/180) ); // 正弦函数(静态方法) }
}
}