丁保国的博客

收集整理工作生活,点点滴滴

  :: :: 博问 :: 闪存 :: :: :: :: 管理 ::

第五讲 对象的初始化

主要内容

 

用构造方法确保初始化

方法的重载

this关键字

类中成员变量的默认值

对象的初始化过程

 

用构造方法确保初始化

缺省构造方法

javap.exe观察类框架

bin目录下的javap.exe,是一个反编译的类察看器。

D:\Javawork\Lesson4>javap Person

Compiled from "Person.java"

class Person extends java.lang.Object{

    int sex;

    int salary;

    Person();

    void employed();

}

观察:类框架中多了哪一项?

 

构造方法的初步认识

²       构造方法的名字和类名相同,无类型修饰,没有返回值。

²       Java类都有构造方法,如果程序中没定义,编译器会自动提供缺省的构造方法。

²       类中无定义构造方法时,编译时自动添加缺省的构造方法

²       缺省的构造方法不带参数。

 

主动在类中引入构造方法

阅读程序分析结果

class Person2{

  int salary;

  Person2(){

     System.out.println("output of constructor");

  }

 

  void employed(){

     System.out.print("Work state:");

     if (salary==0) System.out.println("no job");

     else System.out.println("job");

  }

 

  public static void main(String[] a){

     Person2 p1=new Person2();

     p1.salary=900;

     p1.employed();

  }

}

问题:在创建对象时,能否直接将薪水传递过去?试修改实现。

 

思考

1.    构造方法有什么用?

2.    每个类都有构造方法吗?

3.    构造方法的命名和类型修饰?

4.    构造方法的执行时机?

5.    如果希望创建对象时,传递给对象中的变量初值,怎么实现?

6.    回顾new运算,new 类名(参数),其中的参数什么时候带,什么时候不带?

7.    如果一个类定义了带参的构造方法,可以用new 类名()创建该类的对象吗?

 

说明:构造方法不可声明返回类型(包括void)。如说明编译器将把它看作为一个一般的方法,而不是构造方法。

 

练习构造一个Circle类,可接受变量半径,并有求圆面积的方法getS和求圆周长的方法getL。通过Circle类的实例化对象,分别求半径为:11.52.5的圆面积和圆周长。

 

类中方法的重载

成员方法的重载

重载:一词多义。

方法重载:同一个方法名,被赋予了多个意义。多个同名方法对应于不同的处理任务。

 

例:阅读和分析程序运行结果

class TestOL{

   int x;

   void func(){System.out.println("no arg");}

   String func(int i){

     return "arg is "+i;

   }

   void func(String s){

     System.out.println(s);  

   }

   public static void main(String[] a){

     TestOL c=new TestOL();  

     c.func();

     c.func(c.func(100));

   }

}

 

方法重载设计要点

²       方法名相同

²       参数不同或者返回类型不同

int f(){…}      void f(){…}

void f(int a,int b){…}     void f(String c){…}

 

重载时方法的窄化转型

class TestOL{

   void func(double x){System.out.println(x+" is double");}

   void func(float x){   System.out.println(x+" is float");}

   void func(int x){System.out.println(x+" is int");}

  

   public static void main(String[] a){

     TestOL c=new TestOL();  

     c.func(1);

     c.func(2.5);

     c.func(3.5f);

   }

}

结论:窄化转型,即传递的实参“小于”方法中声明的形参,实参就会自动提升一级。

思考

 

1.    方法重载的特征是什么?

2.    方法重载有何意义?

3.    如果例2main方法中添加语句c.func(‘a’);,会是什么结果?

4.    如果例2的类定义中,注释掉前面两个func方法,又会是什么结果?

 

练习:

1、构造一个包含有求累加和方法sum的类MyCalsum方法可接受一个或两个整型参数,如果是一个参数,则是从自然数1开始的累加;如果是两个参数mn,求的是从其中较小数到较大数的累加和。

2、试用上类。

 

构造方法重载

同一个类可有多个构造方法,但只有一个构造方法在创建对象时执行。

class Flower{

  Flower(String c){

     System.out.println("It's a "+c+" flower.");

   }

  Flower(String s,String c){

      System.out.println("It's a "+s+" "+c+" flower." );

     System.out.println("How beautiful!");

   } 

}

class Test{

   public static void main(String[] aa){

     new Flower("red");

     new Flower("little","yellow");

     new Flower("big","red");

   }

}

思考

1.    一个类的构造方法可以重载吗?

2.    创建对象时,类中所有的构造方法都会顺序执行吗?

3.    创建对象时如何决定运行哪个构造方法?

4.    构造方法的执行时机?

 

练习一:

1、构造一个可接受一个或两个参数的矩形类Square,含求矩形面积的方法。如果传递过来一个参数,作正方形处理;

2、实例化矩形类,求:(1)2.3,宽4.5的矩形面积。(2)边长为7.6的正方形面积。

 

练习二:设计一个类,分别将三角形的三条边作为属性,并能计算面积。(默认为勾三股四弦五的直角三角形,一个参数时默认为边长为1的等边三角形,三个参数时分别为三条边长)

class Triangle{

      double a,b,c;

         Triangle(){

     

         }

         Triangle(double x){

     

         }

         Triangle(double a,double b,double c){

     

         }

         double getS(){

     

     

         }

}

 

this关键字

在方法内使用,表示调用方法的这个对象

²       this.变量名-------访问这个对象的变量

²       this.方法名(参数);----------访问这个对象的方法

²       this(参数)----------调用这个对象的同名成员方法

 

程序一:

class TestA{

   TestA(){

      int i=7;

      System.out.println(i+"  "+this.i);

      this.i=3;

    }

   int i=1;

    public static void main(String[] args){

      System.out.println(new TestA().i);

    }

}

程序二:

class TestThis{

   int a;

   int b;

   TestThis(int a,int b){

     this.a=a;

     this.b=b;

     System.out.println(a+"----"+b+"\t"+this.sum());

   }

   TestThis(int a){

     this(1,a);

   }

   int sum(){

     int s=0;

     for(int i=a;i<=b;i++)s+=i;

     return s;

   }

   public static void main(String[] aa){

     new TestThis(10,20);

     new TestThis(100);

   }

}

思考

1.  方法中的变量与类的成员变量可否同名?

2.  若同名时,在方法中如何访问成员变量?

3.  如何在类方法中调用同类中的方法?

 

类中成员变量的默认值

类中的成员变量可以在类定义时给初值。

如果没有对基本数据类型的成员预先赋初值,则在创建变量时自动初始化。要点:

²       数值型,值为0

²       布尔型,值为false

²       字型串,值为空(null)

class TestInit{

     int x;

     String s;

     boolean f;

  public static void main( String[ ] args ){

    TestInit l=new TestInit();

    System.out.println( "\nx is " + l.x );

    System.out.println( "s is " + l.s );

    System.out.println("f is "+ l.f);

   }

}

程序可以正确编译和运行!

 

如果一个变量在方法中定义,那么使用这个变量前必须赋值。

class TestInit{

    public static void main( String[ ] args ){

    int x;

    System.out.println( "\nx is " + x );

   }

}

 

错误信息:variable x might not have been initialized

 

对象的初始化过程

对象的基本初始化过程

²       初始化时涉及到成员变量和构造方法;

²       实例变量的初始化在构造方法之前。

程序一:

class TestInit{

  int x=3;

  TestInit(){

     x=5;

  }

  public static void main( String[ ] args ){

    TestInit t=new TestInit();

    System.out.println(t.x );

   }

}

 

class TestInit{

  TestInit(int a){

     x=a;

  }

   public static void main( String[ ] args ){

    TestInit t=new TestInit(5);

    System.out.println( t.x );

   }

  int x=3;

}

 

程序二:

class Tag{

  Tag(int m){

     System.out.println("Tag("+m+")");

  }

}

class Card{

  Tag t1=new Tag(1);

  Card(){

     System.out.println("Card()");

     t3=new Tag(33);

  }

  Tag t2=new Tag(2);

  void f(){

     System.out.println("f()");    

  }

  Tag t3=new Tag(3);

}

class TestInit2{

  public static void main(String[] aa){

     Card t=new Card();

     t.f();

  }

}

 

静态变量的初始化

²       类中的静态成员变量的初始化在第一次创建变量,或直接由类调用时进行

²       静态变量只初始化一次

class Bow{

  Bow(int m){

     System.out.println("Bow("+m+")");

  }

  void f(int m){

     System.out.println("f("+m+")");    

  }

}

class Table{

  Bow b1=new Bow(1);

  Table(){

     System.out.println("Table()");

     b2.f(1);

  }

  static Bow b2,b3;

  static{

     b2=new Bow(2);

     b3=new Bow(3);

  } 

}

class TestInit{

  public static void main(String[] aa){

     System.out.println("Creating new Table()");

     new Table();

     System.out.println("Creating new Table()");

     new Table();

  }

}

 

思考

1.    对象的初始化在什么时候进行?

2.    静态变量和实例变量的初始化时机?

3.    实例变量和构造方法哪个先初始化?

4.    除了构造方法外,通常的成员方法会自动初始化吗?

5.    类有多个成员变量,这些变量的初始化顺序?

 

 

posted on 2007-07-21 10:31  丁保国  阅读(351)  评论(0编辑  收藏  举报