2015年7月15日 星期三

15 類別(2)

15   類別(2)
類別(Class)的修飾子
class關鍵字之前的publicabstractfinal稱為修飾子。
格式:
[ public|abstract|final ] class 類別名稱 {
        宣告資料(變數及常數)欄位(Field)
        定義執行演算及其他操作的方法(Method)
}

[公開類別及非公開類別]-public存取修飾子
沒有宣告為public時稱為非公開類別,僅能被同一package(套件、程式集)內的class存取,宣告為public時稱為公開類別,則允許同一package外之所有其他class來存取。
package將於存取權限控制章節說明。




[抽象類別(abstract class)]
不描述處理內容,只定義呼叫方式的方法,稱為抽象方法(abstract method)。而擁有抽象方法的類別稱為抽象類別(abstract class)
抽象類別不能建立物件,需經繼承並覆寫抽象方法,才可建立物件。
abstract class AbstScore1{
  int chi = 79 ;
  int eng = 81 ;
  float tot ;
  float ave ;
  abstract void abstTot() ;
  void abstAve() {
  ave = tot / 2 ;
  System.out.println("平均分數=" + ave) ;
  }
}

class TotAve1 extends AbstScore1 {
  void abstTot() {
    tot = chi + eng ;
    System.out.println("總分=" + tot) ;
  }
}



[抽象類別建立物件-錯誤]
class AbstMain1 {
  public static void main (String[] args) {
    AbstScore1 ta1 = new AbstScore1 ();
    ta1.abstAve() ;
  }
}
編譯結果:C:\js>javac AbstMain1.java
abstMain1.java:16: error: abstScore1 is abstract; cannot be instantiated
    abstScore1 ta1 = new abstScore1 ();
                     ^
1 error

[抽象類別經由繼承建立物件-正確]
class AbstMain2 {
  public static void main (String[] args) {
    TotAve1 ta1 = new TotAve1();
    ta1.abstTot() ;
    ta1.abstAve() ;
  }
}
執行結果:C:\js>java AbstMain2
總分=160.0
平均分數=80.0







[final修飾子(final class)]
final是用來修飾欄位、方法與類別的修飾子。加上final修飾子的欄位,其值不可以被修改。加上final修飾子的方法,該方法不可以被覆寫。而加上final修飾子的類別,則不可以被繼承。
本章節僅先說明final class

[final class範例]
加上final修飾子的類別,不可以被繼承。
final class FinalFat2{
  void finalmd3(){
    int y = 20 ;      
    System.out.println("y=" +y);
  }
}

class FinalsSon2 extends FinalFat2{ }    //不能被繼承
class FinalMain2{
  public static void main(String[] args){
    FinalSon2 fc2 = new FinalSon2();
    fc2.finalmd3();
  }
}
編譯結果:C:\js>javac FinalMain2.java
FinalMain2.java:1: error: cannot inherit from final FinalFat2
class FinalsSon2 extends FinalFat2{ }    //不能被繼承
                         ^
FinalMain2.java:4: error: cannot find symbol
    FinalSon2 fc2 = new FinalSon2();
    ^
  symbol:   class FinalSon2
  location: class FinalMain2
FinalMain2.java:4: error: cannot find symbol
    FinalSon2 fc2 = new FinalSon2();
                        ^
  symbol:   class FinalSon2
  location: class FinalMain2
3 errors



加上final修飾子的類別,可直接建立物件。
class FinalMain3{
  public static void main(String[] args){
    FinalFat2 fc2 = new FinalFat2();
    fc2.finalmd3();
  }
}
執行結果:C:\js>java FinalMain3

y=20

2015年7月8日 星期三

14 類別(1)

14   類別(1)
類別(Class)
類別的成員包含欄位(Field)及方法(Method)。類別內不能執行敘述式,只能定義欄位及方法,而敘述式(運算及列印等操作)則包含於方法內。敘述式也可定義於建構子(後述)內。
格式:
[ public|abstract|final ] class 類別名稱 {
        宣告資料(變數及常數)欄位(Field)
        定義執行演算及其他操作的方法(Method)
}

[一般類別和主類別]
含有名稱為main之主方法的類別稱為主類別,否則是為一般類別。

[一般類別]
不可單獨執行,必須被由主類別內之主方法呼叫使用。

class Score7 {
int Chi = 75 ;
  int Eng = 63 ;
  int Pro = 50 ;
  int totScore ;
  void comDisp( ){
    totScore = Chi + Eng + Pro ;   
    System.out.println ("總分=" + totScore ) ;
  }
}
編譯:C:\js>javac Score7.java



[主類別]
含有名稱為main之方法的類別,為程式執行的起點,一個程式檔最多只能含有一個主類別。
[主類別單獨執行]
class 主類別單獨執行 {
public static void main(String[ ] args) {
int 國文分數 = 81 ;
    int 英文分數 = 66 ;
    int 程式設計分數 = 71 ;
    int 總分;
    總分 = 國文分數+英文分數+程式設計分數 ;   
    System.out.println ("總分=" +總分 ) ;
  }
}
執行結果:C:\js>java 主類別單獨執行
總分=218

[主類別呼叫其他類別]
class 主類別呼叫其他類別{
public static void main(String[ ] args) {
  Score7 tot = new Score7( ) ;
  tot.comDisp( ) ;
  }
}
執行結果:C:\js>java 主類別呼叫其他類別
總分=188



[運算及操作之敘述式不可宣告於方法範圍之外]
[一般類別]
class StateErr1 {
  int i = 50 ;
  int j =100 ;
  int t ;
  t = i + j ;  //錯誤
  System.out.println("t ="+ (i + j)) ;  //錯誤
}
編譯結果:
StateErr1.java:5: error: <identifier> expected
  t = i + j ;  //錯誤
   ^
StateErr1.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                    ^
StateErr1.java:6: error: illegal start of type
  System.out.println("t ="+ (i + j)) ;  //錯誤
                     ^
StateErr1.java:6: error: ')' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                          ^
StateErr1.java:6: error: ';' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                           ^
StateErr1.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                              ^
StateErr1.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                  ^
StateErr1.java:6: error: illegal start of type
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                   ^



StateErr1.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                    ^
StateErr1.java:6: error: ';' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                      ^
StateErr1.java:7: error: reached end of file while parsing
}
 ^
11 errors



[正確方式]-將上述敘述置於方法內
class State1 {
  int i = 50 ;
  int j =100 ;
  int t ;
  void add1() {
    t = i + j ;  //內部區塊可使用外部區塊宣告之變數,見後述
    System.out.println("t ="+ (i + j)) ;
  }
}

[主類別]
class StateErr2 {
  int i = 70 ;
  int j =110 ;
  int t ; 
  t = i + j ;  //錯誤
  System.out.println("t ="+ (i + j)) ;  //錯誤
  public static void main(String[] args) {
    int a = 11 ;
    int b = 22 ;
    int c ;
    c = a + b ;  //正確
    System.out.println("c ="+ (a + b)) ;  //正確
  }
}



編譯結果:
C:\js>javac StateErr2.java
StateErr2.java:5: error: <identifier> expected
  t = i + j ;  //錯誤
   ^
StateErr2.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                    ^
StateErr2.java:6: error: illegal start of type
  System.out.println("t ="+ (i + j)) ;  //錯誤
                     ^
StateErr2.java:6: error: ')' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                          ^
StateErr2.java:6: error: ';' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                           ^
StateErr2.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                              ^
StateErr2.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                  ^
StateErr2.java:6: error: illegal start of type
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                   ^
StateErr2.java:6: error: <identifier> expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                    ^
StateErr2.java:6: error: ';' expected
  System.out.println("t ="+ (i + j)) ;  //錯誤
                                      ^
10 errors




[正確方式]- 將上述敘述置於主方法內
class State2 {
  public static void main(String[] args) {
    int i = 70 ;
    int j =110 ;
    int t ; 
    t = i + j ;  //正確
    System.out.println("t ="+ (i + j)) ;  //正確
    int a = 11 ;
    int b = 22 ;
    int c ;
    c = a + b ;  //正確
    System.out.println("c ="+ (a + b)) ;  //正確
  }
}
執行結果:C:\js>java State2
t =180
c =33




[static方法內不可參照非static變數]
class StatErr3 {
  int i = 50 ;
  int j =100 ;
  int t ;
  public static void main(String[] args) {
    t = i + j ;  //錯誤
    System.out.println("t ="+ (i + j)) ;  //錯誤
  }
}

C:\js>javac StateErr3.java
StatErr3.java:6: error: non-static variable t cannot be referenced from a static
 context
    t = i + j ;  //錯誤
    ^
StatErr3.java:6: error: non-static variable i cannot be referenced from a static
 context
    t = i + j ;  //錯誤
        ^
StatErr3.java:6: error: non-static variable j cannot be referenced from a static
 context
    t = i + j ;  //錯誤
            ^
StatErr3.java:7: error: non-static variable i cannot be referenced from a static
 context
    System.out.println("t ="+ (i + j)) ;  //錯誤
                               ^
StatErr3.java:7: error: non-static variable j cannot be referenced from a static
 context
    System.out.println("t ="+ (i + j)) ;  //錯誤
                                   ^
5 errors



[正確方式]
[1.建立物件]
class State3 {
  int i = 50 ;
  int j =100 ;
  int t ;
  public static void main(String[] args) {
    State3 s3 = new State3() ;
    s3.t = s3.i + s3.j ;
    System.out.println("t ="+( s3.i + s3.j)) ;
  }
}
執行結果:C:\js>java State3
t =150

[2.使用static變數(後述)]
宣告變數為static屬性時,主方法即可使用(因主方法之變數皆具static屬性)
class State4 {
  static int i = 50 ;
  static int j =100 ;
  static int t ;
  public static void main(String[] args) {
    t = i + j ;
    System.out.println("t ="+ (i + j)) ;
  }
}
執行結果:C:\js>java State4
t =150



[相同名稱之不同變數]
主方法外之變數沒有加上static屬性,和在主方法內雖宣告相同之名稱,但仍屬不同之變數(後述)
class State5 {
  int i = 50 ;
  int j =100 ;
  int t ;
  public static void main(String[] args) {
    int i =51 ;    //宣告相同名稱之不同變數
    int j = 102 ;  //相同名稱之不同變數
    int t ;       //相同名稱之不同變數
    t = i + j ;
    System.out.println("t = "+ (i + j)) ;

    State5 aa = new State5( ) ;
    aa.t = aa.i + aa.j ;
    System.out.println("aa.t = "+ aa.t) ;
  }
}
執行結果:C:\js>java State5
t = 153
aa.t = 150





[方法內不可宣告其他方法]
class StateErr4 {
  public static void main(String[ ] args) {
    int chChi = 85 ;
    int chEng = 75 ;
    int chPro = 65 ;
    int totScore ;
    void score31comDisp( ){       //方法內不可再有方法
      totScore = chChi + chEng + chPro ;   
      System.out.println ("張曉的總分數=" + totScore ) ;
    }
  }
}
編譯結果:
C:\js>javac StateErr4.java
StateErr4.java:7: error: illegal start of expression
        void score31comDisp( ){       //方法內不可再有方法
        ^
StateErr4.java:7: error: ';' expected
        void score31comDisp( ){       //方法內不可再有方法
                           ^
2 errors



[不可呼叫其他主類別之main方法]
class StateErr5{
  public static void main(String[ ] args){
    State2 s2 = new State2( );
    s2.main( );  //錯誤
  }
}      
編譯結果:
C:\js>javac StateErr5.java
StateErr5.java:4: error: method main in class state2 cannot be applied to given
types;
        s2.main( );  //錯誤
          ^
  required: String[]
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error}