第7章 Java类的特性 教学内容: 类的私有成员与公共成员 方法的重载 构造方法 实例成员与静态成员 重点: 重载 难点: 静态成员 Windows98 第7章 Java类的特性 教学内容: 类的私有成员与公共成员 方法的重载 构造方法 实例成员与静态成员 重点: 重载 难点: 静态成员 学时:6 汕头大学计算机教学中心
7.1 类的私有成员与公共成员 7.1.1 私有成员 保护成员变量不会被任意改变。 仅供自己使用,黑盒子。 7.1.2 公共成员 Windows98 7.1 类的私有成员与公共成员 7.1.1 私有成员 保护成员变量不会被任意改变。 仅供自己使用,黑盒子。 7.1.2 公共成员 可以被所有类使用,透明。 7.1.3 友元 访问控制符friendly ,可以省略。 同一包中可以访问。 汕头大学计算机教学中心
public String no,name,sex; public int age; void disp(){ Windows98 class Student { public String no,name,sex; public int age; void disp(){ System.out.print(no+“ ”+name+“ ”+sex+ “ ”+age); } public class app1{ public static void main(String args[]){ Student s1 = new Stuednt(); s1.no=“9801”; s1.name = “张三”; s1.sex=“男”; s1.age = -8; //值被更改,不能控制值的范围 s1.disp(); 汕头大学计算机教学中心
private String no,name,sex; private int age; class Student { //私有成员 private String no,name,sex; private int age; void set(String pno,String pname,String psex,int page){ no = pno; name=pname ; sex=psex; if (page>0 && page<=60) age=page; else age=0; } void disp(){ System.out.print(no+“ ”+name+“ ”+sex+ “ ”+age); } public class app1{ public static void main(String args[]){ Student s1 = new Stuednt(); s1.set(“9801”,“张三”,“男”,-8 ); s1.disp(); } Windows98 汕头大学计算机教学中心
private String no,name,sex; private int age; void setAge(int page){ class Student { //私有成员 private String no,name,sex; private int age; void setAge(int page){ if (page>0 && page<=60) age=page; else age=0; } int getAge () { … } } public class app1{ public static void main(String args[]){ Student s1 = new Stuednt(); s1.setAge(20); System.out.print( s1.getAge() ); } Windows98 汕头大学计算机教学中心
Windows98 7.1.3 友元 若在类成员的前面加上访问控制符friendly,说明该成员是友元。 汕头大学计算机教学中心
7.2 方法的重载 方法的重载中参数的类型是关键。 1 方法名相同 2 参数个数不同 或者 参数类型不同 或者 参数的顺序不同。 Windows98 7.2 方法的重载 方法的重载中参数的类型是关键。 1 方法名相同 2 参数个数不同 或者 参数类型不同 或者 参数的顺序不同。 注意:与返回值无关。 汕头大学计算机教学中心
double add (double x,double y) { return (x+y); } Windows98 class overloadDemo { int add (int x,int y){ return (x+y) ; } double add (double x,double y) { return (x+y); } public static void main(String args[]){ int a1=10,b1=2; double a2=9.43,b2=2.34 ; System.out.println( add(a1,b1) ); System.out.println( add(a2,b2) ); } 汕头大学计算机教学中心
class A { int x,y; void set (int i , int j){ x=i; y = j; } Windows98 class A { int x,y; void set (int i , int j){ x=i; y = j; } void set( int i){ x=i; y=0; } void set(){ x=0;y=0;} } 汕头大学计算机教学中心
double add ( int i , int j){ double d; d = 3.14 * (i + j) ; } } Windows98 class A { //改错1 int x , y; void set (int i,int j){ x=i; y = j; } void set( int m , int n){ x=m; y=n } } class A { //改错2 int add (int i , int j){ return ( i + j ) ; } double add ( int i , int j){ double d; d = 3.14 * (i + j) ; } } class A { //改错3 int no ; String name; void set (int pno , String pname){ no=pno; name = pname; } int set(String pname, int pno ){ no=pno; name = pname; return (pno) ; } } 汕头大学计算机教学中心
class Cylinder { //app7_3.java 方法的重载 private double radius; Windows98 class Cylinder { //app7_3.java 方法的重载 private double radius; private int height; private double pi=3.14; private String color; public double SetCylinder(double r, int h) { radius=r; height=h; return r + h ; } public void SetCylinder(String str) { color=str; } public void show( ) { System.out.println("圆柱的颜色为:"+color); } double area() { return pi* radius* radius; } double volume() { return area()*height; } } 汕头大学计算机教学中心
public static void main(String args[ ]) { double r_h; Windows98 public class app7_3 { public static void main(String args[ ]) { double r_h; Cylinder volu = new Cylinder(); r_h = volu.SetCylinder(2.5 , 5 ); volu.SetCylinder(“红色”); System.out.println("圆柱底和高之和="+r_h); System.out.println("圆柱体体积="+volu.volume()); volu.show(); } } 汕头大学计算机教学中心
当传入的参数为一个整数,则返回此数的阶乘。 当传入的参数为两个整数,则返回两数之和。 当传入的参数为两个float型,则返回两数的乘积。 Windows98 重载练习: 1 编写方法 proc , 当传入的参数为一个整数,则返回此数的阶乘。 当传入的参数为两个整数,则返回两数之和。 当传入的参数为两个float型,则返回两数的乘积。 写出主函数,测试。 汕头大学计算机教学中心
7.3 构造方法 int a ; a = 3; 或: int a = 3; class A{ int x; Windows98 7.3 构造方法 int a ; a = 3; 或: int a = 3; class A{ int x; void set( int d } { x = d;} public static void main()(String args[]) { A a1 = new A(); a1.set( 9); } 能否: A a1 = new A(9) ; 汕头大学计算机教学中心
public class TDate { //如何建对象时 同时初始化? private int year =1900 Windows98 public class TDate { //如何建对象时 同时初始化? private int year =1900 private month , day ; public setDate(int yy, int mm, int dd){ year = yy;month=mm;day=dd; } public int getYear(){ return year; } public void print(){ System.out.print(year+”/”+month+”/”+day); } public static void main(String atgs[ ] ) { TDate d1 = new TDate( ) ; //对象数据成员值? d1.setDate ( 2010,4,10); 汕头大学计算机教学中心
class Cylinder { //app7_4.java 构造方法的使用 private double radius; Windows98 class Cylinder { //app7_4.java 构造方法的使用 private double radius; private int height; private double pi=3.14; public Cylinder(double r, int h) { //定义构造方法 radius=r; height=h; } double area() { return pi* radius* radius; } double volume( ) { return area()*height ; } } public class app7_4 { public static void main(String args[ ]) { Cylinder volu=new Cylinder(3.5, 8); //创建对象 并调用构造方法 System.out.println("圆柱底积="+ volu.area()); System.out.println("圆柱体体积="+volu.volume()); } } 汕头大学计算机教学中心
7.3.1 构造方法的作用与定义 (1)构造方法的方法名与类名相同 (2)构造方法没有返回值,也不能写void Windows98 7.3.1 构造方法的作用与定义 (1)构造方法的方法名与类名相同 (2)构造方法没有返回值,也不能写void (3)构造方法的作用是完成对类对象的初始化 (4)在创建一个类的对象的同时,系统会自动调用该类的构造方法为新对象初始化。 (5)构造方法一般不能由编程人员显式地直接调用,而是用new来调用; 汕头大学计算机教学中心
class A{ int x; void set( int d } { x = d;} public static void main()(String args[]) { A a1 = new A(); a1.set( 9); } } class A{ int x; A ( int d } { x = d;} public static void main()(String args[]) { A a1 = new A(9 ); }
public class TDate { //如何建对象时 同时初始化? private int year =1900 Windows98 public class TDate { //如何建对象时 同时初始化? private int year =1900 private month , day ; //public setDate(int yy, int mm, int dd){ TDate(int yy, int mm, int dd){ year = yy;month=mm;day=dd; } public int getYear(){ return year; } public void print(){ System.out.print(year+”/”+month+”/”+day); } public static void main(String atgs[ ] ) { TDate d1 = new TDate( 2010,4,10); d1.print(); 汕头大学计算机教学中心
7.3.2 默认的构造方法 默认的构造方法没有参数,在其方法体中也没有任何代码,即什么也不做。 class A{ Windows98 7.3.2 默认的构造方法 默认的构造方法没有参数,在其方法体中也没有任何代码,即什么也不做。 class A{ private int x; void show(){ Syetem.out.print(x); } 有构造函数吗? 有默认构造函数 A( ) { } 汕头大学计算机教学中心
结论:1 类没有写构造方法,则系统自动加一个默认构造方法。 2 类中有构造方法,则系统不再自动加默认构造方法。 3 类一定有一个构造方法。 Windows98 class A{ private int x; A( ) { } void show(){ Syetem.out.print(x); } 结论:1 类没有写构造方法,则系统自动加一个默认构造方法。 2 类中有构造方法,则系统不再自动加默认构造方法。 3 类一定有一个构造方法。 汕头大学计算机教学中心
练习 class A{ public int x,y; A(int i,int j ){x =i; y=j;} void show(){ Windows98 练习 class A{ public int x,y; A(int i,int j ){x =i; y=j;} void show(){ Syetem.out.print(x+” “+y); } class B{ public int x,y; void show(){ Syetem.out.print(x+” “+y); } } 问题1: 类B有构造函数吗? 2: 类A有 A(){ } 吗? 汕头大学计算机教学中心
7.3.3 构造方法的重载 class A{ public int x,y; A( ) {x=0 ; y=0; } Windows98 class A{ public int x,y; A( ) {x=0 ; y=0; } A(int i ){x =i; y=0;} A(int i,int j ){x =i; y=j;} void show(){ System.out.print(x+” “+y); } public static void main(String args[]){ A t1 = new A(2); t1.show(); //new A; A t2 = new A(7,9); t2.show(); } } 汕头大学计算机教学中心
class Cylinder { // app7_5.java private double radius; private int height; private double pi=3.14; String color; public Cylinder() { radius=1; height=2; color=”绿色”; } public Cylinder(double r, int h, String str) { radius=r; height=h; color=str; } public void getColor() { System.out.println("该圆柱的颜色为:"+color); } double area() { return pi* radius* radius; } double volume() { return area()*height; } } Windows98 汕头大学计算机教学中心
public class app7_5 { //定义主类 public static void main(String args[ ]) { Cylinder volu1=new Cylinder(); //new Cylinder; System.out.println("圆柱1底面积="+ volu1.area()); System.out.println("圆柱1体积="+volu1.volume()); volu1.getColor(); Cylinder volu2=new Cylinder(2.5, 8,”红色”); System.out.println("圆柱2底面积="+ volu2.area()); System.out.println("圆柱2体积="+volu2.volume()); volu2.getColor(); } Windows98 汕头大学计算机教学中心
日期类,初始化对象时,如不给参数,则默认1900-1-1; Windows98 日期类,初始化对象时,如不给参数,则默认1900-1-1; 给一个年份,则月份,日期都为1,给年份、月份,则日期为1,给年、月、日,则根据给定的设置。 public class TDate { private int year ,month , day ; TDate( ){ year=1900 ; month=1;day=1; } TDate(int yy){ year = yy;month=1;day=1; } TDate(int yy, int mm){ year = yy;month=mm;day=1; } TDate(int yy, int mm, int dd){ year = yy;month=mm;day=dd; } public int getYear(){ return year; } public void print(){ System.out.print(year+”/”+month+”/”+day); } public static void main(String atgs[ ] ) { TDate d1 = new TDate(2010 ) ; TDate d2 = new TDate(2010,5); } } 汕头大学计算机教学中心
练习: 1 构造函数重载,有何好处? 2 建立一个时间类, 1)构造函数要求: 可以仅给一个参数,表示时,分、秒为0。 Windows98 练习: 1 构造函数重载,有何好处? 2 建立一个时间类, 1)构造函数要求: 可以仅给一个参数,表示时,分、秒为0。 可以仅给二个参数,表示时、分,秒为0。 可以仅给三个参数,表示时、分、秒。 可以不给参数,表示时、分,秒都为0。 2)打印如 23:11:30的时间 3) 建立测试: 建立时间 10:31:58 , 16:30:21 并打印。 汕头大学计算机教学中心
7.3.4 从一个构造方法调用另一个构造方法 1 从某一构造方法内调用另一构造方法,是通过关键字this来调用的。 Windows98 7.3.4 从一个构造方法调用另一个构造方法 1 从某一构造方法内调用另一构造方法,是通过关键字this来调用的。 2 this 调用语句必须写在该方法的第一行 class A{ private int x; A(int i){ x = i; System.out.print("调用"); } A() {this( -1) ;} void print(){ System.out.print(x);} } public class test1{ public static void main(String args[]) { A a1 = new A(3); a1.print(); A a2 = new A(); a2.print(); } 汕头大学计算机教学中心
class Cylinder { // //app7_6.java private double radius; private int height; private double pi=3.14; String color; public Cylinder() { this(2.5, 5,”红色”); System.out.println(“无参构造方法”); } public Cylinder(double r, int h, String str) { System.out.println(“有参构造方法被调用了”); radius=r; height=h; color=str; } public void show() { System.out.println("圆柱底半径为:"+ radius); double area() { return pi* radius* radius; } double volume( ) { return area()*height; } } Windows98 汕头大学计算机教学中心
【例7.6】续 35 public class app7_6 //主类 36 { Windows98 【例7.6】续 35 public class app7_6 //主类 36 { 37 public static void main(String args[ ]) 38 { 39 Cylinder volu=new Cylinder(); 40 System.out.println("圆柱底面积="+ volu.area()); 41 System.out.println("圆柱体体积="+volu.volume()); 42 volu.show(); 43 } 44 } 汕头大学计算机教学中心
7.3.5 公共构造方法与私有构造方法 1 构造方法一般都是公有(public)的! Windows98 7.3.5 公共构造方法与私有构造方法 1 构造方法一般都是公有(public)的! 2 如构造方法被声明为private,则在类外无法被调用,只能在该类的内部被调用。 汕头大学计算机教学中心
System.out.print("调用"); } A() {this( -1) ;} void print(){ Windows98 class A{ private int x; private A(int i){ x = i; System.out.print("调用"); } A() {this( -1) ;} void print(){ System.out.print(x);} } public class test1{ public static void main(String args[]) { A a1 = new A(3); //? a1.print(); A a2 = new A(); a2.print(); }} 汕头大学计算机教学中心
7.4 静态成员 static称为静态修饰符,它可以修饰类中的成员。 被static修饰的成员被称为静态成员,也称为类成员, Windows98 7.4 静态成员 static称为静态修饰符,它可以修饰类中的成员。 被static修饰的成员被称为静态成员,也称为类成员, 不用static修饰的成员称为实例成员。 汕头大学计算机教学中心
7.4.1 实例成员 在类定义中如果成员变量或成员方法没有用static来修饰,则该成员就是实例成员。 Windows98 汕头大学计算机教学中心
7.4.2 静态变量 用static修饰的成员变量称为“静态变量”,也称为类变量。静态变量是隶属于类的变量,而不是属于任何一个类的具体对象。 Windows98 7.4.2 静态变量 用static修饰的成员变量称为“静态变量”,也称为类变量。静态变量是隶属于类的变量,而不是属于任何一个类的具体对象。 静态变量的使用格式: 类名.静态变量 对象名.静态变量名 汕头大学计算机教学中心
1 2 5 3 8 9 堆 栈 class A{ private int x , y ; static count=0; Windows98 class A{ private int x , y ; static count=0; A(int d1 , int d2) { x=d1; y =d2;} void print(){ System.out.print(x+”,”+y); } class Test { public static void main(String args[]){ A a1=new A(1,2); A a2=new A(5,3); A a3=new A(8,9); A.count =3; System.out.print(a1.count); x 1 y 2 x 5 a1 y 3 a2 a3 x 8 y 9 count 堆 栈 汕头大学计算机教学中心
特点: 1)所有该类的对象共享类变量。 2)通过类名被访问,可以不需创建类的实例(对象)。 Windows98 特点: 1)所有该类的对象共享类变量。 2)通过类名被访问,可以不需创建类的实例(对象)。 3)类方法能直接访问类变量和类方法,但不能直接访问实例变量和实例方法。 类变量初始化 声明时初始化 汕头大学计算机教学中心
A(int d1 , int d2) { x=d1; y =d2; count++;} void print(){ Windows98 class A{ //跟踪 A 被创建了几次 private int x , y ; static count=0; A(){ count ++ ;} A(int d1 , int d2) { x=d1; y =d2; count++;} void print(){ System.out.print(x+”,”+y); } class Test { public static void main(String args[]){ A a1=new A(1,2); A a2=new A(5,3); A a3=new A(); System.out.print(a1.count); System.out.print(a3.count); 汕头大学计算机教学中心
class Cylinder { // app7_8.java静态变量的使用 Windows98 class Cylinder { // app7_8.java静态变量的使用 private static int num=0; //声明num为静态变量 private static double pi=3.14; //声明pi为静态变量 private double radius; private int height; public Cylinder(double r, int h) { radius=r; height=h; num++; } public void count() { System.out.print(“创建了"+num+”个对象:”); } double area() { return pi* radius* radius;} double volume() { return area()*height; } } public class app7_8 { public static void main(String args[ ]) { Cylinder volu1=new Cylinder(2.5,5); volu1.count(); Cylinder volu2=new Cylinder(1.0,2); volu2.count(); } 汕头大学计算机教学中心
private static int year,month,day ; Windows98 1 使用静态变量有何好处? 静态变量练习 2 class TDate { private static int year,month,day ; TDate( ){ year=1900 ; month=1;day=1; } TDate(int yy, int mm, int dd){ year = yy;month=mm;day=dd; } public void print(){ System.out.print(year+"/"+month+"/"+day); } } public class test1 { public static void main(String atgs[ ] ) { TDate d1 = new TDate(2010,4,7 ) ; TDate d2 = new TDate(2010,6,5 ) ; TDate d3 = new TDate(2012,12,12 ) ; d1.print();d2.print();d3.print(); } } 写出程序运行结果,并解释原因。 汕头大学计算机教学中心
7.4.3 静态方法 static 修饰符修饰的方法是属于类的静态方法,又称为类方法。 Windows98 7.4.3 静态方法 static 修饰符修饰的方法是属于类的静态方法,又称为类方法。 静态方法实质是属于整个类的方法,而不加static修饰符的方法,是属于某个具体对象的方法。 1 通过类名被访问,不需创建类的实例(对象) 2 静态方法能直接访问类变量和类方法,但不能直接访问实例变量和实例方法。 3 静态方法中不能使用 this , super 4 调用方法: 类名.静态方法(参数 ) 对象名.静态方法(参数 ) 汕头大学计算机教学中心
public static void main(String args[]) { A a1(3); a1.f1(); a1.f2(); Windows98 class A{ //改错 类方法 int x; static int y=9; A( int i){ x = i;} static void f1(){ x++; y ++; f2(); } void f2 () { x++; y++; f1() ; } } class B{ public static void main(String args[]) { A a1(3); a1.f1(); a1.f2(); A.f1(); A.f2(); System.out.println( A.x); } } class A{ //类方法例题 int x; static int y=9; A( int i){ x = i;} static void f1(){ y ++;} void f2 () { x++;} } class B{ public static void main(String args[]) { A.f1(); System.out.println( A.y); 汕头大学计算机教学中心
编写一个类 myMath,类中提供如下方法: 1 计算阶乘的方法 int fact(int n) 。 Windows98 练习:类方法 编写一个类 myMath,类中提供如下方法: 1 计算阶乘的方法 int fact(int n) 。 2 计算 1+2+3+4 。。。n 的方法 int sum( int n) ; 3为整数排序的方法 sort,该方法接受一个待排序的一维数组,可以指定降序或升序。 sort ( int d[ ] , int direct) //direct=1 升序 , =2 降序 完成该类,并编写测试代码验证。要求使用这些方法时,不需要生成对象实例。 编写一个测试类 myApp, 计算8和12 的阶乘。 计算1+2+3。。+108; 生成10个50以内的随机数,分别以降序、升序排序输出。 汕头大学计算机教学中心
class Cylinder { // app7_9.java 静态方法的使用 private static int num=0; private static double pi=3.14; private double radius; private int height; public Cylinder(double r, int h) { radius=r; height=h; num++; } public static void count() { System.out.println(“创建了"+num+”个对象”); } double area() { return pi* radius* radius; } double volume() { return area()*height; } } public class app7_9 { public static void main(String args[ ]) { Cylinder.count(); Cylinder volu1=new Cylinder(2.5,3); volu1.count(); System.out.println volu1.volume()); Cylinder volu2=new Cylinder(1.0,2); Cylinder.count(); System.out.println(volu2.volume()); } } Windows98 汕头大学计算机教学中心
7.4.4 静态初始化器 对类的静态成员进行初始化。 静态初始化器与构造方法的不同: 1)构造方法是对每个新创建的对象初始化, Windows98 7.4.4 静态初始化器 对类的静态成员进行初始化。 静态初始化器与构造方法的不同: 1)构造方法是对每个新创建的对象初始化, 静态初始化器是对类自身进行初始化。 2)构造方法是在用new运算符创建新对象时由系统自动执行, 静态初始化器一般不能由程序来调用,它是在所属的类被加载入内存时由系统调用执行。 3)用new运算符创建多少个新对象,构造方法被调用多少次, 静态初始化器则在类被加载入内存时只执行一次,与创建多少个对象无关。 4)不同于构造方法,静态初始化器不是方法,因而没有方法名、返回值和参数。 汕头大学计算机教学中心
静态初始化器: class 类名 { static{ 程序块; } public class test1{ int x; Windows98 静态初始化器: class 类名 { static{ 程序块; } public class test1{ int x; public static int y; static { y=9; } void print(){ System.out.print(x+","+y); } public static void main(String args[]) { test1 t1 = new test1(); t1.print(); 汕头大学计算机教学中心
1 类A 有静态成员:数组 buffer ,要求在类加载时就产生20个100以内的随机数存储到数组 buffer中。 Windows98 1 类A 有静态成员:数组 buffer ,要求在类加载时就产生20个100以内的随机数存储到数组 buffer中。 这段代码运行多少次? class A { int no; static String sex="男"; static double buffer[]=new double[20]; static { for (int i=0;i<20;i++) buffer[i] = Math.random() * 100; } public static void main(String args[]) { System.out.println( A.sex); for(int i=0;i<20;i++) System.out.println( A.buffer[i]); } 汕头大学计算机教学中心
System.out.print(x+","+y); } public static void main(String args[]) { Windows98 2 类初始化器能否用构造方法代替? 3 改错 public class test1{ int x; public static int y; static { x=2; y=9; } void print() { System.out.print(x+","+y); } public static void main(String args[]) { test1.print(); } 汕头大学计算机教学中心
System.out.println("B"); } Windows98 4 写出运行结果 public class Test{ private int x; static double y; static { y= Math.random() * 1000; System.out.println("B"); } Test( int i) { x = i ; System.out.println(“构造方法”); } static void printY(){ System.out.println( y ) ; } void printX(){ System.out.println( x ) ; } public static void main(String args[]) { System.out.println( "A"); Test.printY(); Test t1 = new Test(88 ); t1.printX(); } 汕头大学计算机教学中心
7.5 对象的应用 声明一个对象的格式: 类名 对象名 如 A a1 = new A(); a1 引用型变量,存储对象在内存的地址。 Windows98 7.5 对象的应用 声明一个对象的格式: 类名 对象名 如 A a1 = new A(); a1 引用型变量,存储对象在内存的地址。 地址:800 x = 2 y = 3 a1 800 栈内存 堆内存 汕头大学计算机教学中心
7.5.1 对象的赋值与比较 一 赋值 class A{ private int x,y ; Windows98 7.5.1 对象的赋值与比较 一 赋值 class A{ private int x,y ; A (int i, int j){ x=i; y=j; } void print(){ System.out.print(x+”,”+y); } public class Test { public static void main(String args[]){ A a1 = new A(1 , 2); A a2 ; a2 = a1 ; //做了什么? 画出内存示意图 a2.print(); 汕头大学计算机教学中心
Windows98 二 对象作为参数传递 传值调用,但效果是C 的传地址调用。 汕头大学计算机教学中心
public class B { //基本数据类型 传值 int x = 1; void fun( int data ){ Windows98 public class B { //基本数据类型 传值 int x = 1; void fun( int data ){ x = x + data; data++; } public static void main(String args[ ]) { int m=7; B b = new B(); b.fun( m ) ; System.out.println( m ); 传值,data改变但m不改变 data 7 m 7 栈内存 汕头大学计算机教学中心
void show(){ System.out.println(x); } } class B { Windows98 class A{ //按值调用 int x; A(int i ){x =i; } void show(){ System.out.println(x); } } class B { static void f1( A d){ d.x = d.x * d.x; public static void main(String args[]) { A a1 = new A( 3 ); a1.show(); f1( a1 ); 引用,d改变, 就是 a1 改变。 地址:800 d 800 3 x a1 800 堆内存 栈内存 汕头大学计算机教学中心
Windows98 1 交换两个对象的值。 汕头大学计算机教学中心
System.out.println(x); } } class B { static void swap( A d1, A d2){ Windows98 引用例题:两个对象的交换 class A{ private int x; A(int i ){x =i; } int getX() { return x; } void show(){ System.out.println(x); } } class B { static void swap( A d1, A d2){ A temp ; temp=d1; d1 = d2; d2 = temp;} public static void main(String args[]) { A p1 = new A(3); A p2 = new A(5); swap( p1 , p2 ); p1.show() ; p2.show() ; }} p1 A X:3 p2 X:5 d1 d2 p1 A X:3 p2 X:5 d1 d2 交换发生后 交换发生前 能交换成功吗? 输出的结果? 汕头大学计算机教学中心
void show(){ System.out.println(x); } } class B { 正确交换两对象 Windows98 class A{ int x; A(int i ){x =i; } void show(){ System.out.println(x); } } class B { static void swap( A d1, A d2){ int tempX ; tempX=d1.x; d1.x = d2.x; d2.x = tempX; } public static void main(String args[]) { A p1 = new A(3); A p2 = new A(5); swap( p1 , p2 ); p1.show() ; p2.show() ; } p1 A X:3 p2 X:5 d1 d2 p1 A X:5 p2 X:3 d1 d2 交换发生后 交换发生前 汕头大学计算机教学中心
Windows98 日期类,加一个方法,改变日期。 如何更改,才能正确? 汕头大学计算机教学中心
private int year,month ,day; TDate (int yy,int mm,int dd ){ Windows98 changeDay 更改日期程序改错 class TDate{ private int year,month ,day; TDate (int yy,int mm,int dd ){ year=yy; month=mm;day=dd;} static void changeDay(Tdate x, int n){ int y =x.getYear(); int m =x.getMonth(); int d =x.getDay() ; d = d + n ; x = new TDate( y,m,d ); } int getYear() {return year;} int getMonth() {return month;} int getDay() {return day;} public void showDate(){ System.out.println( year+”.”+month+”.”+day); } } class TDateDemo{ public static void main(String args[]) { TDate d1(2005,2,1); TDate.changeDay(d1,2); d1.show(); } 输出:2005.2.3 ? 改变前 2005.2.1 d1 x d1 2005.2.1 x 2005.2.3 改变后 汕头大学计算机教学中心
对象作为参数 练习: 1 为 TDate 日期类添加一个交换两个日期对象的方法 exchangeDate,写出完整的测试代码。 Windows98 对象作为参数 练习: 1 为 TDate 日期类添加一个交换两个日期对象的方法 exchangeDate,写出完整的测试代码。 如:d1 为2005年5月20日,d2为 2005年10月1日,执行 exchangeDate(d1,d2)后,d1 变为2005年10月1日,d2为 2005年5月20日 汕头大学计算机教学中心
Windows98 三 对象比较 1 对象变量地址 2 对象内容 汕头大学计算机教学中心
public static void main(String args[]) { A a1=new A(2,3); Windows98 class A { private int x , y ; A(int i , int j){ x = i ; y = j ;} } public class Test{ public static void main(String args[]) { A a1=new A(2,3); A a2=new A(2,3); A a3; a3 = a1 ; System.out.println( a1==a2); //a1.equals(a1) System.out.println(a1==a3); 汕头大学计算机教学中心
public static void main(String args[]) { A a1=new A(2,3); Windows98 class A { private int x , y ; A(int i , int j){ x = i ; y = j ;} boolean equal( A aa){ if ( x ==aa.x && y==aa.y ) return (true) ; else return (false) ; } } public class Test{ public static void main(String args[]) { A a1=new A(2,3); A a2=new A(2,5); System.out.println( a1.equal(a2) ); 汕头大学计算机教学中心
1)测两日期是否相等的方法equal(TDate d1,Tdate d2))。 返回true/false 表示是否相等 Windows98 为 TDate 日期类添加方法: 1)测两日期是否相等的方法equal(TDate d1,Tdate d2))。 返回true/false 表示是否相等 2)两日期比较大小的方法compare(TDate d1,Tdate d2)。 返回1 表示 d1>d2; 0 表示 d1=d2 ; -1 表示 d1<d2 汕头大学计算机教学中心
7.5.2 引用变量作为方法的返回值 引用变量不但可以作为参数进行传递,而且也可以作为方法的返回值。 Windows98 7.5.2 引用变量作为方法的返回值 引用变量不但可以作为参数进行传递,而且也可以作为方法的返回值。 若要方法返回类类型的变量,只须在方法声明的前面加上要返回的类即可。 返回值:对象的地址返回。 汕头大学计算机教学中心
A(int i , int j){ x = i ; y = j ;} A fun() { int xx , yy; Windows98 class A { //方法返回对象 private int x , y ; A(int i , int j){ x = i ; y = j ;} A fun() { int xx , yy; xx = x*x; yy = y * y; A aa = new A(xx , yy ); return (aa) ; } public class Test{ public static void main(String args[]) { A a1=new A(5,9); A a2; a2 = a1.fun( ); 汕头大学计算机教学中心
class Person { //app7_12.java 方法的返回值为对象 private String name; Windows98 class Person { //app7_12.java 方法的返回值为对象 private String name; private int age; Person(String name, int age) { this.name=name; this.age=age; } Person compare( Person P ) { if (this.age > P.age) return this; else return P; } } public class app7_12 { public static void main(String args[ ]) { Person Per1=new Person (“张三”,20); Person Per2=new Person (“李四”,21); Person Per3; Per3= Per1.compare(Per2); if (Per3==Per1) System.out.println(“张三年龄大”); System.out.println(“李四年龄大”); } 汕头大学计算机教学中心
对象作为返回值练习: 设计虚数类,实现: 两个虚数的加运算: add 两个虚数的减运算:minus Windows98 汕头大学计算机教学中心
7.5.3 类类型的数组 用数组存放对象要经过如下两步: (1)声明类类型的数组变量,并用new运算符分配内存空间给数组; Windows98 7.5.3 类类型的数组 用数组存放对象要经过如下两步: (1)声明类类型的数组变量,并用new运算符分配内存空间给数组; (2)用new创建新的对象,分配内存空间给它,并让数组元素指向它。 汕头大学计算机教学中心
class Person { // app7_13.java 对象数组的应用 private String name; private int age; public Person(String name, int age) { this.name=name; this.age=age; } public void show() { System.out.println(“姓名:“+name+” 年龄:”+age); } } public class app7_13 { public static void main(String args[ ]) { Person Per[]; //声明类类型的数组 Per=new Person[3]; //用new为数组分配内存空间 Per[0]=new Person(“张三”,20); //建新对象,并分 Per[1]=new三 Person(“李四”,21); //配给数组元素 Per[2]=new Person(“王二”,19); Per[2].show(); Per[0].show(); //利用对象Per[0]调用show()方法 Windows98 汕头大学计算机教学中心
对象数组 地址:9000 张三 name 地址:800 20 age 9000 李四 name per 800 21 age 王二 name Windows98 对象数组 地址:9000 张三 name 地址:800 20 age 9000 李四 name per 800 21 age 王二 name 19 age 栈内存 堆内存 汕头大学计算机教学中心
Windows98 7.5.4 以对象数组为参数进行方法调用 对象数组作为参数传递到方法里 传递数组的首地址 汕头大学计算机教学中心
class Person { // app7_14.java 对象数组为参数 private String name; private int age; public Person(String name, int age) { name=name; this.age=age; } public static int min_age( Person p[ ] ) { int min=200; for (int i=0;i<p.length;i++) if (p[i].age<min) min=p[i].age; return min; } } public class app7_14 { public static void main(String args[ ]) { Person Per[]=new Person[3]; Per[0]=new Person(“张三”,20); Per[1]=new Person(“李四”,21); Per[2]=new Person(“王二”,19); System.out.println(“最小年龄”+ Person. min_age(Per)); } } Windows98 汕头大学计算机教学中心
void setX( int _x) { x = _x; } int getX( ) { return x; } Windows98 class A { private int x ; A(int i ){ x = i ; } void setX( int _x) { x = _x; } int getX( ) { return x; } void print(){ System.out.print( x ); } } public class Test{ static void f1( A d[ ] ){ d[1].setX( d[0].getX()+1 ) ; public static void main(String args[]) { A p[] =new A[2 ]; p[0] = new A(11); p[1] = new A(18); Test.f1( p ); p[1].print(); } } 对象内容改变影响实参 汕头大学计算机教学中心
对象数组练习 建立学生类 student ,有数据成员:学号、姓名、年龄、数学成绩、外语成绩、语文成绩、物理成绩。 用数组存储8个学生的信息 Windows98 对象数组练习 建立学生类 student ,有数据成员:学号、姓名、年龄、数学成绩、外语成绩、语文成绩、物理成绩。 用数组存储8个学生的信息 方法: 计算数学、外语、语文、物理成绩的课程平均分 添加数据成员,学生平均分。然后添加方法,计算每个学生的平均分,存储到此成员中。 *添加数据成员,名次。然后添加方法,根据平均分编排名次存储到此成员中。 汕头大学计算机教学中心
7.5.5 对象作为数组成员 (子对象) class A { private int x ; A(){ x = -1 ;} Windows98 7.5.5 对象作为数组成员 (子对象) class A { private int x ; A(){ x = -1 ;} A(int i ){ x = i ; } void print(){ System.out.print( x );} } class B { private A a ; B(int k){ a= new A(k); } void print(){ a.print(); } public class test{ public static void main(String args[]) { B b1 = new B(93) ; b1.print(); 汕头大学计算机教学中心
void print(){ System.out.print( x );} } class B { public A a ; Windows98 class A { public int x ; A(){ x = -1 ;} A(int i ){ x = i ; } void print(){ System.out.print( x );} } class B { public A a ; B(int k){ a= new A(k); } public class test{ public static void main(String args[]) { B b1 = new B(93) ; b1.a.print(); 调用子对象的方法。 汕头大学计算机教学中心
1 学生类 Student,有学号、姓名、出生日期。 方法:构造方法、输出该生年龄、打印该生信息。 Windows98 1 学生类 Student,有学号、姓名、出生日期。 方法:构造方法、输出该生年龄、打印该生信息。 测试:建立一个学生,学号为A101,张三,1981年8月22日出生。输出该生的年龄,以及学号、姓名、出生日期。 注意:日期用 日期类实现。 汕头大学计算机教学中心
综合练习 1 实现一个表示日期的类 TDate,该类有: 私有成员变量:year, month, day 方法: 1)构造函数(尽可能写全) 2)分别返回年、月、日的方法:getYear ,getMonth ,getDay 3)显示日期的公有方法show,格式如:2005年 3月20日 4)判断闰年公有方法 isLeapYear ,返回true/false 表示是否闰年 5)测两日期是否相等的方法equal(TDate d1,Tdate d2))。 返回true/false 表示是否相等 6)两日期比较大小的方法compare(TDate d1,Tdate d2)。 返回1 表示 d1>d2; 0 表示 d1=d2 ; -1 表示 d1<d2 生成对象测试: 1) 只给出2005,生成TDate对象 t1 , 表示2005.1.1 2) 只给出2005年5月,生成TDate对象 t2,表示2005年5月1日。 3) 不给出初始化参数,生成TDate对象 t3,表示1900年1月1日。 4) 生成对象 d1 表示 2005年10月28日,对象 d2 表示 2005年12月18日,输出d1,d2 5) 输出d1 , d2 那一个日期大? 6)思考:上述equal,compare方法写成类方法,有什么好处? Windows98 综合练习 汕头大学计算机教学中心
1) int getWeek() 返回星期几的方法 。(已知1980.1.1 为星期二, 返回0:星期天 , 1 星期一… Windows98 进一步: 2 为TDate 类添加成员方法 : 1) int getWeek() 返回星期几的方法 。(已知1980.1.1 为星期二, 返回0:星期天 , 1 星期一… 2)getNextDay ( int n ) 计算某日期的方法。n 为天数 ,当 n为负 计算该天之前的日期,否则返回n天后的日期 getDays(TDate d1,Tdate d2),返回两日期之间的天数。 测试: 1)利用编好的类,计算自己生日是星期几 2)生成 2005年12月31日的对象d1,输出该对象的下一天的日期。 9天后的日期及前天的日期。 3)计算 2010年5月1日于2005年10月31日之间的天数。 汕头大学计算机教学中心
4 为类TDate 添加一个交换两个日期对象的方法 exchangeDate,写出完整的测试代码。 Windows98 4 为类TDate 添加一个交换两个日期对象的方法 exchangeDate,写出完整的测试代码。 如:d1 为2005年5月20日,d2为 2005年10月1日,执行 exchangeDate(d1,d2)后,d1 变为2005年10月1日,d2为 2005年5月20日 [练习对象作形参] 5 为类TDate 编写一个日期排序的方法 dateSort,形参为日期数组。 测试:建立一个日期数组,存储6个日期,排序后输出。 汕头大学计算机教学中心
类:student:sno ,sname , ssex, sBirthday,sDept Windows98 综合练习 类:student:sno ,sname , ssex, sBirthday,sDept course:cno,cname , ccredir SC: sno , cno , grade 数据成员为私有。 有5个学生,有3门课程,每个学生选修课程,存储在数组中。 输出每个学生的学号、姓名、年龄、课程名,成绩。 输出课程平均分 输出每个学生平均分。 汕头大学计算机教学中心
总结 1方法的重载。 2 掌握构造方法的定义和使用 3.类变量、类方法。 4.对象作形参、返回值 5 对象数组 Windows98 汕头大学计算机教学中心
Windows98 你会了吗? 汕头大学计算机教学中心
4)判断闰年公有方法 isLeapYear ,返回true/false 表示是否闰年 Windows98 4)判断闰年公有方法 isLeapYear ,返回true/false 表示是否闰年 boolean isLeapYear () { boolean bRet; if ( year % 4 && year % 100 !=0 || year % 400=0) bRet = true ; else bRet = false; return ( bRet ) ; } 汕头大学计算机教学中心
if (IsLeapYear( )==1) m[2] = 29; Windows98 TDate1 getNextDay( ){ int m[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; if (IsLeapYear( )==1) m[2] = 29; TDate1 nextday = new TDate ( year , month , day); //next day nextday.day ++ ; if ( nextday.day > m[ nextday.month ] ){ nextday.day = 1; nextday.month ++; if (nextday.month > 12) { nextday.year ++; nextday.month=1; } return (nextday) ; 汕头大学计算机教学中心
TDate1 getNextDay( int n ){ Windows98 TDate1 getNextDay( int n ){ int m[ ]={0,31,28,31,30,31,30,31,31,30,31,30,31}; if (IsLeapYear( ) ) m[2] = 29; TDate1 nextday = new TDate ( year , month , day); //next day nextday.day = nextday.day + n ; //n 可正 , 可负 if ( nextday.day > m[ nextday.month ] ){ nextday.day = 1; nextday.month ++; if (nextday.month > 12) { nextday.year ++; nextday.month=1; } else if (nextday.day < 1 ) { nextday.day = m[nextday.month] + nextday.day ; nextday.month -- if (nextday.month <1) { nextday.year --; nextday.month=12; } return nextday; 汕头大学计算机教学中心
int getDays(TDate d1,Tdate d2){ //返回两日期之间的天数。 Windows98 int getDays(TDate d1,Tdate d2){ //返回两日期之间的天数。 汕头大学计算机教学中心