目前分類:JAVA (20)

瀏覽方式: 標題列表 簡短摘要
● 接續昨日-java連資料庫
Connection=>連線"jdbc"
DriverManager=> 連線"jdbc"
PreparedStatement=>寫入資料庫
=>輸入資料時,是用 PreparedStatement寫入,然後再透過 Connection連接資料庫,經由 DriverManager把輸入的資料丟到資料庫裡,這就是串接
 
Statement=>搭配已讀取資料庫
ResultSet=>搭配已讀取資料庫
 
● 讓使用者輸入的資料可以送至資料庫
 private void okMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  int ID=Integer.parseInt(id.getText());
  int CHI=Integer.parseInt(chi.getText());
  int ENG=Integer.parseInt(eng.getText());
  String NAME=name.getText();
  String sql="insert into student(id,name,chi,eng) values(?,?,?,?)";
 
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  PreparedStatement ps=conn.prepareStatement(sql);
  ps.setInt(1, ID);
  ps.setString(2, NAME);
  ps.setInt(3, CHI);
  ps.setInt(4, ENG);
  ps.executeUpdate();
  System.out.print("ok");
 
  ps.close();
  conn.close();
  }catch(SQLException e){
  System.out.print("no");
  }
  }
**說明:
1.有些連線會寫在建構式,為了不要占用server資源,執行完就做斷線: ps.close(); conn.close();
2.url的說明
jdbc:mysql:=>確認是否有載入java msyql的驅動程式
//localhost:3306=>主機名稱:port
/school=>資料庫名稱
 
● 沒有輸入資料,空白送出,會出現Exception:數字無法格式化
  private void okMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="insert into student(id,name,chi,eng) values(?,?,?,?)";
 
  try{
  int ID=Integer.parseInt(id.getText());
  int CHI=Integer.parseInt(chi.getText());
  int ENG=Integer.parseInt(eng.getText());
  String NAME=name.getText();
  Connection conn=DriverManager.getConnection(url, user, password);
  PreparedStatement ps=conn.prepareStatement(sql);
  ps.setInt(1, ID);
  ps.setString(2, NAME);
  ps.setInt(3, CHI);
  ps.setInt(4, ENG);
  ps.executeUpdate();
  System.out.print("ok");
 
  ps.close();
  conn.close();
 
  }catch(SQLException e){
  msg.setText("編號不可重複");
  }catch(NumberFormatException e){
  msg.setText("資料不可為空白");
  }
  }
 
**說明:
1.要用catch去捕捉Exception
2.在介面上新增一個label位置(variable name),先不顯示文字
3.將錯誤訊息資料用setText()顯示到介面上
4.因為是在輸入時錯誤,所以getText()都要放到try裡面
5.因為 SQLException只檢查連線到資料庫是否成功和輸入的資料和資料庫設定的規則是否衝突,所以測試連線成功後,後面的catch捕捉到的一定是規則衝突,我們這邊只設定編號不能重複,所以內容可以改為 msg.setText("編號不可重複");
 
●抓資料
1.先做介面,一個顯示button (variable name:show) 和一個顯示文字區域(variable name:ans)
 
2.建立連線,和抓Exception,測試連線ok
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  System.out.print("ok");
  }
  catch(SQLException e){
  }
  }
 
 
3.匯入Statement和ResultSet,透過Connection下的 createStatement()物件來和Statement連接,測試ok
  import java.sql.Statement;
  import java.sql.ResultSet; 
 
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="select id,name,chi,eng from student";
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  Statement st=conn.createStatement();
  System.out.print("ok");
  }
  catch(SQLException e){
  }
**說明:
String sql="select id,name,chi,eng from student";
=> select 欄位名稱 from 資料表名稱(因為已經連上資料庫,所以可以省略資料庫名稱)
 
4.找資料和抓資料
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="select id,name,chi,eng from student";
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(sql);
  rs.next();
  System.out.println("編號:"+rs.getInt("id")+"\t名字:"+
  rs.getString("name")+"\t國文:"+rs.getInt("chi")+"\t英文:"+rs.getInt("eng"));
  System.out.print("ok");
  }
  catch(SQLException e){
  }
  }
**說明:
1.Statement中有一個executQuery(String sql),可以放入sql語法來找資料庫的資料,
但抓出來的資料類型為ResultSet,因為Statement沒有提供顯示的動作,所以要透過ResultSet 中的getxxxx方法來抓資料出來顯示,這樣一個傳給一個就是串接的概念
2. ResultSet 中的next()是用來判斷目前連線是否有資料,有資料會回true,才會跑下面get方法,如果沒有做這個動作就會有Exception
3.getInt(String columLable),代表()內要放欄位名稱且為字串 ex: rs.getInt("id")
4.先用System.out.println在主控台測試輸出一筆資料,目前只能一次輸出一筆資料
 
5.要一次能輸出全部資料
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="select id,name,chi,eng from student";
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(sql);
  while(rs.next()){
  System.out.println("編號:"+rs.getInt("id")+
  "\t名字:"+rs.getString("name")+
  "\t國文:"+rs.getInt("chi")+
  "\t英文:"+rs.getInt("eng"));
  }
  System.out.print("ok");
  }
  catch(SQLException e){
  }
  }
**說明:
第四步驟的做法每次都只能輸出同一筆資料,原因在於判斷哪一筆資料是由rs.next()在做,當此時這筆資料判斷有收到就會執行下一步驟,可是沒有再去判斷下一筆是否有資料,就會一直停留在第一筆,所以變成每執行一次println就要再run一次rs.next(),所以可以用while迴圈來解決這個問題
 
6.改為顯示到使用者介面
while(rs.next()){
  ans.setText("編號:"+rs.getInt("id")+
  "\t名字:"+rs.getString("name")+
  "\t國文:"+rs.getInt("chi")+
  "\t英文:"+rs.getInt("eng"));
  }
**說明:
如果直接這樣改,會只顯示最後一筆,因為每撈出一筆資料就會把上一筆資料給覆蓋過去
 
要做成
 
  import java.util.ArrayList;
 
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="select id,name,chi,eng from student";
 
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(sql);
  ArrayList<String> x=new ArrayList<String>();
  while(rs.next()){
  x.add("編號:"+rs.getInt("id")+
  "\t名字:"+rs.getString("name")+
  "\t國文:"+rs.getInt("chi")+
  "\t英文:"+rs.getInt("eng")+"\n");
  }
  ans.setText(x.toString());
  System.out.print("ok");
  rs.close();
  st.close();
  conn.close();
 
  }
  catch(SQLException e){
  }
  }
 
**說明:
為了避免被下一筆資料蓋過,改用collection的 ArrayList,把資料收集後全部放在x中,這時x是資料集合的物件,所以不能直接 用setText() 把內容顯示出來,要透過toString()把物件轉成字串                             
 
**另一種做法
  private void showMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="select id,name,chi,eng from student";
 
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  Statement st=conn.createStatement();
  ResultSet rs=st.executeQuery(sql);
  String s="";
 
  while(rs.next()){
  String a="編號:"+rs.getInt("id")+
  "\t名字:"+rs.getString("name")+
  "\t國文:"+rs.getInt("chi")+
  "\t英文:"+rs.getInt("eng")+"\n";
  s=s+a;
  }
  ans.setText(s);
  System.out.print("ok");
  rs.close();
  st.close();
  conn.close();
  }
  catch(SQLException e){
  }   
 
**說明:
1.先預設變數s為空值
2.把所有的欄位值丟到變數a(區域變數),再把a丟給s,用setText(s)輸出所有抓出來的資料
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

*JAVA與MYSQL實作
1.先建立新的資料庫=>new schema(產生新的資料庫名稱)
 
2.完成後會在左下角看的到資料庫名稱
 
3.新建table
 
4.設定欄位
PK(primary key):主索引
NN:必填欄位,不可空白
VARCHAR:字元,預設最大45個字元,可調
=>欄位大小寫沒有影響
 
5.設定完成後點左下角的table名稱可以看到欄位標題顯示
 
6.用netbeans建立專案school、student class、做介面
 
7.jDBC
java.SQL.*(和database有關的api都放在這)
Connection=>連線用
DriverManager=>連線用
PrepareStatement
*Connection是interface,不能new,要透過 DriverManager的getConnection把連線丟給 Connection
 
=>import三個class
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
 
8.連mysql的語法如下,但這樣寫完發現會出現exception,所以要加上try...catch
且import java.sql.SQLException;
private void okMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school"; 
  String user="root";
  String password="123456789";
 
  Connection conn=DriverManager.getConnection(url, user, password);
  }
 
 
加上try...catch來檢查資料庫連線是否成功,但還是失敗,因為需要匯入mySQL的驅動程式Connector J,不同程式語言要下載不同的驅動程式
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;  
 
  private void okMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  System.out.print("ok");
  }catch(SQLException e){
  System.out.print("no");
  }
 
  }     
 
匯入驅動程式jar檔
 
匯入後再測試OK,紅色訊息是資料庫的回應,不用管
 
9.建立資料,先設定一個sql語法的變數,insert into 資料表名稱(欄位名,欄位名,...) values(欄位內容,欄位內容,...),這邊?代表先不給之後再輸入,代表任意字元
 String sql="insert into student(id,name,chi,eng) values(?,?,?,?)";
 
10.傳資料給資料庫要用 PreparedStatement,透過connection把資料轉成同樣為 PreparedStatement 類型
新增資料時要用 PreparedStatement下的method(setInt(),setString()),第一個參數代表欄位的位置,第二個參數代表要輸入的內容
  private void okMouseClicked(java.awt.event.MouseEvent evt) {
  String url="jdbc:mysql://localhost:3306/school";
  String user="root";
  String password="123456789";
  String sql="insert into student(id,name,chi,eng) values(?,?,?,?)";
 
  try{
  Connection conn=DriverManager.getConnection(url, user, password);
  PreparedStatement ps=conn.prepareStatement(sql);
  ps.setInt(1, 1);
  ps.setString(2, "kelly");
  ps.setInt(3, 78);
  ps.setInt(4, 65);
 
  System.out.print("ok");
  }catch(SQLException e){
  System.out.print("no");
  }
  }  
 
11.輸入完成後去執行,按ok button在資料庫會查不到資料,因為還要加上 ps.executeUpdate();,把資料庫內容更新
,之後去資料庫看資料表內容,要記得重新整理,就可以看到輸入的資料
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

Generics(泛型)&Collection(集合;收集)=>在java.util
 
●collection=>List-ArrayList( 和陣列一模一樣 )
                            -LinkedList
                  =>Set-HashSet(雜湊)
                           -sort(介面)-TreeSet
**說明
1.List是有順序的,有索引碼,先key先排,可重複資料
2.Set是亂數排序,不允許重複
3.collection、List、Set都是interface
4.sort提供順序
5.Treeset=>資料不允許重複,但有順序
 
(一)Generics(泛型)
1.不定類型
2.<T,E,....>
=>T,E=> 任意英文代號
3.限定使用"WRAPPER"類別與"class"
4.可以用在field、建構式、method
(當要讓使用者在新增時才決定類別時使用)
class Book<T>{
String bookname;
T bookprice;
 
Book(String bookname, T bookprice){
this.bookname=bookname;
this.bookprice=bookprice;
}
 
void show(){
System.out.println("書名:"+bookname+"\t價格:"+bookprice);
}
}
**說明:
1.如果使用者希望價格有時候可以輸入double有時候可以輸入int,改用泛型
2.new的時候由使用者自己定義類型
3.在class name後面寫<任意英文>,要使用泛型的地方都要放一樣的代號
 
class add1{
public static void main(String args[]){
Book<T> b1=new Book<T>("Java",380);
}
}
**說明:
1.如果在new的時候直接在class name後面加上<T>,會出現如上錯誤
2.代表java無法判斷如何新增內容,因為不知道380在這邊應該是甚麼類型,但詳細說明要重新編譯用javac -Xlint add1.java來看,詳細內容如下
3.所以將<T>改為<int>,設定使用者要用int,卻出現錯誤訊息如下,因為需要使用reference=>代表要用class,int是基本類別只能定義變數,要使用wrapper類別(ex:Double,Integer...)才能當作reference,因為wrapper類別既代表整數又有class身分
 
 
正確做法
class add1{
public static void main(String args[]){
Book<Integer> b1=new Book<Integer>("Java",380);
Book<Double> b2=new Book<Double>("android",650);
b1.show();
b2.show();
}
**說明:
但在這邊要注意,如果使用Double這個wrapper類別,輸入時就一定要使用浮點數,不然會出現錯誤訊息,不像基本類別的double可以接受整數
class add1{
public static void main(String args[]){
Book<Integer> b1=new Book<Integer>("Java",380);
Book<Double> b2=new Book<Double>("android",650.3);
b1.show();
b2.show();
}
}
 
多個不定類型時的用法
class Book<T,E>{
String bookname;
T bookprice;
E x;
 
Book(String bookname, T bookprice, E x){
this.bookname=bookname;
this.bookprice=bookprice;
this.x=x;
}
 
void show(){
System.out.println("書名:"+bookname+"\t價格:"+bookprice);
}
}
 
class add1{
public static void main(String args[]){
Book<Integer,Double> b1=new Book<Integer,Double>("Java",380,6.2);
Book<Double,Integer> b2=new Book<Double,Integer>("android",650.3,50);
}
}
 
另外,java7以後改成前面不寫,只寫後面也可以
class add1{
public static void main(String args[]){
Book b1=new Book<Integer,Double>("Java",380,6.2);
Book b2=new Book<Double,Integer>("android",650.3,50);
}
}
 
(二) Collection
1.解決"陣列"數量無法增加的問題
2.將"資料結構"應用寫成"API"應用
3.需搭配"泛型"為"reference"
4.語法:( 收集資料的方式/集合方式要先決定 )
集合方式<類型> 集合物件=new 集合方式<類型>();
=>集合物件指動態陣列
 
a) ArrayList
import java.util.ArrayList;
class add2{
public static void main(String args[]){
ArrayList<Integer> x=new ArrayList<Integer>();
x.add(110);
x.add(20);
x.add(30);
x.add(30);
 
for(Integer o:x){
System.out.println(o);
}
System.out.println("=============");
x.add(20);
x.add(650);
for(Integer o:x){
System.out.println(o);
}
}
}
**說明:
*注意:這邊x的類型是Integer而非 ArrayList, ArrayList是收集資料的方式
1.add()這個方法是從collection繼承給下面所有不同的收集方式,所以全部都可用add()來新增資料
新增資料的方式用add(E)=>看要使用的類型來決定輸入的類型,如上述就是Integer
2.輸入的資料無限制筆數且可重複
3. ArrayList 輸出時的排列方式為,先打進去的資料會排前面
4.ArrayList不能用.length會出現錯誤訊息,所以我們要一個個顯示資料可以用foreach的方式,如果要計算陣列個數則可以用迴圈和count++來做
5.可重複,所以有兩個30
6.可事後增加數量,所以第二次的輸出多兩個內容
7.如果要查記憶體位置,要用x.iterator();這個方法,結果如下:
 
LinkedList
import java.util.ArrayList;
import java.util.LinkedList;
class add2{
public static void main(String args[]){
LinkedList<Integer> x=new LinkedList<Integer>();
x.add(110);
x.add(20);
x.add(30);
x.add(30);
 
for(Integer o:x){
System.out.println(o);
}
System.out.println("=============");
x.add(20);
x.add(650);
for(Integer o:x){
System.out.println(o);
}
System.out.println(x.iterator());
}
}
**說明:
1.要先import class進來
2.輸出結果完全一樣,只有收集資料的方式不同
3. LinkedList和ArrayList差別在於,前者除了list還有一個Queue interface,用途是為了能解省記憶體,但因為java不太管效能,所以很少用
 
HashSet
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashSet;
class add2{
public static void main(String args[]){
HashSet<Integer> x=new HashSet<Integer>();
x.add(110);
x.add(20);
x.add(30);
x.add(30);
 
for(Integer o:x){
System.out.println(o);
}
System.out.println("=============");
x.add(20);
x.add(650);
for(Integer o:x){
System.out.println(o);
}
System.out.println(x.iterator());
}
}
**說明:
順序亂數排列,且不重複
 
TreeSet
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.TreeSet;
class add2{
public static void main(String args[]){
TreeSet<Integer> x=new TreeSet<Integer>();
x.add(110);
x.add(20);
x.add(30);
x.add(30);
 
for(Integer o:x){
System.out.println(o);
}
System.out.println("=============");
x.add(20);
x.add(650);
for(Integer o:x){
System.out.println(o);
}
System.out.println(x.iterator());
}
}
**說明:
由小到大重新排列,且不重複
 
實作
這次要收集的資料類型是一整張表的資料,而非只有integer或double,所以資料類型變成student class(student類型的資料)
(一)ArrayList和 LinkedList
import java.util.ArrayList;
import java.util.LinkedList;
 
class student {  
private String name;
private int chi;
private int eng;
 
student(String name,int chi,int eng){
this.name=name;
this.chi=chi;
this.eng=eng;
}
 
void show(){
System.out.println("名字:"+name+"\t國文:"+chi+"\t英文:"+eng);
}
 
class add3{
public static void main(String args[]){
//ArrayList<student> s=new ArrayList<student>();
LinkedList<student> s=new LinkedList<student>();
 
s.add(new student("aa",85,77));
s.add(new student("aa1",85,77));
s.add(new student("aa2",86,78));
for (student o:s){
o.show();
}
}
}
 
**說明:
1.用 ArrayList和 LinkedList輸出結果相同
2. 在new的時候,這邊變成要新增一個學生物件 new student("aa",85,77) ,而非一個值
3. foreach的類型也要是student,因要和s同樣類型 因為把s指給o,所以o也是一個物件,可以直接用o.show()
 
(二)用HashSet,資料不重複
class add3{
public static void main(String args[]){
HashSet<student> s=new HashSet<student>();
s.add(new student("aa",85,77)); 
s.add(new student("aa1",87,97));
s.add(new student("aa2",83,67));
for (student o:s){
o.show();  
}
}
}
**說明:
1.用 HashSet亂數排序
2. 是否重複是看記憶體位置,只要有new就不會重複記憶體位置
 
(三)用HashSet,資料重複
class add3{
public static void main(String args[]){
HashSet<student> s=new HashSet<student>();
s.add(new student("aa",85,77)); 
s.add(new student("aa",85,77));
s.add(new student("aa",85,77));
 
for (student o:s){ 
o.show();  
}
}
}
**說明:
因為HashSet判斷是否重複是由記憶體位址來判斷,而非由輸入的值來判斷,所以還是會有三筆資料
 
(四)用TreeSet
class add3{
public static void main(String args[]){
TreeSet<student> s=new TreeSet<student>();
s.add(new student("aa",85,77)); 
s.add(new student("aa",85,77));
s.add(new student("aa",85,77));
 
for (student o:s){ 
o.show();
}
}
}
**說明:
1.改用TreeSet,可以compiler但是執行出現Exception
2.因為這邊是物件無法直接排序,要排序的話要由現有的欄位中抓一個欄位當作索引欄位(要告訴他要由哪個欄位來排順序)
 
 
正確做法:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.TreeSet;
 
class student implements Comparable<student>{  
private String name;
private int chi;
private int eng;
 
student(String name,int chi,int eng){
this.name=name;
this.chi=chi;
this.eng=eng;
}
 
void show(){
System.out.println("名字:"+name+"\t國文:"+chi+"\t英文:"+eng);
}
public int compareTo(student o){
return this.chi-o.chi;
}
}
 
class add3{
public static void main(String args[]){
TreeSet<student> s=new TreeSet<student>();  
s.add(new student("aa",85,77));
s.add(new student("aa",85,77));
s.add(new student("aa",85,77));
  
for (student o:s){
o.show();
}
}
}
 
**說明:
1. 要繼承comparable interface(用implements),<>中要放要排序的類型物件,因為comparable是泛型
2.因為繼承interface的compareTo()方法,所以要override,故前面要加public和繼承的int,copareTo()裡面要放本身物件(student),和下一個物件(o)
3.return時,this是物件本身,o是指下一個物件,這邊要指定欄位用國文分數(chi),
4.語法:this-o,如果:>0由小到大排列,<0由大到小排列,=0不變
5.通常當主索引欄不會重複且可以判斷先後順序者,會用TreeSet來做
6. TreeSet排列是用指定的欄位值來判斷,這邊指定國文分數來判斷,此時三者相同,所以判斷重複,最後會輸出一筆
7.如果改為如下,就會輸出三筆並且照國文分數由小到大排列
s.add(new student("aa",86,77));
s.add(new student("aa",88,77));
s.add(new student("aa",85,77));
 
●泛型與多型應用
1.泛型
2.多型
=>陣列:數量無法增加;集合:可增加(又稱為動態陣列)
 
 
 
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.HashSet;
import java.util.TreeSet;
 
class student implements Comparable<student>{
private String name;
private int chi;
private int eng;
 
student(String name,int chi,int eng){
this.name=name;
this.chi=chi;
this.eng=eng;
}
 
void show(){
System.out.print("名字:"+name+"\t國文:"+chi+"\t英文:"+eng);
}
public int compareTo(student o){
 
return this.chi-o.chi;
}
}
 
class A extends student{
private int word;
A(String name,int chi, int eng ,int word){
super(name,chi,eng);
this.word=word;
}
void show(){
super.show();
System.out.println("\tword:"+word);
}
}
 
class B extends student{
private int excel;
B(String name,int chi, int eng ,int excel){
super(name,chi,eng);
this.excel=excel;
}
void show(){
super.show();
System.out.println("\texcel:"+excel);
}
}
 
class add3{
public static void main(String args[]){
ArrayList<student> s=new ArrayList<student>();  //定義父類別(的資料收集方法)
 
s.add(new A("aa",86,77,88));   //new子類別
s.add(new A("aa2",88,77,76));
s.add(new B("bb",85,77,87));
 
for (student o:s){
o.show();
}
System.out.println("=============");
s.add(new A("aa3",67,87,96));
s.add(new B("bb2",73,84,97));
 
for (student o:s){
o.show();
}
}
}
**說明:
1.在做輸入資料的介面時不可能鎖死資料筆數,所以要用集合不能用陣列
2.這邊只要A和student有繼承關係就能 s.add(new A("aa",86,77,88));
3. for (student o:s)=>forecach的reference還是看student,因為s的reference是student
4.和多型一樣,也是先定義父類別然後new子類別
5.做法和陣列完全一樣,只是改為集合,數量可以增加,陣列的作法為
  student s(定義父類別)={new A("aa3",67,87,96),new B("bb2",73,84,97)};(new子類別)
6.可以事後增加資料
7. 此時還沒有索引碼,所以還沒辦法直接用索引碼找資料
 
3.先用集合建立,再透過Object[]陣列=>集合toArray();  (不一定要做這個步驟)
=>轉回陣列=>製作索引碼
class add3{
public static void main(String args[]){
ArrayList<student> s=new ArrayList<student>();
 
s.add(new A("aa",86,77,88));
s.add(new A("aa2",88,77,76));
s.add(new B("bb",85,77,87));
 
Object[] x=s.toArray();
System.out.println(x[0]);  //輸出記憶體位址
//x[0].show(); //出現如下錯誤
((student)(x[0])).show();
}
}
 
**說明:
1.要把s集合的內容轉為x陣列
2.toArray()會轉成物件類型Obtect class(所有class的共同父類別)
3.如果直接用x[0].show()會找不到,因為編譯時會先去x找show()方法,但x是Object類型,會找不到
4.要把x[0]轉型為student類型(toArray一開始會先把類別拉到最上層(即所有class的父類別Object),所以要再降為目前的類型),把 x[0].show();改為((student)(x[0])).show();即可
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●Exception
1)執行上的錯誤=>bug處理
2)捕捉exception
=>try{ ...}catch(異常類型  物件名) {....}
3)多重捕捉
=>try{...} catch(異常類型  物件名) {....}
 
4)exception api分類
throwable
=>error
    =>stackOverFlow(遞迴)
    =>....                 
=>exception
    =>RuntimeException
    =>(非 RuntimeException
**說明:
1. java.lang.throwable=>只做兩個動作1.中斷2.拋訊息,其他條件都由繼承的子類別來做
2.error=>嚴重錯誤
3.exception=>異常=>可不修改程式碼=>加說明
4. RuntimeException=>JRE設定好,自動檢查(自動捕捉),可不加 try{ ...}catch() {....}也可
=>unchecked,可以編譯,不用捕捉也看的到,只是使用者不知道
5. RuntimeException=>JRE沒有設定自動捕捉訊息=>一訂要加 try{ ...}catch() {....}
=>checked=>不能編譯,要加try{}catch(){}才能編譯,即要自己做檢查機制
6.建構式中如果有throws,會啟動該throw下的exception去檢查
 
import java.util.Scanner;
class ex1{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for(int i=0;i<n;i++){
     System.out.println("hello");
}
}
}
**說明:
1.java.util.InputMismatchException這個exception是runtime的
2.查的方式是去api看Scanner下的nextInt(),有一個throws,下面有exception
3.點任何一個exception進去看,可以看到繼承關係,這些都是屬於RuntimeException
 
 
舉例
import java.util.Scanner;
class ex1{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
try{
System.out.println("請輸入陣列數量");
int m=sc.nextInt();
int[] x=new int[m];
System.out.println("請輸入索引號碼");
 //new java.util.InputMismatchException()
int n=sc.nextInt();        
 //new java.lang.IndexOutOfBoundsException() 
x[n]=100;                            
//new java.lang.ArithmeticException()
System.out.println(10/n);
for(int i=0;i<n;i++){
     System.out.println("hello");
}
}catch(java.util.InputMismatchException e){
     System.out.println("輸入整數");
}catch(java.lang.ArithmeticException e){
     System.out.println("分母不可為0");
}
catch(java.lang.IndexOutOfBoundsException e){
     System.out.println("索引號碼錯誤,要n-1");
}
}
}
**說明:
當出現異常的時候,其實就是在那個步驟時,new了一個exception(因為exception是class=>是物件),然後new完的建構式去做中斷和丟訊息的動作,當出現catch時,就會等待直到把exception物件丟給指定的變數這個例子的指定變數為e),收到以後就會轉換成去執行catch內的內容
 
5)非RuntimeException(編譯時就會提醒你)
a)一定要捕捉,方式有二
=>try....catch
=>throws(拋出)
b)一般定義在2個部分
=>constructors
=>methods
 
舉例,使用java.io.File=>class File是用來開檔案或資料夾
=>會先chk是否有一樣的檔名,true or false,有一樣就不動作,沒有就產生新的檔,有Exception
=>為非runtimeexception
import java.io.File;
class ex2{
public static void main(String args[]){
//在c下面新增一個txt檔,這裡只是先new物件,產生檔案要用method
File f=new File("c:/a.txt");
f.createNewFile();
}
}
 
**說明:
1.編譯時產生error,所以要改程式碼
2.錯誤訊息:需要被捕捉(try....catch...)或被拋出(throws)
3.因為有IOException,但沒有跟編譯器說要怎麼處理
 
作法一:try...catch自己寫說明
import java.io.File;
import java.io.IOException;
class ex2{
public static void main(String args[]){
try{
File f=new File("c:/a.txt");
f.createNewFile();
}catch(IOException e){
     System.out.println("無法新增");
}
}
}
**說明:
會出現無法新增,因為c:會有權限問題無法寫入,把寫入位置改為c:/java/14/a.txt即可
 
作法二:throws,不用寫說明
mport java.io.File;
import java.io.IOException;
class ex2{
public static void main(String args[]) throws IOException{
File f=new File("c:/a.txt");
f.createNewFile();
}
}
 
**說明:
1.改用throws,就是在method後面加上throws 異常類別,如上,如果有多個,可用","隔開
2.用throws以後編譯可過,執行時會自動出現說明,但只有dos介面看的到,一般使用者視窗介面就看不到
3.有時用在檢查程式,判斷是否之後要寫說明
 
c)自訂Exception(非RuntimeException)
1.使用 Exception(針對方法) (Exception要在main執行時用)
=>內容
     =>使用if(沒有中斷機制)
     =>throw new Exception();
=>方法或建構式:throws Exception
用if但不加exception
class student{
String name;
int chi;
int eng;
student(String name,int chi,int eng) {
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.name=name;   
this.chi=chi;
this.eng=eng;
}
}
void show(){
System.out.println("名:"+name+
"\t國文:"+chi+
"\t英文:"+eng
);
}
}
class add{
public static void main(String args[]){
student[] s={
new student("kent",200,91),
new student("maggie",86,92),
new student("derek",85,93)
};
for(int i=0;i<s.length;i++){
s[i].show();
}
}
}
**說明:
1.用if在建構式先做判斷,沒有加else,所以如果超過這個範圍就不更新資料,用初始值
2.但是當輸入的內容超過範圍,程式還是會跑完全部,而非停在出錯的 new student("kent",200,91)
3.如過用exception就會在出錯的 new student("kent",200,91)停止,不會繼續run,當後面資料和前面資料有關聯時,用exception比較適合
用exception+if
class student{
String name;
int chi;
int eng;
student(String name,int chi,int eng) throws Exception {
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.name=name; 
this.chi=chi;
this.eng=eng;
}else{
throw new Exception();   
}
}
void show(){
System.out.println("名:"+name+
"\t國文:"+chi+
"\t英文:"+eng
);
}
}
**說明:
1.exception要搭配if來使用,放在else中,代表如果沒有符合條件,就把exception()這個物件丟出去給使用student建構式的人
2.但假設沒有在 student(String name,int chi,int eng)後面加上 throws Exception,就會出現如上錯誤訊息,代表需要捕捉或拋出
3.所以要在 student(String name,int chi,int eng)後面加上 throws Exception,代表從student拋出去
4.thorows Exception是在等else裡面的new Exception產生
5.如果在else{}中只寫new Exception(),前面沒有加throw,會只在else{}中產生沒有辦法丟出去,因為生命週期,所以要加上throw才能丟出去給建構式外的throws接收 
** 這邊的Exception其實是用java.lang.Exception class(裡面有包含自訂exception的功能)
使用我們自己訂的Exception
class add{
public static void main(String args[]){
student s1=new student("kent",87,91);
}
}
**說明:
在main執行我們自己做的exception,也是要捕捉,不然會出現錯誤,因為非runtime
 
class add{
public static void main(String args[]){
try{
     student s1=new student("kent",87,91);
}catch(Exception e){
}
}
**說明:
所以要用try...catch或throws
使用try...catch和throws兩個的差別     
 
class student{
String name;
int chi;
int eng;
student(String name,int chi,int eng) throws Exception{
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
     }else{
         throw new Exception();
     }
}
student(int chi,int eng) {
try{
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.chi=chi;
this.eng=eng;
}else{
     throw new Exception();
}
}catch(Exception e){
     System.out.println("國文英文分數,0~100");
}
 
}
void show(){
System.out.println("名:"+name+
"\t國文:"+chi+
"\t英文:"+eng
);
}
}
 
(狀況一:add沒有加 throws Exception 或 try...catch)
class add{
public static void main(String args[]){
     //因為main沒有加throws Exception所以compiler會出現錯誤
     //student s1=new student("kent",870,91); 
    //出現 國文英文分數,0~100
student s2=new student(870,91);        
     }
}
 
(狀況二:add有加throws Exception 或 try...catch)
class add{
public static void main(String args[]){
    try{
student[] s={
new student("kent",87,91),   //see 說明4.
new student(86,92),          //see 說明5.
new student("derek",85,93),
};
for(int i=0;i<s.length;i++){
     s[i].show();
}
}catch(Exception e){
     System.out.println("分數:0~100");
}
}
}
**說明
1.如果在寫建構式或方法時,exception是透過throws Exception來處理,則解說要在執行的時候寫在main裡=>此時如果main方法沒有寫throws Exception,編譯就會過不了
2.也可以在寫建構式或方法時, exception 不要透過throws Exception來處理,而是直接在建構式中寫好解說(try...catch寫在建構式中),可以編譯
3.通常contructor會用try...catch加在裡面,method會用throws Exception的方式
4.在狀況二中,若改為 new student("kent",-87,91),會outputs "分數:0~100"
5.但在狀況二中,若改為 new student(-86,92),則會outputs如下內容,先在輸入-86那筆資料的建構式做中斷,然後其他資料還是繼續可以跑,並且跑下面的迴圈,因為try...catch寫在建構式中,生命週期在該筆資料寫入後就結束了,不影響其他筆資料的輸入
**在建構式中的try catch是針對每一筆填入的資料中斷,其他筆資料會繼續做,但放在main中就要確定全部資料都對不然就會中斷不能再填資料,通常前者的用法會用在web讓user填寫資料,因為會同時多人一起進行,不能一個寫錯就全部中斷,只能針對每一筆資料做判斷不影響其他筆資料
例:
假設此時有兩個method,但規則不同,如果同時有兩個不同method出現Exception該如何判斷catch要抓哪個?
 
class student2{
String name;
int chi;
int eng;
student2(String name,int chi,int eng) {
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
}
}
int sum1(int chi,int eng) throws Exception{
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.chi=chi;
this.eng=eng;
     return chi+eng;
}else{
     throw new Exception();
}
}
int sum2(int chi,int eng) throws Exception{
if(chi>=0 &&chi<=200 && eng>=0 &&eng<=200){
this.chi=chi;
this.eng=eng;
return chi+eng;
}else{
     throw new Exception();
}
}
void show(){
System.out.println("名:"+name+"\t國文:"+chi+ "\t英文:"+eng );
}
}
 
class add2{
     public static void main(String args[]){
student2[] s={
new student2("kent",87,91),
new student2("maggie",86,92),
};
for(int i=0;i<s.length;i++){
     s[i].show();
}
try{
     System.out.println(s[0].sum1(60,90)+s[0].sum2(70,80)+s[1].sum1(60,90)+s[1].sum2(70,80));
}catch(Exception e){
     //同時違反兩個規則時,如何判斷要show 0~100 或 0~200
     System.out.println("0~200");  
}
}
}
 
**說明:
1. 要修改分數後再加總,要兩個人都對了才能加總,
2.通常exception都會用在傳值類的method
3.用自訂Eexception
4.要把不同method的檢驗機制放進Exception中,但Exception只能中斷,不過可以提供繼承,把中斷功能繼承給子類別,見下方說明
2.繼承Exception=>自訂Exception Class
class check extends Exception{
check (String msg){
     System.out.println("需介於"+msg);
}
}
 
class student2{
String name;
int chi;
int eng;
student2(String name,int chi,int eng) {
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
}
}
int sum1(int chi,int eng) throws check{
if(chi>=0 &&chi<=100 && eng>=0 &&eng<=100){
this.chi=chi;
this.eng=eng;
return chi+eng;
}else{
     throw new check("0~100");
}
}
int sum2(int chi,int eng) throws check{
if(chi>=0 &&chi<=200 && eng>=0 &&eng<=200){
this.chi=chi;
this.eng=eng;
return chi+eng;
}else{
     throw new check("0~200");
}
}
void show(){
System.out.println("名:"+name+
"\t國文:"+chi+
"\t英文:"+eng
);
}
}
 
class add2{
public static void main(String args[]){
student2[] s={
new student2("kent",87,91),
new student2("maggie",86,92),
};
for(int i=0;i<s.length;i++){
     s[i].show();
}
try{
     System.out.println(s[0].sum1(60,80)+s[0].sum2(70,280)+s[1].sum1(60,90)+s[1].sum2(70,80));
}catch(check e){  
}
}
}
**說明:
1. check已經自動繼承Exception的中斷功能
2.要記得把class Exception都改成class check,因為已經繼承了改使用class check
3.catch(check e),這邊如果改成Exception e也可以,而因為多型的概念(Exception 是所有自訂Exception class的共同父類別)=>多型的宣告方式;Exception e=new check(),這邊又是e=new check(),所以換成Exception e也會正確執行
**實例
=>業績<500000時,獎金比=0
=>業績>=500000時,獎金比=0.03
class check1 extends Exception{
check1(String msg){
     System.out.println(msg);
}
}
 
class money {
private String name;
private int x;
private int m;
 
money(String name,int x) throws check1{
if(x>=0){
this.name=name;
this.x=x;
if(x>=500000){
     m=(int)(18000+x*0.03);
}else{
     m=18000;
}
}else{
     throw new check1("業績需大於0");
}
}
 
     void show(){
     S     ystem.out.println("名:"+name+"\t業績:"+x+"\t實領薪資:"+m);
     }
}
class add3{
public static void main(String args[]) throws check1{
     money m1=new money("kelly",560000);
     m1.show();
}
}
**說明:
因為在check1中已經有寫說明了,所以在main程式中不需要再用try...catch來寫說明
同上例,如果事後想要修改業績,因為x為private,所以要寫method來改
void change(int x) throws check1{
if(x>=0){
this.name=name;
this.x=x;
if(x>=500000){
     m=(int)(18000+x*0.03);
    }else{
          m=18000;
    }
}else{
     throw new check1("業績修改需大於0");
}
}
 
class add3{
public static void main(String args[]) throws check1{
money m1=new money("kelly",560000);
m1.show();
m1.change(-6000);
m1.show();
}
}
 
**說明
1.加一個change() method,一樣要做判斷,調整一下判斷顯示的訊息
2如果用錯誤的業績數字輸入修改,此時會自動抓取change()中的判斷
3.outputs為 業績修改需大於0
 
 
 
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

1.CAL.jar
2.說明文件
ARea(長,寬)=>矩形面積
CARea(半徑)=>圓面積
FV(本金,利率,年)=>本金*(1+利率)
money(業績)=>獎金比
50萬以上     3%
0~50萬       0
 
本薪=18000
本薪+獎金
*有畫底線所以都是static的
 
●結合昨天的homework.jar和使用者介面
1. 設計版面
2.先匯入昨天完成的jar檔,還要import進來,設定button clicked
3.double要用Double.parseDouble(); 如果要轉字串也可以用String.valueOf()
4.加入程式碼
  private void cal1MouseClicked(java.awt.event.MouseEvent evt) {
  double H=Double.parseDouble(h.getText());
  double W=Double.parseDouble(w.getText());
  area.setText("面積:"+math.ARea(H, W));
  }
 
  private void cal2MouseClicked(java.awt.event.MouseEvent evt) {
  double R1=Double.parseDouble(r1.getText());
  carea.setText("圓面積:"+math.CARea(R1));
  }
 
  private void cal3MouseClicked(java.awt.event.MouseEvent evt) {
  int P=Integer.parseInt(p.getText());
  double R2=Double.parseDouble(r2.getText());
  int Y=Integer.parseInt(y.getText());
  fv.setText("總計:"+company.FV(P, R2, Y));
  }
 
  private void cal4MouseClicked(java.awt.event.MouseEvent evt) {
  int M=Integer.parseInt(m.getText());
  money.setText("實領:"+company.money(M));
  }
 
 
5.完成畫面
 
*小數位數的問題可回到CAL.math去修改,重新轉jar就可以用,不需要再import一次
 
*把text field=>properties=>enable勾取取消,則user不能輸入
 
 
6.轉成可執行檔,先在這個完成的介面專案的properties選run,指定main class的位置,再clean and build 一次就可以直接開啟該.jar檔
 
*如果到別台電腦不能開啟這個執行檔,應該是因為沒有安裝jre
 
●Java常用api
1.java.lang.*
2.exception/error(異常)(bug)
(一)執行上的錯誤
a)error=>程式碼直接重寫
b)exception=>加錯誤訊息,一般api文件都會加上exception
**與if最大差別,exception會強制中斷程式執行
 
(二)異常訊息的捕捉
try{
     有問題的程式碼...
}
catch(異常類型  物件變數)
{
     要顯示的錯誤訊息
}
import java.util.Scanner;
class ex1{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
     for(int i=0;i<=10;i++)
     {
          System.out.println("i="+i+"\thello");
     }
}
}
**說明:
假設輸入的是小數,出現exception如上
1.代表在執行nextInt()時就出現錯誤(ex1.java:5代表錯誤在第5行),此時就中斷程式不會在往下run for...
2.exception in thread "main" java .util.InputMismatchException;=>執行緒 main出現exception,是被 java .util.InputMismatchException發現的
3.at...,代表這四個scanner的功能都有加上 java .util.InputMismatchException 這個文件的檢查功能
 
正確做法
import java.util.Scanner;
import java.util.InputMismatchException;
class ex1{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
try{
int n=sc.nextInt();
for(int i=0;i<=10;i++)
{
     System.out.println("i="+i+"\thello");
}
}catch(InputMismatchException e){
     System.out.println("請輸入整數");
}
}
}
**說明
1.在 sc.nextInt()這邊中斷的時候,會new一個exception,再透過"e"這個物件變數抓下來
2.有問題的程式碼一定要放在try裡面不然會抓不到
 
(三)多個異常訊息的捕捉,但是單選,只要有一個符合就會中斷程式
try{程式碼....}
catch(異常1 物件){....}
catch(異常2 物件){....}
import java.util.Scanner;
import java.util.InputMismatchException;
class ex1{
public static void main(String args[]){
     Scanner sc=new Scanner(System.in);
try{
int n=sc.nextInt();
System.out.println("10/n"+10/n);
for(int i=0;i<=10;i++)
{
     System.out.println("i="+i+"\thello");
}
}catch(InputMismatchException e){
     System.out.println("請輸入整數");
}
}
}
 
**說明:
如果輸入0,會被java.lang.AbstractMethodError抓出來整數不能為0的問題
 
正確
import java.util.Scanner;
import java.util.InputMismatchException;
class ex1{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
try{
int n=sc.nextInt();
System.out.println("10/n"+10/n);
for(int i=0;i<=10;i++)
{
System.out.println("i="+i+"\thello");
}
}catch(InputMismatchException e){
     System.out.println("請輸入整數");
}catch(AbstractMethodError e){
     System.out.println("分母不能為0");
}
}
}
**說明:
e為區域變數所以不會互相影響
 
3.泛型&集合 collection=>8/11
4.io(input/output)=>保留資料
=>file/database
5.thread 執行緒
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●package套件(資料夾)
public =>可開放權限到不同套件(資料夾)
protected =>可開放權限到不同套件
deafult=>可開放權限到同一個套件
private =>可開放權限到同一個class
import(只要不是放在java.lang全部都要import)=>但import進來不一定要用來做繼承
 
*實作案例
UML:(#:protected)
1.先建立資料夾
=>專案下很多個資料夾,用dos去編譯會習慣停在專案的最上層位置,然後編譯時指定路徑
 
**做interface student2的說明
a.指定路徑要在最前面加上package,這樣java才找的到路徑,從專案最上面開始寫 ,如:package school.stu;
b.這就是一個school專案,找的方式是school中的stu中的student2.class
c.以後做資料夾要習慣在最前面指定路徑
2.開始寫 A.class
狀況一:
A.java
package school.sa;
class A extends student {
     private int chi;
}
**說明
1.如果如上作法,會發現錯誤訊息,代表找不到student class,因為java會先去school.sa找這個class,找不到就會去java.lang找,但還是找不到就出現上述訊息
2.所以要指定路徑,使用import,寫在package和class中間
3.寫import要寫到class name為止
 
正確寫法:
A.java
package school.sa;
import school.stu.student;
class A extends student {
     private int chi;
}
 
狀況二
A.java
package school.sa;
import school.stu.student;
class A extends student {
     private int chi;
}
**說明
1.import後還是出現錯誤訊息,因為要對方授權了才能使用student class(因為在不同資料夾)
2.所以在student class前加上public=>public class student{...}
 
狀況三
**說明
1.開放了student class的權限以後,還是有錯誤訊息,因為student的建構式不是public,super不能存取不同套件的建構式()
2. 查完class就會去查建構式所以要一起改不然無法繼承,所以改成public student(String name){ this.name=name; }
 
implements student2的做法比照上述辦理
student2.java
package school.stu;
public interface student2{  }
 
A.java
package school.sa;
import school.stu.student;
import school.stu.student2;
class A extends student implements student2{....}
 
**說明
A.class要implements interface student2也是如上做法,先import並開放權限
 
2.寫B.class,做法與A.class同,留意資料夾位置即可
B.java
package school.sb;
import school.stu.student;
import school.stu.student2;
 
class B extends student implements student2{
private int eng;
B (String name,int eng){
super(name);
this.eng=eng;
}
}
 
3.先測試一下上述內容,編寫main程式
狀況一
add.java
package school.main;
class add{
public static void main(String args[]){
     student s=new student("kent");
}
}
**說明
1.出現錯誤訊息,找不到student class
2.所以要加入import school.stu.student;
 
狀況二
//要測試show()功能
add.java
package school.main;
import school.stu.student;
class add{
public static void main(String args[]){
student s=new student("kent");
System.out.println(s.show());
}
}
**說明
1.加了以後還是有錯誤訊息,因為show()的權限還沒開放
2.即使在class前面加了public也不代表裡面的內容都一起開放權限了,要改成如下:
public String show(){ return "名:"+name; }
3.在dos執行時,寫路徑的方式要調整,因為要送到java虛擬主機,所以要寫成java  school.main.add
 
class A比照 class student辦理
A.java
package school.sa;
import school.stu.student;
import school.stu.student2;
public class A extends student implements student2{
private int chi;
public A(String name,int chi){
super(name);
this.chi=chi;
}
}
 
add.java
package school.main;
import school.stu.student;
import school.sa.A;
class add{
    public static void main(String args[]){
student s=new student("kent");
System.out.println(s.show());
A a=new A("MAGGIE",80);
System.out.println(a.show());
}
}
**說明
1.要先import A的路徑
2.在A class和A的建構式前面加上public
 
4.把A.class對父類別做override
A.java
package school.sa;
import school.stu.student;
import school.stu.student2;
 
public class A extends student implements student2{
private int chi;
public A(String name,int chi){
super(name);
this.chi=chi;
} public String show(){
     return super.show()+"\t國文:"+chi;
}
}
**說明:
add.java不用改,就可輸出=>名:MAGGIE   國文:80
 
5. 把B.class對父類別做override
B.java
package school.sb;
import school.stu.student;
import school.stu.student2;
 
public class B extends student implements student2{
private int eng;
public B (String name,int eng){
super(name);
this.eng=eng;
}
public String show(){
     return super.show()+"\t英文:"+eng;
}
}
 
**說明:
1.add.java加入下述內容
B b=new B("may",87);
System.out.println(b.show());
2輸出=>名:may   英文:87
 
6.完成A_1.class,並在add測試
A_1.java
package school.sa;
import school.stu.student2;
 
public class A_1 extends A implements student2{
private int math;
public A_1(String name,int chi,int math){
super(name,chi);   
this.math=math;
}
public String show(){
     return super.show()+"\t數學:"+math;
}
}
 
add.java
package school.main;
import school.stu.student;
import school.sa.A;
import school.sb.B;
import school.sa.A_1;
class add{
public static void main(String args[]){
student s=new student("kent");
System.out.println(s.show());
 
A a=new A("MAGGIE",80);
System.out.println(a.show());
 
B b=new B("may",87);
System.out.println(b.show());
 
A_1 a1=new A_1("ANDY",65,91);
System.out.println(a1.show());
       }
}
 
**說明:
1.因為A_1和A放在同一個資料夾,所以不需要import A
2.add也要記得import A_1
3. A_1的建構是繼承A,要記得super()中是兩個引數
 
**注意:
假設把A_1 class放到A.java下會出現下列訊息
因為當有package時,多個class要寫在同一個檔,只能有一個public,如果要寫另外public一個要重新宣告一個檔
 
protected的說明,在studetn class加上一個protected的show2()
student.java 加上
protected String show2(){
return "name:"+name;
}
 
A.java 改成
public String show(){
return show2()+"\t國文:"+chi;
}
 
add.java 加上
student s=new student("kent");
System.out.println(s.show2());
執行時=> 出現錯誤訊息
 
正確做法 
add.java
A a=new A("MAGGIE",80);
System.out.println(a.show());
 
**說明:
1.protected和public都可以透過import來給不同資料夾的class使用
2.兩者的差別在於使用時,protected限定給子類別繼承用,沒有開放透過new物件的方式來存取,所以要使用就要寫一個子類別去繼承他來用
3.所以用a.show()就不會有問題,因為在A class已經繼承show2()來用
 
● 用netbeans做上述例子
1.建立school_2專案,這邊的是專案名稱,而非上述的package最上層名稱
2.在src下=>new=>java package,把資料夾建立好
3.在資料夾下新增class:
interface:new=>java interface
一般class:new=>java class
4.輸入程式碼
**找錯誤可以直接看紅色燈泡,或是點可以在主控台看詳細的錯誤訊息
**view=>show line-numbers勾選才會出現行數編號
**view=>show non-printable characters如果勾選會如下圖,出現段落標記符號
*@override,代表下方的method有作override,可加可不加
● 製作
1.做JAR檔
2.寫說明文件,註解寫法/**..../,因為要給人家用的是建構式和method(field鎖死了),所以寫在建構式前面
/**
*@參數(ex:author/version/para)
*/
3.練習
package school.sa;
import school.stu.student;
import school.stu.student2;
/**
 *
 * @author:maggie
 * @version:1.0
 * @學員管理系統<br>測試一下換行
 *
 */
public class student {
  private String name;
  public student(String name){
  this.name=name;
  }
/**
 *
 * @return:return the name user input
 */
  public String show(){
  return "名:"+name;
  }
 
說明:
1.之後轉黨會自動轉成html格式,所以可套用html語法ex:斷行要用<br>不是直接按enter,但不可套css
2.package和import不需要說明,所以說明要寫在package和class中間
3.說明要放在要解說的建構式或method前,只要打/**+enter就會自動跳出註解
 
4.轉檔:project名稱上按右鍵=>generate javadoc
=>預設會用ie打開這個轉好的檔案,如果沒有打開,可以到專案資料夾(school2)下的dist/javadoc找index.htm
=>return的說明出現了,但是@author和@version的說明沒出現
 
5.因為預設@author和@version是關閉的,所以要在專案上按右鍵=>properties=>Documenting=>勾選這兩個選項後才會出現
=>也可在這邊設定private是否要顯示,和設定瀏覽器上的網頁名稱
=>設定好關閉ie,重新做generate javadoc
 
**API=>Application Interface/應用程式介面(ex:Netbeans,eclipse)
實際上我們在用的應該是API的函式庫,就是放在jdk/lib下的內容
我們寫出來的class最後也會轉成jar檔(一個封裝壓縮檔,裡面放很多class)
 
7.轉為jar檔,先全部重新編譯一次,按上方的掃把工具,或是在project上面按右鍵選clean and build,下方出現此訊息代表轉檔完成
8.轉檔完後會把dist下的javadoc刪除,所以轉檔完後要再generate javadoc一次,要用的時候就把*.jar和javadoc一起copy出來用
 
9.要拿來使用,先開一個全新的project test,然後新增一個main.java
=>假設我們想要用student的show()功能,直接import school.stu.student;會出現找不到(因為是去java.lang找)
=>要在專案右鍵選properties=>Libraries=>Add JAR/Folder 指定jar檔的路徑
以後自己寫好的jar都可以這麼做
=>如果要用A就要import A, 要用B就要import B
 

  ● wrapper類別(包覆類別)
針對基本類別設計一個class出來,可以定義普通變數,也可以提供method(因為本身是class),有些甚至有建構式
=>這些method主要拿來轉型(casting)用(ex:字串轉整數)
=>在java.lang可查
ex:
Byte x=10; 和 byte x=10; 兩個一樣都只是用來定義普通變數
parseByte(String s)=>把String 轉成 byte等級的類型
=>通常是拿來把字串轉其他類別,因為鍵盤輸入的都是字串
 
ex:以昨天的netbeans練習為例 
  String Name=name.getText();
  //Interger class下的parseInt()method
  int Chi=Integer.parseInt(chi.getText());
  int Eng=Integer.parseInt(eng.getText());
  System.out.println("姓名:"+Name+
  "\n國文:"+Chi+
  "\n英文:"+Eng+
  "\n總分:"+(Chi+Eng));
  
● jar檔
靜態=>將class功能import來用
動態=>有main程式,可以直接操作
 
● 昨天範例要顯示加總內容,使用setText():void,內容限定字串(輸出輸入都要是字串,只有中間計算才轉換類型)
1.先把panel和textarea使用者畫面設計好,variable name設定為show
2.把原本的System.out.println改為show.setText();
  String Name=name.getText();
  int Chi=Integer.parseInt(chi.getText());
  int Eng=Integer.parseInt(eng.getText());
  show.setText("姓名:"+Name+
  "\n國文:"+Chi+
  "\n英文:"+Eng+
  "\n總分:"+(Chi+Eng));
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

●生命週期;reference
1.field=>變數
a)local/global=>this
b)物件類=>"new"物件存取=>每個物件都有自己的屬性
c)類別類=>static=>類別直接存取
=>不須"new"物件存取
=>只產生一次,所有物件共同使用的屬性(絕對位址)
*參考程式碼java/11/add1.java
 
2.method=>方法
a)傳值/不傳值(可當值來用)
b)物件類=>需透過"new"物件存取
c)類別類=>static
=>不須透過"new"物件存取
=>類別(class)直接存取
*參考程式碼java/11/add1.java
 
3.內部類別inner class(nested class)
=>一定要全部的class寫在同一個*.java檔案,不能分開寫,但編譯的時候每一個class會自動編譯成獨立的*.class檔
=>主要目的是為了好管理,一個檔案可以管理好幾個class
=>先確定外部類別outer class
=>不是繼承(是獨立的),所以不能結合多型
add2.java
class student2{
class A{
}
}
class add2{
public static void main(String args[]){
}
}
=>A是S2的內部類別,S2是A的外部類別,將add2.java編譯後,會產生三個*.class檔,其中student2$A.class就代表,A是student2的內部class
 
a)物件類內部類別
=>先"new"外部類別物件再"new"內部類別物件
add2.java
class student2{
String name="student2 name";
class A{
     String name="student2_A name";
}
}
class add2{
public static void main(String args[]){
student2 s=new student2();
 //pirnt  student2 name,因為這邊的reference是student2
System.out.println(s.name);
}
}
 
**說明
1)class A也是student2的屬性,和String name同位階,所以在uml圖中也是寫在field區,寫法為A:class,所以存取方式和規則會和String name相同
2)如果要抓的A裡面的name,要先確認外部是否要new(是否為static),再確認內部是否需要new,而java的路徑是用"."來表示,所以寫成 student2.A;
3)如果沒加static,有多少層就要new多少層,因為要先產生student才能找到A,再由A找到自己的內容
 
**錯誤的做法
class add2{
public static void main(String args[]){
student2 s=new student2();
System.out.println(s.name);
student2.A s2=new student2().A;
}
}
=>如果寫成 new student2().A;,會出現錯誤,這邊的做法是把A當作變數了,因為class一定要產生物件
 
**正確的作法:要連續new 2次,也就是左邊有幾層,右邊就要new幾次
class add2{
public static void main(String args[]){
student2 s=new student2();
System.out.println(s.name);
student2.A s2=new student2().new A();
System.out.println(s2);
}
}
=>這裡可以看出透過new了兩層以後,把stack配給A了
 
**所以這時再做System.out.println(s2.name);
=>這邊s2.name的reference就變成student2中的 A class,所以output會變成 student2_A name
 
**多層的做法左邊有幾層,右邊就要new幾次 )
class student2{
String name="student2 name";
class A{
     String name="student2_A name";
     class A_1{
         String name="student2_A_1 name";
     }
}
class B{
String name="student2_B name";
}
}
class add2{
public static void main(String args[]){
student2 s=new student2();
System.out.println(s.name);
student2.A s2=new student2().new A();
System.out.println(s2.name);
student2.B s3=new student2().new B();
System.out.println(s3.name);
student2.A.A_1 s4=new student2().new A().new A_1();
System.out.println(s4.name);
}
}
 
**方法的呼叫
(一)先區別一次產生一個物件,和一次產生兩個物件的做法
 
class add2{
public static void main(String args[]){
//只產生一個物件
student2 s =new student2();
s.show();
s.show2()
//產生兩個物件
new student2().show();
new student2().show2();
}
用記憶體來看,前兩個的記憶體位址相同,後面兩個記憶體位址不同
 
(二)要使用A_1中的方法
class student2{
String name="student2 name";
void show(){
     System.out.println("hello student2--1");
}
void show2(){
     System.out.println("hello student2--2");
}
 
class A{
String name="student2_A name";
class A_1{
String name="student2_A_1 name";
void show(){
     System.out.println("hello student2.A.A_1--1");
}
void show2(){
     System.out.println("hello student2.A.A_1--2");
}
     }
}
class B{
     String name="student2_B name";
}
}
 
class add2{
public static void main(String args[]){
student2.A.A_1 s4=new student2().new A().new A_1();
s4.show();
s4.show2();
new student2().new A().new A_1().show();
}
}
=>如果兩個方法都要使用,就new了以後指定給s4,但如果只需要用其中一個功能,那就不需要指定給s4,可以new完直接呼叫
 
b)類別類內部類別=>外部類別物件不用"new"
(一)使用內部static class的非static method
**如何判斷是否要new:class A有static,代表要跟它的外部class(student3)說,sudent3要new,所以class A是否要new是由它裡面的show2()來決定
class student3{
static String name="student3";
static void show(){
     System.out.println("hello student3--1");
}
void show2(){
     System.out.println("hello student3--2");
}
static class A{
void show2(){     //沒有static所以A要new
     System.out.println("hello student3.A--2");
}
}
}
**錯誤寫法:
執行時,如果寫成student3.A s=studnet3().new A();會有錯誤,因為刪除是要刪student3右邊的()而非左邊的new(student3()就變成一個建構式了,要刪除建構式要先刪除括號)
 
**正確寫法:
class add3{
public static void main(String args[]){
     student3.A s=new student3.A();   
     s.show2();
}
}
=>這樣才是new student3中的A物件
 
**注意:如果只能到單獨的內部*.class檔是不能用的,一定要連外部的*.class都拿到才能用
 
 
 
 
(二)使用內部static class的static method
class student3{
static String name="student3";
static void show(){
     System.out.println("hello student3--1");
}
void show2(){
     System.out.println("hello student3--2");
}
static class A{
void show2(){
     System.out.println("hello student3.A--2");
}
static void show(){
     System.out.println("hello student3.A--1");
}
}
}
class add3{
public static void main(String args[]){
     student3.A.show();
}
}
=>可以直接使用,因為static void show()告訴A不需要再new
 
(三) 使用內部非static class的static method
class student3{
static String name="student3";
static void show(){
     System.out.println("hello student3--1");
}
void show2(){
     System.out.println("hello student3--2");
}
static class A{
void show2(){
     System.out.println("hello student3.A--2");
}
static void show(){
     System.out.println("hello student3.A--1");
}
}
class B{
String name="student2_B name";
static void show(){
     System.out.println("hello student3.A--1");
}
}
}
=>出現error,因為只要class沒有加static,裡面的method就不能加static
 
**另外,student3前面也不能加上static,因為static是告訴他的外部class是否需要new,但student3已經是最外層沒有更外部了
 
c)匿名類別(沒有名字的子類別)
=>繼承"interface"類別
=>沒有"class"名稱
=>借用"介面"名字來"new"物件
=>主要定義(宣告)在"main"程式裡
 
(一)先複習interface
add4.java
interface student4{
double pi=3.14;
void show();
}
class sa implements student4{
public void show(){
     System.out.println("hello sa");
}
}
class add4{
public static void main(String args[]){
sa s =new sa();
s.show();
}
}
 
**說明
1.interface只能放常數和抽象方法
2.繼承的子類別要注意權限,並且一定要override抽象方法
3.一定要透過子類別來new interface
 
(二)匿名類別的做法,就是把原本拉出來獨立的子類別class sa放到main中藏起來,實際真正繼承interface是在main 裡面繼承
add4.java
interface student4{
     double pi=3.14;
     void show();
}
/*class sa implements student4{
public void show(){
System.out.println("hello sa");
}
}*/
class add4{
public static void main(String args[]){
student4 s =new student4(){
     public void show(){
         System.out.println("hello sa");
     }
};
     s.show();
}
}
**
1.new student4實際上是在new student4()後面{}中的內容,這就是一個沒有名字的子類別,這個子類別等於就是把class sa中的內容拉進來
2.此時s是指匿名class而非interface student4
2.所以裡面的規則其實和class sa一樣,假設沒有寫內容只有 new student4(){ },出現錯誤訊息表示子類別沒有做override
3.如果寫了內容但沒有加public,會出現錯誤訊息表示子類別的權限太弱
4.編譯後會產生一個檔案如下,是一個沒有名稱放在add4下面的類別,不能單獨使用
 
(三)匿名子類別的簡潔寫法
add4.java
class add4{
public static void main(String args[]){
new student4(){
public void show(){
     System.out.println("hello sa");
}
public void show2(){
     System.out.println("hello2 sa");
}
}.show();
}
}
 
(四)java8以後不限定一定要interface才能用匿名子類別繼承,一般class也能用匿名class來繼承,且同時會把父類別的其他東西也一起繼承下來,不過主要應用還是用在interface上(因為遇到static時會有問題要處理,目前不提)
=>如果在add2.java的student2中加入void abc(){System.out.println("一般class匿名類別測試");} 
 
add4.java
new student2(){
public void show(){
System.out.println("hello sa");
}
public void show2(){
System.out.println("hello2 sa");
}
}.abc();
 
**說明
1.outputs為 一般class匿名類別測試
2.show()和show2()都做override
3.abc()是繼承了student2
 
 
d)enum=>列與值(列舉)=>具public static final=>沒有名字的陣列
**values()=>顯示 enum 的記憶體位址
/*
class bookName {
public static final String book1="JAVA";
public static final String book2="android";
public static final String book3="WEB";
}
*/
enum bookName{
     Java,Android,WEB
};
class add5{
     public static void main(String args[]){
     }
}
**說明
1.enum是一個清單的概念,裡面只能放常數(全部都是值)
2.當使用class打很多值的資料如class bookName,很浪費時間,可以用enum來做
3.enum bookName的 bookName指的是{}的reference,裡面有一個沒有名字的陣列,就是{}中的內容,所以每一個值背後都有編號[0][1][2]....
4.都是以存String值為主,數字類在enum中無法儲存(裡面內容規則和變數名稱的命名規則一樣)
5.所以不用加String,他本身內容具有三個特性public static final
6.但是卻不能定義一個 String 變數放進去,因為它的reference(or類型)是bookName而非String
=>enum背後代表的是一個沒有名字但是類型為bookName的陣列:bookName[]   ={JAVA,android,WEB};
7.System.out.println(bookName.values());去查enum的記憶體位置會顯示如下:
=>[:表示是一個陣列,reference為bookName
 
要把bookName中的內容變成String的作法
enum bookName{
     Java,Android,WEB
};
class add5{
public static void main(String args[]){
System.out.println(bookName.values());
bookName[] x=bookName.values();
for(int i=0;i<x.length;i++){
     System.out.println(x[i]);
}
}
}
**說明:
1.寫一個類型也是bookName的陣列x,並且把bookName.values()指給它,但這邊不是傳址,實際上是做copy的動作,把值copy給陣列x
2.因為enum中的值預設是final的,如果是傳址,則當x[0]要做改變會有問題,因為final不能改,所以不是在傳址
 
eumu的用法
class book{
enum bookName{
Java,Android,WEB
}
}
 
class add5{
public static void main(String args[]){
book.bookName[] x=book.bookName.values();
for(int i=0;i<x.length;i++){
     System.out.println(x[i]);
}
}
}
**說明:
1.eunm可以當作內部類別,因為本身是static可以直接使用,通常用來存放專有名稱
2.作法,設定一個book的bookName類型的陣列x然後把 book.bookName 位址內的資料傳給他
3.去查x和bookName的位址,確實不一樣
System.out.println(bookName.values());
System.out.println(x);
 
●MVC
modeling=>模組化(寫class/method)
view=>ui介面;操作畫面
controller=>控制流程
 
●netbeans實作
=>做一個輸入畫面,要輸入:姓名、國文、英文,一個確定按鈕
主控台輸出:(這邊用println來做)
你的名字:
國文分數:
英文分數:
總分:
 
1.container:panel(是一個分組的概念)/label/text field/button
2.先把使用者介面做好
3.命名變數名稱:name/chi/eng/ok
4.設定ok button的滑鼠事件=>mouseclicked
5.java.lang中的包覆類別:字串轉intInterger.parseInt(String);
=>輸入程式碼如下:
 System.out.println("名:"+name.getText()+
  "\n國文:"+chi.getText()+
  "\n英文:"+eng.getText()+
"\n總分:" +(Integer.parseInt(chi.getText())+Integer.parseInt(eng.getText()))
  );
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

● 抽象類別與interface介面=>superclass=>多型的應用=>DAO(uml的圖)
(一)抽象類別
1.與一般class一樣,具有field,constructors,mehtods
2.關鍵=>抽象方法=>abstract(只有名字,沒有內容),抽象方法不提供內容,內容由繼承的子類別來提供,透過overrride
*在用多型管理的時候,為了配合子類別override而在父類別加的method,因該方法只有名稱沒有內容,只是用來比對名稱,但是加上{}還是會占空間(等於是一個假的方法=>即抽象的方法),所以可以:
 
(一) 直接把void abc(){},後面的{}拿掉,代表不提供內容了
student.java
class student{
String name;
student(String name){
this.name=name;
}
String show(){
return name;
}
void abc();
void abc(int chi){}
}
=>但是只這樣做會出現如上錯誤訊息,沒有正確宣告抽象方法
 
(二)那就對這個方法宣告為抽象:
abstract void abc();
=>只在這個方法前加上absract也會出現錯誤訊息如上
=>因為父類別中只要任何一個(真實的)mehtod要改為抽象method,則該類別(class)的前面也要加上abstract,否則會出現錯誤訊息,子類別不能override
 
(三)正確作法:student class 和 abc() method前都要加上abstract
student.java
abstract class student{
String name;
student(String name){
this.name=name;
}
String show(){
return name;
}
abstract void abc();
void abc(int chi){}
}
 
 
3.只提供繼承,無法單獨個別"new"物件=>喪失new的功能
student class改成abstract以後,在add.java中如果去new student,會出現錯誤訊息如下:
student x=new student();
=>因為student已經不能實體化(instantiated)了,所以不能new,不能配stack記憶體給它,只能提供繼承的功能了
 
4.繼承的子class(subclass)=>extends=>一定要"override"抽象方法(全部都要)
如果子類別沒有override父類別的抽象方法,則不能繼承
student.java
abstract class student{
String name;
student(String name){
this.name=name;
}
String show(){
return name;
}
abstract void abc();
abstract void abc(int chi);
}
 
B.java
class B extends student{
int eng;
B(String name,int eng){
super(name);
this.eng=eng;
}
String show(){
return super.show()+"\t英文:"+eng;
}
}
=>b這是後沒有override abc()和abc(int)這兩個抽象方法,所以會出現錯誤訊息(一次只出現一個)
 
正確
B.java
class B extends student{
int eng;
B(String name,int eng){
super(name);
this.eng=eng;
}
/*String show(){
return super.show()+"\t英文:"+eng;
}*/
void abc(){
System.out.println("abc--B");
}
void abc(int eng){
this.eng=eng;
}
}
=>String show(){}因為不是抽象方法,所以子類別的 String show(){}沒有做override也不會有問題
 
● 抽象類別的UML
 
*所有程式碼請參照: java/10/A.java、 B.java C.java student.java、 add.java
 
(二)interface
1.內容只能定義"常數"與"抽象方法"
2.當superclass(父類別)用,提供繼承,無法"new"物件(因為是抽象的)
interface text{
double pi=3.14;
}
 
class add2{
public static void main(String args[]){
text t=new text();
System.out.println(t.pi);
}
}
因為interface預設是abstract的,所以不能實體化不能new
 
3.常數內容=>public final 類型 常數名=初始值;(一定要初始值)
=>public final 可省略,但編譯會自動加
* interface和class一樣用來定義功能,但compiler出來還是*.class檔
interface text{
double pi=3.14;  //省略public final,編譯會自動加上去
}
 
4.抽象方法=>public adstract....
=>可省略=>繼承的子類別一定要"override"
(所以interface子類別的override幾乎都是public,因為interface是public,子類別的權限要跟他一樣或比他大)
(一)在interface中的方法後面加上{}
interface text{
double pi=3.14;  
void abc(){}   //省略public abstract
}
=>錯誤,在interface中都是抽象方法,所以不能加內容(即{})
 
(二)在子類別如果沒有override
class text2 implements text{
}
=>出現錯誤,子類別對抽象方法沒有做override
 
(三)有override,但沒有設定權限
interface text{
double pi=3.14;
void abc();    //省略public abstract
}
class text2 implements text{
void abc(){
}
}
=>因為繼承了text,所以子類別的override權限要大於或等於父類別
 
5.但要繼承interface,不能用extends,而是要用關鍵字:implements 
interface text{
     double pi=3.14;
}
class text2 implements text{
}
class add2{
public static void main(String args[]){
text2 t=new text2();
System.out.println(t.pi);
}
}
=>透過text2這個子類別去new
 
*以前述uml為例,把student恢復成一般class
(以後自己做的class盡量不要轉抽象,抽象方法全部放在interface中,這樣自己做的class才能new)
(把interface當作索引目錄的概念)
**父類別可多個,但是有規則
1.一般父類別一定要放在第一個(先extends再interface),只能一個一般父類別,其他都必須是interface
class A extends student implements student2{
int chi;
A(String name,int chi){
super(name);
this.chi=chi;
}
String show(){
return super.show()+"\t國文"+chi;
}
 
void abc(){
System.out.println("abc--A");
}
void abc(int chi){
this.chi=chi;
}
 
=>如果interface放在前面,會有錯誤訊息
 
2.多型如果有遇到interface也是共同父類別時,共同父類別名稱可以改為用interface的students2
student2[] s={
new A("kelly",80),
new B("kent",81),
new B("maggie",82),
new A("derek",83),
new A("david",84),
new C("Sylvie",85),
};
 
3.如果要用如下方法run show()method
student2[] s={
new A("kelly",80),
new B("kent",81),
new B("maggie",82),
new A("derek",83),
new A("david",84),
new C("Sylvie",85),
};
for(int i=0;i<s.length;i++){
     System.out.println(s[i].show());
}
=>出現錯誤,因為在interface student2中找不到show()method
 
4.正確:
interface student2{
     String show();
}
=> 在student2中加入show()method, 並同時把A/B/C三個class中的show()改為public String show(){....}
 
 
(三)Data Access by Object(UML中稱為DAO模式)=>data以object的方式存取的模式
*其中interface的繼承關係用虛線表示,+代表public
 
● netbeans的練習
要做一個輸入分數的判斷小畫面
**要key資料=>textField
要打名稱=>label
按鈕=>button
**UI介面
接收訊息=>getText():String;(所有程式預設抓進來都是文字字串 )
 
**步驟
1.新增JFrame,命名為grade
2.拉出一個panel
3.加入一個label,text改為成績,調整字體大小
4.加入一個text field,刪除text,調整要顯示的字體大小
5.加入一個button,修改text名稱
6.給予text field和button variable name 分別為(grade/ok),在左下角可以看到設定好的variable name
7.點一下button,選擇event=>mouseclicked=>選okmouseclicked
8.在private void okMouseClicked(java.awt.event.MouseEvent evt) { }中,輸入 System.out.println(grade.getText());
=>用getText()抓grade文字欄位的資料
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

(一)
1.下列選項哪些可以編譯成功?(選擇2個) 
    A.char xy='yz';
    B.String s2="s2";
    C.char a='\'; 
    D.String s="\"";
    E.int i=1+0.1;
 
 
 2.請選擇合法的敘述句。(選擇2個) 
   A. String #s1="Hi!";
   B. int $money=1000;
   C. double _tax=0.06;
   D. double ~pi=3.14;
 
 
 3.程式碼如下:
    01 int i=1;
    02 long I=1;
    03 float f=1.0f;
    04 double d=1.0;
    05 sum=i+I+f+d;
  請問sum應該定義成什麼資料類型? 
    A. byte
    B. short
    C. int
    D. long
    E. float
    F. double
 
 4.下列選向哪些可以編譯成功?(選擇3個) 
    A. int i=(int)(1+1.1f+1.1);
    B. double d=(float)(1+1.1f+1.1);
    C. long I=1+1.1f+1.1;
    D. float f=(long)(1+1.1f+1.1);
    E. int i=(int)1.1f+1.1;
 
 5.選出合法的識別字(選擇4個 ) 
    A. _$i
    B. $_i
    C. javac
    D. 2i
    E. i2
 
 
 
 
答案:1. bd   2.bc  3. f  4. abd  5. abce

 
(二)
1. 7+6-5*4/3%(2+1)的結果為何? 
   A. 13
   B. 14
   C. 15
   D. 16
   E. 17
   
 
2.程式碼如下,請問最後結果為何? 
   01. int i=100;
   02. String s="10";
   03. s+=i; =>s=s+i變成連結功能
   04. Systemout.println(s);
  
   A. 110
   B. 10010
   C. 10100
   D. 11000
   E. 編譯失敗
 
3.程式碼如下,請問最後結果為何? 
   01. boolean result;
   02. int i=1;
   03. result=1 = =2 && ++i>=2;
   04. System.out.println("result="+result+",i="+i);
   A. result=true , i=1
   B. result=true , i=2
   C. result=false , i=1
   D. result=false , i=2
   E. 編譯失敗
 
4.程式碼如下,請問最後結果為何? 
   01. int x=1, y=1;
   02. boolean b=++x>++y;
   03. System.out.println(b);
 
   A. true
   B. false
   C. 編譯失敗
 
 
5.程式碼如下,請問最後結果如何? 
   01. int x=1 , y=1;
   02. boolean b=!(x>y)^!(x<y);
   03. System.out.println(b);
   A. true
   B. false
  C. 編譯失敗
 
 
 
 
 
 
答案:1. a   2.c  3. c  4. c  5.b

 
(三)
1.程式碼如下,請問最後結果如何?
01. class Test{
02. public static void main(String args[]){
03. int x=2;
04. int y=1;
05. if((x==1)&&(y = = 2))
06. System.out.println("x=1,");
07. System.out.println("y=2, ");
08. if((x+y)==3)
09. System.out.println("x+y=3");
10. }
11. }
 
 A. x=1 , y=2 , x+y=3
 B. y=2 , x+y=3
 C. x=1 , y=2
 D. x+y=3
 E. 編譯失敗
 
 
2.程式碼如下,請問最後結果為何?
01. int x=0;
02. int y=0;
03. do{
04. y++;
05. ++x;
06. }while(x<5);
07. System.out.println(x+","+y);
 
A. 5,6
B. 5,5
C. 6,5
D. 6,6
E. 編譯失敗
 
 
3.程式碼如下,請問最後結果為何?
01. class Test{
02. public static void main(String args[]){
03. String str;
04. z:
05. str="";
06. for(int x=3;x<8;x++){
07. if(x==4) break;
08. if(x==6) break z;
09. str+=x;
10. }
11. System.out.println(str);
12. }
13. }
 
A. 3
B. 34
C. 345
D. 3456
E. 34567
F. 編譯失敗
 
4.程式碼如下,請問最後果為何?(d)
01. class Test{
02. public static void main(String args[]){
03. int i=2000;
  04. int j=1999;
05. int k=1000;
  06. if((i>j)^((k*2)==i))
07. System.out.println(1);
08. if((j+1)!=i^((k*2)==j))
09. System.out.println(2);
10. }
11. }
 
 A. 1
 B. 2
 C. 12
 D. 沒有任何輸出
 E. 執行失敗
 F. 編譯失敗
 
 
5.程式碼如下,請問最後結果為何?(b)
01. class Test{
02. public static void main(String args[]){
03. String str="";
04. z:
05. for(int x=0;x<3;x++){
06. for(int y=0;y<2;y++)
07. if(x==1) break;
08. if(x==2) break z;
09. str=str+x+y;
10. }
11. }
12. System.out.println(str);
13. }
14. }
 
A. 00
B. 0001
C. 000110
D. 00011011
E. 編譯失敗
 
 
 
 
 
答案:1. b   2.b  3. f  4. d  5.b
 

 
(四)
1.程式碼如下,請問最後結果為何?
01. class Excute{
02. public static void main(String args[]){
03. int[] a={4,3,2};
04. int i=a.length>0 ? a[0]:null;
05. System.out.println(i);
06. }
07. }
 
A. 4
B. 3
C. 2
D. null
E. 編譯失敗
 
 
2.程式碼如下,請問最後結果為何?
01. import java.util.Arrays;
02. class Search{
03. public static void main(String args[]){
04. String a[]={"b","r","g","y","o"};
05. Arrays.sort(a);
06. int i1=Arrays.binarySearch(a,"o");
07. int i2=Arrays.binarySearch(a,"v");
08. System.out.println(i1+""+i2);
09. }
10. }
 
A. 3-4
B. 3-5
C. 2-5
D. 2-4
E. 編譯失敗
F. 執行失敗
 
 
3.程式碼如下,請問最後結果為何?
01. import java.util.Arrays;
02. class Execute{
03. public static void main(String args[]){
04. String[] a[]={{"1","2"},{"3","4","5"}};
05. String[][] b=a;
06. System.out.println(b[1][2]);
07. }
08. }
 
A. 1
B. 2
C. 3
D. 4
E. 5
F. 編譯失敗
E. 執行失敗
 
 
4.程式碼如下,請問最後結果為何?
01. String[] str=null;
02. System.out.println(str.length);
 
A. 0
B. null
C. 1
D. 編譯失敗
E. 執行失敗
 
 
5.程式碼如下,請問最後結果為何?
01. import java.util.Arrays;
02. class Execute{
03. public static void main(String args[]){
04. String[] s1={"1","2","3"};
05. String[] s2={"4","5","6"};
06. s1=s2;
07. for(String str:s1)
08. {System.out.println(str);}
09. }
10. }
 
A. 123
B. 456
C. 編譯失敗
D. 執行失敗
 
 
 
 
 
 
答案:1. a  2.c  3. e  4. e  5.b
 

 
(五)
1.程式碼如下,請問最後結果為何?
01. class Execute{
02. public static void main(String args[]){
03. new Execute().cal("one",1);
04. new Execute().cal("two","three",5);
05. }
06. public void cal(String...num1,int num2){
07. System.out.println(num1[num1.length-1]+" ");}
 
A. one 1
B. two three 5
C. one two
D. two one
E. 編譯失敗
 
 
 
2.程式碼如下,請問最後結果為何?
01. class Person{
02. String name="anonymity";
03. public Person(String n){name=n;}
04. }
05. class Employee extends Person{
06. String empID="E00";
07. public Employee(String id){empID=id;}
08. }
09. class Execute{
10. public static void main(String args[]){
11. Employee em=new Employee("E01");
12. System.out.print(em.empID);
13. }
14. }
 
A. E00
B. E01
C. anonymity
D. E00 E01
E. 編譯失敗
 
 
 
3.第5行插入甚麼方法,可以編譯成功?(選擇3個)
01. class A{
02 protected int getInt(int i){return i;}
03. }
04. class B extends A{
05. //插入程式碼
06. }
 
A. public int getInt(int i){return i;}
B. private int getInt(int i){return i;}
C. private int getInt(long i){return (int)i;}
D. protected long getInt(int i){return i;}
E. protected int getInt(long i){return (int)i;}
 
 
 
4.給定下面程式碼,哪些選項的描述是對的?(選擇3個)
01. class Animal{}
02. class Dog extends Animal{Tail tail;}
03. class Beagle extends Dog{public void jumper(){}}
04. class Cat extends Animal{public void jumper(){}}
 
A. Cat is-a Animal
B. Cat is-a jumper
C. Dog is-a Animal
D. Dog is-a jumper
E. Beagle has-a Tail
 
 
5.程式碼如下,請問最後結果為何?
01. class Person{
02. final String name;
03. public Person(String n){name=n;}
04. }
05.
06. class Execute{
07. public static void main(String args[]){
08. Person p=new Person("Joe");
09. System.out.print(p.name);
10. }
11. }
 
A. Joe
B. null
C. 沒有任何輸出
D. 編譯失敗
 
 
 
 
 
答案:1. e  2.e  3.ace  4. ace  5.a
文章標籤

muchone 發表在 痞客邦 留言(1) 人氣()

● IDE=>視窗開發介面
● 找api時,放在越下面的代表越新
 
● NebBeans介紹
1.用開啟新專案的方式,因為要做一組新的功能class
2.開啟後,選java=>java application
(javafx是類似flash做動畫的)
3.把create main class勾選取消,我們要自己命名main clas
4.但實際上檔案是在files下做,會放在ex1下的sc資料夾(source),在sc資料夾按右鍵=>new=>other下的main class(要自己命名),只要做一次就可以
*在netbeans中,打完程式就會自動compiler完成,右鍵選run,執行結果就會出現在下方主控台
 
5.左下角會有類似uml表現方式的class說明,建構式、field、method(傳值與不傳值表現方式不同)的符號不同,黃線部分代表apple繼承student
6.練習寫一個介面在src=>右鍵=>new=>JFrameForm(這個才有main才能執行),執行時到這邊設定好的檔案名稱按右鍵=>run
 
7.切換source和設計畫面
 
8.properties可以設定這些介面的屬性ex:背景顏色....,也可在實際上的操作介面元素上直接按右鍵改properties
9.containers放操作的面板,controls放控制項,event是結合程式要用的事件,code是結合程式要用的一些設定ex:variable name
 
10.先拖曳一個面板和一個按鈕然後修改按鈕的名稱及面板的背景色
*注意這邊button上的ok是在properties中的text修改,只是這個button畫面上的名稱(外觀)不能用來與程式結合
 
11.如果要和程式結合,要在code修改variable name,修改好之後左下角的navigator也會跟著改變
 
12.假設我們要在ok按鈕按下的時候顯示hello java
event=>mouseclicked,改為onmousecliced,其他都是預設none,如果有不是的要記得刪除不然會出錯
 
13.這時在程式中出現如下的method,名字為button的variable name+mouseclicked,括號中的引數代表當滑鼠按下時的這個event,在這個method中加入我們要輸出的內容即可
 
14.執行結果
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

● 可以把多個class寫在同一個檔案中,但檔名只能有一個,compiler時會自動產生不同class的*.class檔
ex:student.java中有student class/a class/b class,compiler後會自動產生student.class/a.class/b.class三個檔案
 
1.instanceof 
=>查詢is-a(查詢物件是何類型)=>true/false
=>ex:查a是不是A物件=>a instanceof A(true or false)
studtent.java
class student{ }
class A extends student{ }
class A_1 extends A{ }
class B extends student{ }
 
add.java
A a = new A();
System.out.println(a instanceof A);
System.out.println(a instanceof student);
System.out.println(a instanceof A_1);
=>instanceof只會往上找不會往下找,所以找A_1會變成flase
 
System.out.println(a instanceof B);
=>instanceof尋找時,限定組織圖中的同一條線上,如果是另外一條線compiler會出現問題(B和A無關)
 
 
2.java.lang.object;
a) 所有物件的共同父類別
*因為class是為了new物件用的,所以object是所有class的共同父類別也會是所有物件的共同父類別
 
b) 新增class時會自動繼承
*只要是寫class雖然都沒有寫extends但都會自動繼承object
*如果日後在使用object的method時,也可以用override修改
 
c) equals 方法
*不論是物件還是變數或陣列,只要"="的左右兩邊都是位址,就會把左邊砍掉
add.java
A a=new A();
A b=new A(); 
a.x=50;
a.show();   
b.show();  
b=a;  
b.x=200;
b.show();
a.show(); System.out.println(a.equals(b));
=> 假設不小心把位址砍掉了,show()的時候才發現兩個結果一樣,檢查的方法除了直接查兩個物件的記憶體外,還可以用equals方法,看a和b兩個物件的記憶體是否相同,相同就是true,不同就是false
 
3.final
a)field=>常數,須給初始值,如果沒有給初始值,compiler會出錯,如下,一定要給初始值或是用建構式給予初始值
studtent.java
class student{
final double pi=3.14;
}
 
class A extends student{
int x;
void show(){
System.out.println("x="+(x+pi));
}
 
add.java
A a = new A();
A b = new A();
a.x=50;
a.show();
b.show();
b=a;
b.x=200;
a.show();
b.show();
 
**final常數給了以後不能再修改
studtent.java
int x;
void show(){
pi=5;
System.out.println("x="+(x+pi));
}
=>final變數不能指定
 
b)method=>不允許override
如果有個程式(名稱)不想被override,就在前面類型加上final,就無法被override,要改就要另外取名字寫
studtent.java
class A extends student{
int x;
final void show(){
System.out.println("x="+(x+pi));
}
}
class A_1 extends A{
     void show(){  }
}
 
c)class=>不允許繼承
如果有寫一個class不想被繼承,又不想加private(因為加private在文件中會被隱藏),就在class前面加上final
studtent.java
final class A extends student{
int x;
final void show(){
System.out.println("x="+(x+pi));
}
}
 
class A_1 extends A{
/*void show(){
}*/
}
=>A因為有加final所以不允許繼承
 
d)空final變數(沒給初始值的final變數),需透過建構式給予初始值(要在new的時候給初始值,所以是建構式給)
通常會用在輸入帳號時,因為帳號一開始空的給使用者輸入,輸入以後就要變成常數不能再修改
member.java
class member{
final String name;
member(String name){
this.name=name;
}
}
 
add.java
member m=new member("iamaccount");
System.out.println(m.name);
=>輸出iamaccount
 
=>如果之後用m.name="change";去修改,會出現錯誤訊息,name是final variable不能修改
 
4.參數列表
a) 即方法的引數 
b) 與陣列類似 
ex:
abc(int [ ] x):void; 或 abc(int... x):void;
studtent.java
class B extends student{
  int sum1(int x, int y, int z){  
       return x+y+z;
  }
  int sum2(int[]x){
      //用陣列的時候沒有數量的限制
       return x[0]+x[1]+x[2]; 
  }
 int sum3(int...x){   //一定只能有三個點
       return x[0]+x[1]+x[2];
  }
}
add.java
int[] x={10,20,30};  
System.out.println(new B().sum1(10,20,30));
System.out.println(new B().sum2(x));  
=>要先宣告陣列 x,且這邊sum()內放的是陣列x
System.out.println(new B().sum3(x));
//注意引數的類型要一致
System.out.println(new B().sum3(20,30,40)); 
 
=>參數列表比陣列有彈性在於,這邊輸出時可以當作陣列用也可以直接輸入3個引數(自動幫你轉成陣列),但如果在 System.out.println(new B().sum2(10,20,30));放入引數,就會錯誤,而且在 sum3(20,30,40) 這裡放入的引數也沒有數量的限制
 
**如果student.java中,把method的名稱改為一致就不會是overloading,因為兩個方法的引數都是陣列
int sum(int[]x){
     return x[0]+x[1]+x[2];  
  }
int sum(int...x){   
     return x[0]+x[1]+x[2];
  }
**參數列表只能設定一個,不能一次設定多個
void abc(int[] x,double[] y){  }
void abc2(int... x, double... y){  }
**當引數還有混和其他變數時,參數列表一定要放在最後
void abc(int[] x,double[] y){}
void abc2(int[] x,int y, int z){}
void abc3(int... x,int y, int z){}
 
=>正確的用法
void abc3(int y, int z,int... x){}
 
● 靜態class也可以放入main程式,可以同時是靜態也是動態,而且因為有main所以可以執行
=>這樣做可以用來自己測試自己寫好的class,檔案命名時以main為主
class ABC
{
      public static void main(String args[]){
            new ABC(100).show();
      }
 int x;
 ABC(int x)
 {
       this.x=x;
 } 
 void show()
 {
  System.out.println("hello "+x);
 } 
}
 
 
 
 
 
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

c)constructors
1.全部都要執行
2.順序上==>下(父==>子)
3.super(引數):sup
d)overloading
 
●實作
UML
 
程式
(一)假設A沒有建構式,但school有建構式,compiler會出現錯誤訊息
=>required: String,int
=>因為在new A的時候,會run school的constructor,這時會需要引數,可是A沒有丟給school引數
 
做法:
引數透過子類別的建構式丟給父類別,如果沒有這樣做就不能繼承
A.java
//這個步驟是先接收user key的內容(接收外部資料)
A(String name,int chi){  
//透過super(引數)才會把引數丟給父類別
super(name,chi);          
System.out.println("A班學生");
}
=>注意!!super()中的順序和類型都要和父類別的建構式引數一致
=>在new的時候會先new A(所以引數就放在new A()),可是run是先run school(父類別)
 
school.java
class school{
String name;
int chi;
 
school(String name,int chi){
this.name=name;
this.chi=chi;
System.out.println("新增一位學生school\tname:"+name+"\tchi:"+chi);
}
}
 
*但如果交換System.out.println("A班學生");super(name,chi);的順序,
compiler會出現次錯誤
=>super要放第一個因為交換以後,變成先執行子類別在執行父類別的建構式了...
A.java
A(String name,int chi){   
System.out.println("A班學生");
super(name,chi);          
}
 
 
*如果A本身的建構式中也要放入引數
A.java
private int word;
//可以直接放在A()中,這邊的內容不用和school()中的內容一致,只要有包含school()中的內容即可
A(String name,int chi,int word){ 
//重點在super()中的內容要和school()中的內容一樣
super(name,chi);
this.word=word;   //要記得放在super()後面
System.out.println("A班學生\t word:"+word);
}
 
add.java
A a=new A("maggie",80,95);
 
 
 
(二)overloading
假設school有多個建構式(有引數的建構式才會有多個)
school.java
String name;
int chi;
 
school(String name,int chi){
this.name=name;
this.chi=chi;
System.out.println("新增一位學生school\tname:"+name+"\tchi:"+chi);
}
 
school(String name){
this.name=name;
System.out.println("新增一位學生school\tname:"+name);
}
 
*A在繼承時,只需要選一個繼承即可,由super()中的引數判斷是繼承哪一個,但如果兩個都要繼承時,不可以在同一個建構式中寫兩個super(),因super()在同一個建構式中只能使用一次,全部都要繼承,子類別就要拆成好幾個建構式(至少一定要繼承一個)
A(String name,int chi,int word){
super(name,chi);
this.word=word;
System.out.println("A班學生\t word:"+word);
}
A(String name,int word){
     super(name);
this.word=word;
System.out.println("A班學生\t word:"+word);
}
 
(三)A,A_1,和B都繼承
**繼承class之前一定要記得先去看class中的建構式
school.java
class school{
String name;
int chi;
school(String name,int chi){
this.name=name;
this.chi=chi;
System.out.println("新增一位學生school\tname:"+name+"\tchi:"+chi);
     }
school(String name){
this.name=name;
System.out.println("新增一位學生school\tname:"+name);
}
}
 
A.java
class A extends school{
private int word;
A(String name,int chi,int word){
super(name,chi);
this.word=word;
System.out.println("A班學生\t word:"+word);
}
A(String name,int word){
super(name);
this.word=word;
System.out.println("A班學生\t word:"+word);
}
}
 
A_1.java
class A_1 extends A{
     private int access;
     A_1(String name,int chi,int word,int access){
          super(name,chi,word);
          this.access=access;
          System.out.println("A_1組\taccess:"+access);
}
}
=>A_1有兩層要繼承又都有overloading時,只要處理他的上一層(A)建構式,因為school那一層已經由他的父類別(A)處理好了
 
B.java
class B extends school{
private int excel;
B(String name,int chi,int excel){
super(name,chi);
this.excel=excel;
System.out.println("B班學生\t excel:"+excel);
}
}
 
add.java
class add {
public static void main(String args[]){
     A_1 a1=new A_1("maggie",80,95,60);
}
}
 
(6)methods方法
 
1.hsa-a
引用上例:
school加上show()method,A、B、A_1不變
void show(){
System.out.println("school學生");
}
 
去執行時,三個都有繼承show()
A a=new A("maggie",80,95);
a.show();
=>輸出school學生
A_1 a1=new A_1("maggie",80,95,60);
a1.show();
=>輸出school學生
B b=new B("maggie",80,77);
b.show();
=>輸出school學生
 
**當在做a1.show()時順序是,會先去A_1show()找,再去找Ashow(),最後在school找到show()
 
2.overloading
=>名字一樣,引數不一樣
=>上述在同一個class中的overloading規則也適用於父類別和子類別的關係(適用於上下關係)
當school有overloading且A本身又有自己的method=>這樣也適用overloading的規則
school.java
void show(){
System.out.println("school學生");
}
void show(String name){
System.out.println("school學生 姓名:"+name);
}
 
A.java
void show(int word){
this.word=word;
System.out.println("A班學生\t word:"+word);
}
 
在執行時
add.java
school s=new school("maggie");
s.show("kelly");
s.show(85);=>compiler會出現錯誤訊息,因為在查reference只會往上找不會往下找
 
A a=new A("maggie",80,95);
a.show();   //繼承school method
a.show("kent");  //繼承school method
a.show(58); //自己本身的method
 
 
3.override(改寫)
=>名字一樣,引數一樣,類型一樣
=>必須位於不同class(父,子),如果同一個class compiler就會出錯
當school有一個show(),A下面也有一個show(),名字類型和引數都一樣
 
school.java
void show(){
System.out.println("school學生");
}
 
A.java
void show(){
System.out.println("A");
}
 
add.java
school s=new school("maggie");
s.show();
System.out.println("=====");
A a=new A("maggie",80,95);
a.show();
=>執行時,s.show()是去抓school class的show(),A.show()是去抓A class的show()
**通常發現程式有錯時,作法有兩種
1.找原始碼去改school class中的show()
2.拿不到原始碼,或是不想改變已固定使用的介面,想做微調就好
=>在子類別用overriede的方式來改,可以避免其他繼承同一父類別的子類別被想到
 
傳值類method
在school中新增一傳值類methodd
school.java
int abc(int x){
// 把abc(int x)視為一個變數,return就是"="=>int abc(...)=x的意思 
     return x;  
}
 
如果要改為輸入值+20,而且要從子類別A做調整:
(一)若改為如下
A.java
void abc(int x){  }
=>會出現錯誤訊息,類別不正確,因為當子類別方法的名字和引數都跟父類別相同時,就會自動當作override,就會去檢查類別
 
(二)正確做法
A.java
int abc(int x){
     return x+20;
}
 
**如果superclass的方法有設定封裝權限(權限大小順序:public>protected>default>private)
=>子類別權限要>=父類別
=>如果沒有寫封裝權限就是default
=>只要沒有加private都可以繼承
如果在school中的int abc()封裝權限為protected,在A中的abc()為default
school.java
protected int abc(int x){
return x;
}
A.java
int abc(int x){
return x+20;
}
=>compiler會出現錯誤訊息,A class的封裝權限weaker than school class,
所以要把權限改為protected(相等)或public(大於)school才可以override
A.java
public int abc(int x){
return x+200;
}
 
5.內容
=>super.方法
如果要把繼承於父類別的函數拿去運算出另一個結果
school.java
protected int abc(int x){
return 3*x+100;
}
A.java
public int abc(int x){
return abc(x)+200;
}
=>abc(x)代表superclass的method,x還是帶int x
=>如果直接去執行,會出現一直在跑下列訊息,因為override,造成執行時去找到的是A class本身的abc(),一直呼叫自己造成遞迴(會有stackoverflow 記憶體不斷堆疊的問題)
 
正確做法
當名稱引數都一樣,又要引用上一層同樣的method時,就要用super.method,才不會因為被override造成遞迴的問題但只能引用上一層,上上一層不能引用,void不能這樣用,因為void不能當作值去做運算
A.java
public int abc(int x){
return super.abc(x)+200;
}
 
● Polymorphism  多型(=>用來討論方法的使用)
1)多個class,有共同的父類別
2)使用父類別定義物件名稱=>"new"新增物件(實體化)使用子類別
3)目的:會限制使用的"方法"數量
=>只有定義物件的父類別有定義的方法"名稱"才可使用
=>繼承或"override"
語法:
父類別 物件=new  子類別(); =>父類別和子類別間須有繼承關係
 
 
程式說明
(一)多型的宣告方式
原本new一個物件的方法如下:
add.java
A a = new A();
B b = new B();
C c = new C();
a.show();
b.show();
c.show()
 
*但因為ABC有共同的父類別,可以把左邊改為student,但左右兩邊一定要有繼承關係
add.java
student a = new A();
student b = new B();
student c = new C();
 
*如果這時我們要用a呼叫abc():
add.java
student a = new A();
student b = new B();
student c = new C();
a.abc();
 
student.java
void show(){
System.out.println("hello student");
}
 
A.java
void show(){
System.out.println("hello student a");
}
void abc(){
System.out.println("hello student a, abc");
}
 
=>compiler時會出現錯誤訊息,因為在做a.abc時,call by reference會先去看左邊的student class是否有abc(),結果student中並沒有abc()method
 
 
(二)想使用子類別的某個方法但父類別沒有時的作法
studetn.java
void show(){
System.out.println("hello student");
}
 
B.java
void abc2(){
System.out.println("hello student b ,abc2");
}
 
add.java
student a = new A();
student b = new B();
student c = new C();
a.abc();
b.abc2();
=>因為在sudent中並沒有abc2()這個方法,所以編譯時在call by reference這個階段時就出現錯誤了
=>如果在使用多型時,父類別沒有的方法,是絕對不能用的,如果一定要用某個子類別有但父類別沒有的方法,就要在父類別中加入該方法但不用寫內容(因為只是要用來被子類別的內容override)
=>故此例要在student中加入void abc2(){}
 
**所以多型的使用又稱為異質宣告,和一般宣告最大的不同,在於方法的限制比較嚴格,只有兩種做法
1.由父類別繼承而來
2.override而來 
=>須注意的是,當call by reference時,是由等號左邊開始找,所有方法都要在父類別找的到compiler才能過,等執行時卻是從等號右邊開始找class中有沒有該方,有override會先做,沒有override就做由父類別繼承而來的方法(因為執行的時候要看記憶體,只有new的時候才會有記憶體,所以執行時從右邊開始找)
 
**所以多型的父類別有索引目錄的概念,個別的子類別都會有父類別所列的方法,然後各自有不同的功能
 
(三)多型的method繼承與method override的實作
*在student和A中都有abc(),但在B和C中都沒abc()
 
student.java
void abc(){
System.out.println("hello student 繼承來的");
}
 
A.java
void abc(){
System.out.println("hello student override");
}
 
add.java
student a = new A();
student b = new B();
student c = new C();
a.abc();
b.abc();
c.abc();
 
outputs
hello student override
hello student 繼承來的
hello student 繼承來的
 
*如果A下面還有A_1,因為也有共同父類別student,所以也能用多型的規則來new,但是當呼叫abc()method時,因為上一層A有abc()method,會直接用A的
 
add.java
student a = new A();
student b = new B();
student c = new C();
student a_1=new A_1();
 
a.abc();
b.abc();
c.abc();
a_1.abc();
 
outputs
hello student override
hello student 繼承來的
hello student 繼承來的
hello student override
 
4)搭配=>陣列使用(因為資料量很多,用來管理名字)
=>多型就是為了搭配陣列以及和後續會提到的抽象類別、interface有關
假設A班有2人B班有2人C班有一人,隨機輸入資料
student.java
void abc(){
System.out.println("hello student");
}
 
A.java
void abc(){
System.out.println("hello student a");
}
 
B.java
void abc(){
System.out.println("hello student b");
}
 
C.java
void abc(){
System.out.println("hello student c");
}
 
add.java
student [] s={
new A(),
new B(),
new A(),
new C(),
new B()
};
for(int i=0;i<s.length;i++){
     s[i].show();
}
//outputs
 
 
文章標籤

muchone 發表在 痞客邦 留言(1) 人氣()

● static
1.與excel絕對位置觀念一樣
=>在excel中
相對:計算式一樣,但每個計算結果所用的來源資料都不一樣
(每多一筆資料就會多一筆不同的來源)/new的概念
絕對:某一格的內容要一直隨著不同計算結果重複使用,
但不想要每次改變都要一筆一筆資料重作,就拉出表外獨立
($B$1=>代表會鎖住B1位置,計算的時候不會隨著下拉改變)
 
2.class定義時,定義成"唯一"一格,不會隨著"new"物件而配發給每 一筆物件"heap"區,不與物件資料排列
=>只有一格
 
3.存取方式,不需透過物件,只須透過"class"呼叫
=>又稱"類別類"(需透過物件呼叫使用,稱"物件"類)
=>class產生時,還沒new之前,static就已經產生,
所以不用透過new一個物件來產生(由類別來定義產生)
=>所以下例可以一開始就直接寫成fv.money=5000000
*所以在看API 的時候會發現沒有建構式的時候幾乎都是static,因為建構式一定要做new的動作
 
4.使用對象
a)field區屬性
b)methods(如下例的fv.title())
=>當method使用static時要注意,在static method中的變數如果有用到最開始定義的變數(field),只能用有定義為static的變數,但如果是與上面無關的變數就不需要限定為static
c)inner class內部類別(之後再講)
=>b,c是最主要的應用
 
● 實作:
複利本利和=本金(1+利率)n =>fv=money*Math.pow((1+r),Y);
**加底線代表static
**static說明
money改成static前:
 
fv f1= new fv(1,1000000,0.05,10);
fv f2= new fv(2,1000000,0.01,15);
fv f3= new fv(3,1000000,0.07,5);
f1.show();
f2.show();
f3.show();
 
System.out.println("==============");
 
f1.money=2000000;
f1.show();
f2.show();
f3.show();
 
=>3筆本金是不同的資料,所以改f1.money,其他兩筆不會一起變動
money改成static後:
 
fv f1= new fv(1,1000000,0.05,10);
fv f2= new fv(2,2000000,0.01,15);
fv f3= new fv(3,3000000,0.07,5);
f1.show();
f2.show();
f3.show();
 
System.out.println("==============");
 
f1.money=2000000;
f1.show();
f2.show();
f3.show();
 
 
=>最上面的本金會全部變為3000000,因為static只有一格,資料會被最後一筆改掉
=>下面只要f1.money或 f2.money或 f3.money任一改變全部都會跟著改變( 改成static後,變成絕對位置,(相當於拉出excel表外獨立),f1.money=f2.money=f3.money,不論誰改變都會同時變動 )
*完整內容
fv.java
class fv{
private int number;
static int money;
private double r;
private int y;
private double fv;
 
fv(int number,double r, int y){
this.number=number;
this.r=r;
this.y=y;
fv=money*Math.pow((1+r),y); //y是(1+r)的次方
}
 
void show(){
 
System.out.println("編號:"+number+
"\t本金:"+money+
"\t年利率:"+r+
"\t年:"+y+
"\t複利本利和:"+(int)fv //去小數
);
}
 
add1.java
fv.money=5000000;
fv f1= new fv(1,0.05,10);
fv f2= new fv(2,0.01,15);
fv f3= new fv(3,0.07,5);
f1.show();
f2.show();
f3.show();
System.out.println("==============");
f1.money=2000000;
f1.show();
f2.show();
f3.show();
 
=>因為年金都相同,所以就不用每次都去輸入這筆資料,可以把constructor中的money都刪除
 
*如果編號要自動跳號
(一)直接把nubmer++
add1.java
fv.money=5000000;
fv f1= new fv(0.05,10);
fv f2= new fv(0.01,15);
fv f3= new fv(0.07,5);
f1.show();
f2.show();
f3.show();
 
fv.java
private int number;
static int money;
private double r;
private int y;
private double fv;
 
fv(double r, int y){
this.number++;
this.r=r;
this.y=y;
fv=money*Math.pow((1+r),y); //y是(1+r)的次方
}
 
=>因為目前number不是static,所以以每一筆編號都是獨立的不是共用的,當f1做完0+1後,f2的編號是獨立的,故還是從0開始做++,f3亦然
 
(二)把number改為static再++
fv.java
private static int number;
static int money;
private double r;
private int y;
private double fv;
=>如果把static加在private和int中,會得到如上結果
=>這邊的做法是當new f1時,number=0+1=1, 當new f2時,number=1+1=2, 當new f3時,number=2+1=3,最後一筆number把前面的都改掉了
 
=>以這個作法如果要每個編號不一樣,就只能在執行的時候馬上秀一筆資料,才不會後面的資料給改掉,但這樣很難跟陣列結合
add1.java
fv f1= new fv(0.05,10);
f1.show();
fv f2= new fv(0.01,15);
f1.show();
fv f3= new fv(0.07,5);
f1.show();
(三)正確做法
fv.java
private int number;
private static int count;
static int money;
private double r;
private int y;
private double fv;
 
fv(double r, int y){
//也可寫成this.number=++count,但++要寫在前面,
//不然會把加之前的資料指過去
count++;
this.number=count;
this.r=r;
this.y=y;
fv=money*Math.pow((1+r),y); //y是(1+r)的次方
}
=>所以number不能用static,要用另外一個變數(count)去加,這樣number就會各自獨立不會共用一個,是每一次count算好就丟給每一個nubmer
 
 
**複利本利和沒有跟著本金而改變的問題處理
問題:
當本金由5000000改為,20000000,複利本利和都沒變
 
add1.java
fv.money=5000000;
fv f1= new fv(0.05,10);
fv f2= new fv(0.01,15);
fv f3= new fv(0.07,5);
f1.show();
f2.show();
f3.show();
System.out.println("==============");
//static直接用類別呼叫,不要再用f1/f2/f3
fv.money=2000000;
f1.show();
f2.show();
f3.show();
 
fv.java
fv(double r, int y){
count++;
this.number=count;
//也可寫成this.number=++count,但++要寫在前面,不然會把加之前的資料指過去
this.r=r;
this.y=y;
//y是(1+r)的次方,這邊的建構是可以不加這個公式,因為下面mehtod有重算
//fv=money*Math.pow((1+r),y); 
}
 
void show(){
fv=money*Math.pow((1+r),y);
System.out.println("編號:"+number+
"\t本金:"+money+
"\t年利率:"+r+
"\t年:"+y+
"\t複利本利和:"+(int)fv //去小數
);
=>因為本利和本來是在建構式中計算(new的時候才會計算)
當本金改變,不會重新計算,解決辦法就是在show()輸出前重新計算一次
 
**如果要做成表格的方式,把標題拉到最上方共用
fv.java
void show(){
  fv=money*Math.pow((1+r),y);
  System.out.println(number+"\t"+money+"\t"+r+"\t"+y+"\t"+(int)fv);
}
static void title(){
  System.out.println("編號\t本金\t年利率\t年\t複利本利和");
}
 
add1.java
fv.money=5000000;
fv.title();
fv f1= new fv(0.05,10);
fv f2= new fv(0.01,15);
fv f3= new fv(0.07,5);
f1.show();
f2.show();
f3.show();
 
System.out.println("==============");
fv.money=2000000;
f1.show();
f2.show();
f3.show();
=>因為title()是static,所以可以直接用fv.title()不需要new
 
**method使用static要注意,在static method中的變數如果有用到最開始定義的變數(field),只能用有定義為static的變數
eX:把show()改為static,會出現錯誤訊息non-statice varible
static void show(){
fv=money*Math.pow((1+r),y);
System.out.println(number+"\t"+money+"\t"+r+"\t"+y+"\t"+(int)fv);
}
=>因為當在執行show()的時候,會把裡面的變數都當作static來做,如fv.money(ok)、fv.(r),會用fv直接呼叫,這時呼叫到不是static的變數就會出現錯誤
 
如果改成如下內容,就不會有問題,因為count是static
static void show2(){
     System.out.println("請輸入第"+count+"個");
}
 
 
 
**用Scanner來做
addtest.java
import java.util.Scanner;
class addtest{
public static void main(String args[]){
Scanner sc=new Scanner(System.in);
System.out.println("請輸入資料筆數");
int n=sc.nextInt();
System.out.println("輸入本金:");
fv.money=sc.nextInt();
fv[] f=new fv[n];
for(int i=0;i<f.length;i++)
{
System.out.print("輸入第"+(i+1)+"筆-->利率: ");
double r=sc.nextDouble();
System.out.print(); //換行排版用    
System.out.print("輸入第"+(i+1)+"筆-->年: ");
int y=sc.nextInt();
f[i]=new fv(r,y);
}
fv.title();
for(int i=0;i<f.length;i++)
{
     f[i].show();
}
}
}
=> double的Scanner函式為 nextDouble()
 
● static import:如果要使用的api的功能中,大部分都是static method,可以直接匯入static method,這樣就可以直接使用method不需要再call class,但非屬於static的method不能這樣做,要透過new
ex:Math
import static java.lang.Math.*;
 FV(double r,int y){
  count++;
  this.number=count;
  this.r=r;
  this.y=y;
  fv=money*pow((1+r),y);
 }
=>這邊的路徑是指到Math下的method,而非指到Math,如果不加static而直接用pow()不用Math.pow() 會找不到
● 實作:
static不一定要連database,譬如可以把常用的公式放入一個class,然後method都設定為static,要用的時候直接呼叫,不用每次都要new,
ex:
FV=>複利本利和=本金*(1+利率)n=>FV(m,r,y)
(m,r,y=>先想好要用到的變數)
AR=>圓面積=3.14*rr=>AR(r)
RO=>周長=23.14r=>RO(r)
cal.java
class cal
{
static double FV(int money,double r, int y)
{
return money*Math.pow((1+r),y);
}
static double AR(double r)
{
return 3.14*r*r;
}
static double RO(double r)
{
return 2*3.14*r;
}
}
 
addcal.java
class addcal{
public static void main(String args[]){
System.out.println(cal.FV(10000,0.05,5));
System.out.println(cal.AR(5));
System.out.println(cal.RO(20));
}
}
=>用double小數點可以取到最小比較精準
=>因為有return,所以是傳值類的,故名稱前面要設定類別,而且可以直接print出來
 
● inheritance繼承=>目的:產生父類別
(1)多個class,共同的屬性與規則
(2)superclass=>父類別,subclass=>子類別(順序由上到下的概念)
(3)extends
假設同一個學校有兩個科系a和b 
a.java
class a{
String name;
int chi;
int excel;
void show(){
    System.out.println("姓名:"+name+"\t國文:"+chi+"\texcel:"+excel);
     }
}
b.java
class b{
String name;
int chi;
int word;
void show(){
     System.out.println("姓名:"+name+"\t國文:"+chi+"\tword:"+word);
 }
}
add2.java
class add2{
public static void main(String args[]){
a a1= new a();
b b1= new b();
a1.show();
b1.show();
}
}
=>在同一個機構/系統(這邊是同一個學校)的前提之下,假設規則要改變(ex:chi要改成可以用double),以上面的做法必須兩個class分別去做修正,如果有很多class就變成要一個一個去改,這樣太浪費時間,可以去抓a和b兩個class定義一樣的規則(共同規則),放到另外一個class(公因數的概念)
class school{
      String name;
      double chi;
}
=>把a和b的這兩個class中的name和chi刪除,若此時直接compiler add2.java,會出現錯誤訊息,因為在a和b class中找不到上述兩個變數
 
作法:
把a和b class都加上extends school
class a extends school{ .....}
class b extends school{ .....}
=>classs a extends school 稱作:school的內容繼承給a,代表把a要用到的內容/功能放在其他class
(一條線延伸的概念,翻譯成延伸比較好理解)
=>所以new的時候,會找a+extends 中 的內容
 
 
 
(4)is-a=>是否具有此class的類型(包括自己定義的class與父類別)
has-a=>是否擁有使用此"方法"與"field"的權限=>是否有繼承
用下面例子來解釋:
我們用b class產生了一個b1物件,如果想看b1有多少功能(包括本身與繼承而來的功能)可用
 
is-a(類型):
b1 is a b(b1是 b class類型的物件)
b1 is a school (b1是 school class類型的物件)
=> 是call by reference的概念
=>因為查b的時候看到裡面有extends school,代表有繼承school,所以b1 is a school,如果shool上面還有繼承也是要一起抓下來
 
has-a(內容):
b1 has a word
b1 has a name
b1 has a chi
**只要沒有設定權限,就會全部繼承,所以越sub的功能越多,越super的功能越少
*繼承時因為很多層,如果用notepad++開發要每一個class都compiler一次不然run會有問題
*繼承的好處=>共同規則只要改一次就好
 
(5)constructor 建構式
a)全部都要執行,一定要執行
b)順序由父類別====>子類別(有上到下)
(一) school有一個建構式,但a沒有建構式的狀況下
school.java
String name;
int chi;
school(){
     System.out.println("我是父類別的建構式");
}
 
a.java
int excel;
void show(){
     System.out.println("姓名:"+name+"\t國文:"+chi+"\texcel:"+excel);}
 
add2.java
a a1= new a();
a1.show();
 
 
(二) school有一個建構式,但a也有一個建構式的狀況下
school.java
String name;
int chi;
school(){
     System.out.println("我是父類別的建構式");
}
 
a.java
int excel;
a(){
     System.out.println("我是子類別的建構式");
}
void show(){
     System.out.println("姓名:"+name+"\t國文:"+chi+"\texcel:"+excel);
}
 
add2.java
a a1= new a();
a1.show();
 
=>在new a的時候,會先去查a class有沒有父類別,如果有,會去看繼承內容和是否有建構式,有建構式就會先做父類別的建構式再做a的建構式,如果school上還有父類別,會再往上找(即由上往下)
 
 
● 之後寫程式,盡量main的內容越少越好,都放在static class
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

(四)初始值(化)的方式(java.util.Arrays)
**陣列一定要有位址(記憶體)才能做資料
2){ }=>動態輸出=>自己決定初始值
(動態建立初始值的方式)
語法:類型[]陣列名={值,...,...,...}; =>陣列類型和值的類型要一致
EX:
如果使用new建立陣列,填值得時候要一筆一筆建立(如下),
當資料很多又同時都要輸入值,一筆一筆去改初始值很麻煩,就要用動態建立
chi[0]=65;
 
**{}會配給記憶體,但只會做到stack,不會給heap區,
如下{}沒給值,可以compiler但是執行會出現exception
int []chi={};
System.out.println(chi);
System.out.println(chi[0]); //因為還沒有產生chi[0]
 
3)比較new和{}的差別
new會配給記憶體,且給索引值和初始值(即heap區)
{}只會配給記憶體(只做到stack,但沒給heap區)
=>{}是打一個值就出現一個
 
=>new則是一次出現全部
 
 
**使用 java.util.Arrays的sort()來排序,
會把數字從小到大,文字(限定英文)從a到z排列
ex:(要記得先在class上面import java.util.Arrays;)
int []chi={100,70,88,64,33};
System.out.println(chi);
System.out.println(chi[0]);
for(int i=0;i<5;i++){
     System.out.println(chi[i]);
}
System.out.println("=========================");
Arrays.sort(chi);  //用Arrays裡的sort功能把chi陣列重新排列
for(int i=0;i<5;i++){
     System.out.println("chi["+i+"]="+chi[i]);
}
 
**使用binarySearch()來查陣列中是否有我們需要的資料,
binarySearch()是傳值類的method,所以執行完會產生一個值,
要指定如何輸出這個值
int []chi={100,70,88,64,33};
//要先做排列再查資料不然查出來的結果會怪怪的,
//另外srot()是void不傳值類的method
Arrays.sort(chi);  
for(int i=0;i<5;i++){
     System.out.println("chi["+i+"]="+chi[i]);
}
//要給的參數(要查的陣列名稱,要查找的資料)
System.out.println(Arrays.binarySearch(chi,64));
System.out.println(Arrays.binarySearch(chi,71));
=>當查找之後有資料,就會把查到的索引碼回傳(chi[1]=64)
=>但如果找不到資料,會去跟陣列的資料作比對排列,
像例子中71應該是排在索引碼3的位置,也就是第四個,
它會對應到負整數第四個位置,也就是-4(取負的索引碼)
=>所以只要回傳的值為負的,就代表找不到資料
 
(五)length=>查詢陣列的元素個數(可以用在迴圈的限制條件上)
int []chi={100,70,88,64,33};
System.out.println(chi.length);
for(int i=0;i<chi.length;i++){
     System.out.println(chi[i]);
}
 
(六)多維陣列
語法:類型[][]陣列名=new 類型[n][m];
=>分組的概念
=>組織圖有幾階段分組就會有幾個[][]
=>多維陣列中的[][]位置可以改變ex: int[] grade []
ex:有3個人,每個人有國文和英文兩個成績
(一)可以分成兩組,國文和英文,每組有三個人
int[]chi=new int[3];
int[]eng=new int[3];
 
(二)用多維陣列簡化作法
int[][]grade=new int[2][3];  
=>在記憶體中的做法就是,先找到grade array,
發現裡面有兩組陣列(chi和eng),再看陣列裡面,各有3個元素
**第一層就是第一個[],第二層就是第二個[],
所以上面代表先分2組,每組3個(由2個陣列組合而成)
**如果是[3][2]則代表先分3組,每個組別裡面有2個元素(由3個陣列組合而成),
與上述是不同的
=>畫成組織圖如下
 
=>組織圖如下:陣列表示應為school[3][2][3]
 
*看多維陣列的記憶體位址,如上例grade[0]和grade[1]兩組陣列都有記憶體位址
=>陣列的stack和heap排列方式與物件相同
 
*用巢狀迴圈run
動態:
int[][]陣列名稱={{xx,xxx,xx},{xx,xxx,xx}}(以兩組為例)
=>代表先分兩組,每組有3個元素
int[][]grade={{56,77,88},{66,73,91}};  
for(int x=0;x<2;x++){
  for(int y=0;y<3;y++){
    System.out.println("grade["+x+"]["+y+"]="+grade[x][y]);
  }
}
**如果直接用int[][]grade={56,77,88,66,73,91}
=>會出現錯誤訊息,因為前面是2維,後面是1維
 
*使用.length
ex:
int[][]grade={{56,77,88,99 } , { 66,73,91,63}};
System.out.println(grade); 
System.out.println(grade[0]);
System.out.println(grade[0][0]);
*[[I=>兩個[[代表有兩層陣列,有幾個就代表有幾層陣列
不論是查 grade 或grade[0]結果都是
[[I@..... 或[I@0000=>代表後面都是接記憶體位置,
只有 grade[0][0]才是值
=>只有查到最後一層才會是值,前面都只會查到記憶體位置
ex:
int[][]grade={{56,77,88,99 } , { 66,73,91,63}};
System.out.println(grade.length);  //outputs 2
System.out.println(grade[0].length); //outputs 3
*grade.length,查出來結果為2是因為grade的下是兩組陣列:
 length是線性的,只能查一層
 grade[0].length,查出來的結果為3,因為兩組陣列中每一組都是3個元素
應用到迴圈(一) 
=>迴圈中x代表第一個[],y代表第二個[]
int[][]grade={{56,77,88,99},{66,73,91,63}};
for(int x=0;x<grade.length;x++){
for(int y=0;y<grade[x].length;y++){
     System.out.println("grade["+x+"]["+y+"]="+grade[x][y]);
}
}
(二)如果兩組內的元素數量不同,用.length就不需要調整迴圈
int[][]grade={{56,77},{88,99,66,73,91,63}};
for(int x=0;x<grade.length;x++){
     for(int y=0;y<grade[x].length;y++){
         System.out.println("grade["+x+"]["+y+"]="+grade[x][y]);
     }
}
 
 
(七)值;位址=>"="  (java中做這個事為了回收記憶體;null),要判斷是值還是位址的換算
1)傳值=>passed by values
2)傳址=>passed by address
=>判斷"="兩邊是值還是位置,如果是值,會把資料copy過去,但如果是位置,
會把左邊的位置砍掉(回收記憶體),因此左邊的資料會消失,要非常注意!!
當y=x時,會有兩種狀況:
若只是資料copy,則x還是x,y還是y,兩者沒有關聯
若是y被x取代,則當y改變,x也會改變
 
(一)用變數來看
int x=10;
int y=20;
System.out.println("x="+x);
System.out.println("y="+y);
System.out.println("==========");
y=x;
System.out.println("x="+x);
System.out.println("y="+y);
System.out.println("==========");
y=30;
System.out.println("x="+x);
System.out.println("y="+y);
=>當y=x時,因為x和y都代表一個值,是把x的資料copy給y的動 ,所以當y=1時,x1[0]還是=1
 
(二)用陣列來看
int[]x1={1,2,3};
int[]y1={4,5,6};
System.out.println("x1="+x1);
System.out.println("y1="+y1);
System.out.println("==========");
System.out.println("x1[0]="+x1[0]);
System.out.println("y1[0]="+y1[0]);
y1[0]=x1[0];
System.out.println("x1[0]="+x1[0]);
System.out.println("y1[0]="+y1[0]);
y1[0]=100;
System.out.println("x1[0]="+x1[0]);
System.out.println("y1[0]="+y1[0]);
System.out.println("==========");
=> y1[0]=x1[0];是做資料copy的動作,所以當y1[0]=100時,x1[0]還是=1
 
 
y1=x1;
System.out.println("x1="+x1);
System.out.println("y1="+y1);
System.out.println("x1[0]="+x1[0]);
System.out.println("y1[0]="+y1[0]);
y1[0]=100;
System.out.println("x1[0]="+x1[0]);
System.out.println("y1[0]="+y1[0]);
=>當y1=x1時,是把y1指到x1的位址,所以會發現y1和x1的記憶體位置相同了,
這時去print x1[0]和y1[0]都會=1
=>再讓y1[0]=100;則 x1[0]和y1[0]都會變成100,因為是相同的記憶體位置
 
**java回收記憶體的方式:因為值都沒有記憶體,有記憶體都會常駐,如果都沒有使用還是會暫ram的空間
(一)用指定位址的方式,把y1刪除
int[]x1={1,2,3};
=>x1,y1代表位址,x1[0],y1[0]代表值
int[]y1={4,5,6};
y1=x1;
(二)用null的方式,直接把y1回收
int[]x1={1,2,3};
int[]y1={4,5,6};
System.out.println("x1="+x1);
System.out.println("y1="+y1);
y1=null;
System.out.println("x1="+x1);
System.out.println("y1="+y1);
 
(八)Java的陣列個數為固定,無法事後增加
int[] x={10,20,30,52};
for(int i=0;i<x.length;i++)
{
     System.out.println(x[i]);
}
System.out.println(x[4]);
System.out.println(x); //改變前的x
x=new int[10];
System.out.println(x); //改變後的x
for(int i=0;i<x.length;i++)
{
     System.out.println(x[i]);
}
=>可以compiler,但是記憶體位置改變了,等於產生了新的陣列
=>代表把新的位置傳給x,把原本的資料給砍掉了(不要舊的陣列要換一個新的陣列)
=>新的陣列所有值都變成初始值了
若再去查x[4],System.out.println(x[4]);=>會出現exception
 
(九)與物件導向結合應用
1.先定義陣列=>名稱為統一(決定數量)
2.物件再個別新增內容=>實體化
實例(一):建置一個會員資料庫,有三個欄位name,add,tel
靜態做法:
addmember.java
假設我們要輸入一百筆資料,輸出時不用陣列變成要一筆一筆輸出太麻煩
(一)
member aa=new member("aab1","city","123456789");
member dd=new member("aab2","city","123456789");
member cc=new member("aab3","city","123456789");
aa.show();
dd.show();
cc.show();
=>如果要用陣列,先判斷是否為同一組
=>因為aa/dd/cc都是用同一張表member有共同的reference,可以用陣列來做
 
(二)
class addmember{
     public static void main(String args[]){
          member[] m1=new member[3];
     }
}
=>member[] m1代表用member這張表作一個陣列,
new member[3]則代表先決定數量,此時m會配有記憶體
=>m[0]/m[1]/m[2]是三個物件而不是變數,
但這時候new只做了一件事就是定義三個物件的名字為 m[0]/m[1]/m[2],
並沒有配記憶體
=>如果這時候去print m[0],會出現null
=>當陣列結合物件時,第一次new是定義名字的動作,
個別物件要再new一次才能決定記憶體位置,如下:
 
member[] m=new member[3]; //等於是做上面(一)等號左邊命名的動作
//這邊開始才是做(一) 等號右邊new的動作
m[0]=new member("aab1","city","123456789");  
m[1]=new member("aab2","city","123456789");
m[2]=new member("aab3","city","123456789");
for(int i=0;i<m.length;i++){
     m[i].show();
}
 
 
**兩次new與配給記憶體的步驟
(1)第1次new時,只是用一個記憶體位址存放 m[0]/m[1]/m[2]這三個名字,
但沒有配給記憶體
(2)第2次new時,才會配給記憶體位址和heap區
 
**單獨使用new的說明
member aa=new member("aab1","city","123456789");
new member("aab2","city","123456789"); //可以compiler
System.out.println(aa);
System.out.println(new member("aab2","city","123456789"));
=>兩筆資料在java中都視為已完成,第2筆會丟一個位址出來,
所以可以print,且print會show記憶體位置
 
member aa=new member("aab1","city","123456789");
new member("aab2","city","123456789");
aa.show();
new member("aab2","city","123456789").show();
=>因為第2筆也是新增一個物件(物件就會有記憶體位址),
因為有記憶體位置所以可以做.show()
=>因為機器判斷時看的不是aa這個名字,而是記憶體位址
 
動態作法
addmember.java
member[] m={
new member("aab1","city","123456789"),
new member("aab2","city","123456789"),
new member("aab3","city","123456789"),
new member("aab4","city","123456789")};
 
for(int i=0;i<m.length;i++){
     m[i].show();
}
=>如果只有 member[] m={};,這時只會配給記憶體位置,不會配給索引碼
實例(二):
UML和流程圖
需要做s[0]~s[3],共4筆
student.java
class student{
private String name;
private int chi;
private int eng;
private int sum;
private double ave;
 
student(String name,int chi,int eng){
if(chi>=0 && chi <=100 && eng>=0 && eng <=100){
this.name=name;
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
}else{
     System.out.println("國文英文分數需介在0~100");
}
}
void show(){
System.out.println("姓名:"+name+
"\t國文:"+chi+
"\t英文:"+eng+
"\t總分:"+sum+
"\t平均:"+ave);
}
}
addstudent.java
class addstudent{
public static void main(String args[]){
student[] s ={
new student("kelly",90,100),
new student("kent",87,78),
new student("sylvie",73,55) ,
new student("maggie",100,63)
};
for(int i=0;i<s.length;i++){
       s[i].show();
}
}
}
*用scanner作互動(用scanner不能用動態)
addstudent.java
import java.util.Scanner;
class addstudent1 {
public static void main(String args[]) {
     Scanner sc=new Scanner(System.in);
     System.out.println("請輸入人數");
     int n=sc.nextInt();
     student[] s=new student[n];
     for(int i=0;i<s.length;i++) {
         System.out.print("第"+(i+1)+"的姓名");
         String name=sc.next();
         System.out.print("第"+(i+1)+"的國文");
         int chi=sc.nextInt();
System.out.print("第"+(i+1)+"的英文");
int eng=sc.nextInt();
s[i]=new student(name,chi,eng);
}
for(int i=0;i<s.length;i++) {
     s[i].show();
}
     }
}
=>這邊的name,chi,eng可以用區域變數,
因為輸入後就會把值丟給s[0],s[1],s[2],s[3],完成後就消失沒有關係
 
 
 
 
 
 
 
 
 
 
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

● 實作練習
UML
流程圖
1.school(名,國,英);
2.
 
add.java
class add
{
 public static void main(String args[])
 {
  school s1=new school("abc",-75,78);
  s1.show(); 
 }
}
 
school.java
class school{
private String name;
private int chi;
private int eng;
private int sum;
private double ave;
 
school(String name,int chi,int eng){
if(chi>=0 && chi<=100 && eng>=0 && eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;     //如果使用變數不能直接加"."要先括號起來再加
}else{
          System.out.println("國英分數須介在0~100");
}
}
void show(){
System.out.println("姓名:"+name+
"\t國文:"+chi+
"\t英文:"+eng+
"\t總分:"+sum+
"\t平均:"+ave);
}
}
 
**建構式都會會訂規則,所以在看reference時一定要先看,因為建構式在new的時候一定會執行
狀況1.如果沒有建構式school,但是add.java卻給了引數,會出現下列錯誤訊息
required(需要):no arguments=>不需要引數
 
狀況2.如果有建構式school,但是add.java卻沒有給引數,會出現下列錯誤訊息
required(需要):String,int,int=>需要三個引數
 
 
(5)Overloading(多載化;多種狀況)=>建構式名稱一樣,但是設計多種狀況,稱為多載化
=>名稱一樣
=>引數不一樣,幾個建構式名稱相同,就是要用()中的引數來區別
=>單選,每new一次只能選一個規則來使用
ex:假設有些狀況,只是要先填名字其他資料後續補上,所以有第二個規則,只需輸入名字,就另外再建立一個新的costructor
school.java
school(String name,int chi,int eng){
if(chi>=0 && chi<=100 && eng>=0 && eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
}else{
     System.out.println("國英分數須介在0~100");
}
}
school(String name){
     this.name=name;
}
add.java
school s1=new school("kelly",50,75); //new一次選一種規則使用
school s2=new school("david"); //new一次選一種規則使用
s1.show();
s2.show();
 
 
ex:
school(String name,int chi,int eng){
if(chi>=0 && chi<=100 && eng>=0 && eng<=100){
this.name=name;
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
}else{
     System.out.println("國英分數須介在0~100");
}
}
school(String name){
     this.name=name;
}
school(String name,int chi) { ...}
school(int chi, String name) { ...}
school(String x, int y,int z , int a) {... }
school(String x , int y) { ...}
**假設有上述這麼多規則,多載化的區別包含類型(資料類型)、
  數量(需要輸入的引數數量)、順序(各個引數的排序),
  如果完全相同就會出現錯誤訊息如下
  所以最後一個是錯的,因為和第三個類型數量及順序都重複了,
  變數的名稱則沒有任何影響
 
● Methods方法(其他語言稱函式)
(一)java api
(二)內部函式庫=>java.lang.*;
=>預設直接載入,直接存取(java api把最常使用的函式都放在java.lang)
ex:
System.out.println(Math.PI);
//找到lang下的math class中field,有PI,
//因為是static開頭,存取時不需要加上new,可以直接使用
 
ex:
System.out.println(Math.abs(-10));  //outputs 10
//outputs 1024.0 (因為類型為double所以會有小數點)
System.out.println(Math.pow(2,10));
 
*abs()=>絕對值
 random()=>亂數
 pow(a,b)=>a的b次方
 
(三)外部函式庫=>非java.lang.*都算
a)絕對路徑(若沒告知路徑會當作在java.lang中)
b)import(在class之前要先把要用的函式位置寫好)
=>也可以寫作import java.util.*,但不建議這麼做,因為後續程式碼很多,
要找問題時要看那些功能可以直接找上面,若沒一項項列出會增加查文件的困難度
import java.util.Scanner; //需要寫到Scanner這個class為止
class add
{
 public static void main(String args[])
 {
  //java.util.Scanner sc = new java.util.Scanner(System.in);
 //=>加了import就不需要指定路徑
  Scanner sc=new Scanner(System.in);
  school s1=new school("name",75,78);
  school s2=new school("aaa");
  s1.show();
  s2.show();
 }
}
 
(四)常用的api函式
a)java.util.*;
b)java.io.*; =>之後和field和dtabase一起講
c)java.SQL.*; =>之後和field和dtabase一起講
 
(五)自訂方法method(自訂函式)
1)語法:類型 方法名稱(引數){ 步驟 }
*引數區域和全域的區別與建構式一樣=>要判斷時一樣可以使用this
2)類型:
a)傳值=>void
b)不傳值=>return(與"="一樣)
ex:如果輸入成績時輸錯了,不能再使用school的constructor
 
(狀況一)如果直接再用一次new school=>會出現下列錯誤訊息,s1已經定義了
school s1=new school("kelly",50,75);
school s1=new school("kelly",50,75);
s1.show();
 
(狀況二)如果用s2 來new school=>則s1和s2會變成兩個不同人
school s1=new school("kelly",50,75);
school s2=new school("kelly",50,75);
s1.show();
 
(正確狀況)
add.java
school s1=new school("kelly",50,75);
s1.show();  //修改前
s1.change(70,75);
s1.show();  //修改後
class.java =>加上下列內容
void change(int chi,int eng){
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
}
ex:如果有兩個人的資料都錯了修改後,要修改後的加總
 
1.如果直接用System.out.println(s1.change(80,75)+s2.change(77,75)),會出現下列錯誤訊息
因為void只能執行method中的步驟,不能做加減乘除的運算,因為它不是值也不是變數(做加減乘除運算時,左右兩邊都要是值或變數,但目前兩邊都是步驟)
 
2.如果需要把method的結果拿來做運算,執行完畢可把它視作變數,因此要使用變數的規則來定義=>即要定義類型(ex:int,String...)
所以跟變數一樣,要給初始值,如果沒給初始值,會出現錯誤訊息(missing return statement)如下
int change2(int chi,int eng){
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
}
 
3.正確做法:這邊return sum的意思是,把sum指定給 int change2(int chi,int eng),讓他可以做加減乘除
**return就和"="的用法一模一樣
school.java
int change2(int chi,int eng){
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2.;
return sum; //return後面可放值、變數或計算式,但後面指定內容的類型必須和一開始 int change2(int chi,int eng)的類型相同
}
 
add.java
school s1=new school("kelly",50,75);
school s2=new school("joanne",50,75);
s1.show();
s2.show();
System.out.println("兩人的總分和為:"+(s1.change2(80,63)+s2.change2(77,70)));
s1.show();
s2.show();
 
*return也可單獨運用,有傳值回來,只是沒有拿來做運算
school s1=new school("kelly",50,75);
school s2=new school("joanne",50,75);
s1.show();
s2.show();
s1.change2(80,63);
s1.change2(77,70);
s1.show();
s2.show();
3)Overloading(規則與建構式同)=>目的是為了盡量用最少的單字做最多的事
**與建構式的差別在於,建構式不需要給類型,且只有new的時候要用建構式,事後要修改都用method
=>規則和constructor一樣,用()中的內容來區別,只用引數的類型、數量和順序做判斷,傳值(void)不傳值(return)也不列入考慮
ex:
void change(int chi,String name) { ...}
void change(String name,int chi){ ...}
int change(int x, String y){return 100;}
void change(int x, String y) { ...}
最後兩個都和第一個數量、類型、順序一樣,所以無法compiler,是否傳值不列入考慮
 
*加上method和overloading以後重畫一次UML如下:
● 實作練習-薪資與獎金(針對業務員)
1)輸入=>姓名和業績
2)底薪:18,000
3)業績/獎金比
150萬以上         7%
100萬~150萬     5%
50萬~100萬      3%(0.03)
0~50萬             0%
=>獎金=業績*獎金比
4)Database
姓名:name
業績:x1
獎金比:x2
獎金:x3
底薪:x4
實領薪資:x5
 
5)UML和流程圖
salary.java
class salary{
private String name;
private int x1;
private double x2;
private int x3;
private int x4;
private int x5;
 
salary(String name, int x1){if(x1>=1500000){  //從大的開始判斷
     x2=0.07;
    //如果沒有把this.x1=x1放在if中,當x1<0時還是會顯示,
    //無法過濾,設定後如<0,println時就會直接把x1帶初始值
     this.x1=x1;      
}else if(x1>=1000000 && x1<1500000){
     x2=0.05;
     this.x1=x1;     
}else if(x1>=500000 && x1<1000000){
     x2=0.03;
     this.x1=x1;  
}else if(x1>=0 && x1<500000){
     x2=0;
     this.x1=x1;   
}else{
     System.out.println("業績必需>=0");
}
this.name=name; //要區分區域或全域,所以要加this
 //因為x2為double,但x3為int,所以這邊要做轉型
x3=(int)(x1*x2);  
x4=18000; //因為是固定數,也可在上面定義變數時直接設定好
x5=x4+x3;
}
void show(){
System.out.println("姓名:"+name+
"\t業績:"+x1+
"\t獎金比:"+x2+
"\t獎金:"+x3+
"\t底薪:"+x4+
"\t實領薪資:"+x5);
}
add2.java
class add2{
public static void main(String args[]){
salary sc = new salary("kelly",700000);
sc.show();
}
}
 
如果要使用Scanner,做法如下:
addtest.java
public static void main(String args[]){
    //new就是把Scanner的所有東西全部丟給sc
java.util.Scanner sc = new java.util.Scanner(System.in);  
System.out.println("請輸入姓名");
String y1=sc.next();
System.out.println("請輸入業績");
int y2=sc.nextInt();
salary sc2 = new salary(y1,y2);
sc2.show();
}
 
● Array(陣列)
(一)變數名(陣列簡單說就是分類的命名);相同類型的多個變數;同一機構同一組
=>避免使用太多英文名稱命名,增加複雜度,可以用一個"共同"名稱代表全體,個別再以"暫數"索引碼區別,限定整數
=>分組的概念
=>陣列具有物件的特性,是因為也是使用new的規則(有配記憶體)
 
int[] chi;=>這樣compiler可以過,但如果把它print出來會有下列錯誤訊息
 
因為int chi[];=>此時尚未產生陣列,要透過new才會產生記憶體位置
int chi[]=new[3];
System.out.println(chi);
產生如下訊息,這裡"["代表的是陣列,"I"代表int,@15db9742代表所在記憶體位置
=>可以想成產生3個空白的格子並且配有int大小和初始值(如果是class每格的大小可能不同,因為資料類型不同,但這邊資料類型相同所以每格大小相同)
=>初始值和class一樣=>int:0,double:0.0,boolean:false,String:null
 
(二)語法:類型[ ] 陣列名 = new 類型[n]; n=數量;個數 ,編碼從0開始,[0]、 [1]、....
=>int[] chi的[]代表這是一個陣列類型,chi才是陣列名稱
=>chi[0]會先找chi即記憶體位置,然後再找[0]編號
int[]chi=new int [3]; //等號兩邊的類型必須相同
System.out.println(chi[0]);
System.out.println(chi[1]);
System.out.println(chi[2]);
 
(三)輸出陣列的值
1)for(; ; ) =>有索引碼
2) for-each 加強型 =>沒有索引碼
語法:for(類型 變數:陣列)
**foreach的類型必須和陣列的類型相同
public static void main(String args[]){
int chi[]=new int[3];
for(int x=0;x<3;x++){    //這邊的int指的是索引碼是int
     System.out.println(chi[x]);
}
for(int o:chi){   //這邊的int指的是o必須為int所以要和陣列的類型相同
     System.out.println(o);
}
}
**這邊o:chi的":"會先去判斷chi有無資料,如果有,就會把找到的第一個值指定給o,然後再回去chi看還有沒有資料,如果有再把找到的第二個值指定給o,若是沒有找到就是false,就會停止run
 
(四)初始值(化)的方式
1)new=>靜態輸出,只要有new就會有記憶體(即實體化)
 =>new先給 =>new只給記憶體位址不給初始值
=>事後再更新
ex:各種初始值
int
int chi[]=new int[3];
for(int x=0;x<3;x++){
     System.out.println(chi[x]);
}
System.out.println("======================");
for(int o:chi){
     System.out.println(o);
}
double
double chi[]=new double[3];
for(int x=0;x<3;x++){
     System.out.println(chi[x]);
}
System.out.println("======================");
for(double o:chi){
     System.out.println(o);
}
boolean
boolean chi[]=new boolean[3];
for(int x=0;x<3;x++){
     System.out.println(chi[x]);
}
System.out.println("======================");
for(boolean o:chi){
     System.out.println(o);
}
String
for(int x=0;x<3;x++){
     System.out.println(chi[x]);
}
System.out.println("======================");
for(String o:chi){
     System.out.println(o);
}
 
2){ }=>動態輸出=>0801
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

● (一)判斷java程式無法執行原因
(1)JRE=> 如果換了電腦以後,原本可執行的*.class卻不能執行了,
要檢查該電腦是否有安裝JRE(JDK是編譯用) 
 
(2)動態class(main)/靜態class
=>如下例,如果有main方法,是可以執行的,但如果沒有main方法,
只有class ex1{}就無法執行,但兩個做法都可以編譯
class ex1{   public static void main(String args[]){ } }
 
(二)Object物件(一筆資料)=>一個物件(可以記錄下來)就想成是一筆資料
(1)資料庫紀錄的資料
 =>資料表(table):資料庫用資料表的方式來儲存資料
 =>每一筆資料的欄位(欄位就是field)標題(attribute屬性):
共同規則 、定義、一次重複使用 建立資料表時,
要先定義每個欄位的名稱(標題又稱細目),因為要儲存的是data,就牽涉
datatype也要先定義好(ex:姓名/電話/地=>String),
上述只要定義一次就可以針對每一筆資料重複使用這些定義和規則
 
String name1="a1";
String add1="b1";
String tel1="c1";
 
String name2="a2";
String add2="b2";
String tel2="c2";
 
String name3="a3";
String add3="b3";
String tel3="c3";
 
System.out.println("名:"+name1+"\t地址:"+add1+"\t電話:"+tel1+"\n");
System.out.println("名:"+name2+"\t地址:"+add2+"\t電話:"+tel2+"\n");
System.out.println("名:"+name3+"\t地址:"+add3+"\t電話:"+tel3+"\n");
 
*如果不用物件導向的方式直接寫程式,三筆資料就要九個變數,
如果需要改變規則像是改變資料類型,就需要一筆一筆去改變
 
(2)新增資料時
1.定義要在哪一張"資料表"(reference)=>定義資料的共同規則要在靜態的class
 2.新增這筆資料=>在動態class做
ex:
class ex2{
String name;
String add;
String tel;
}
*另外開一個靜態class ex2,先定義都會用到的3個欄位標題(屬性):name,add,tel
 
(3)新增物件(資料的方式)=>或稱"實體化;初始化"物件
*java中不能只定義變數或物件,一定要"初始化"ex:給初始值
語法:
類別    物件名 = new  類別();  
類別=>使用的class=>reference(要用哪一個class的規則來新增資料) 
=>等號左右兩邊的類別(class)要相同  
*如果要查程式碼的某個字是變數或是物件,可以直接用println(要查詢的內容),當輸出的是一個值,那就是變數,輸出的內容為aaa@xxxx
 則該查詢內容為物件,且其reference為@前的aaa
ex:
ex2 n1;
System.out.println(n1);
*ex2=>規則(類別),n1是第一筆資料 =>沒初始化之前,n1就像是表格的第一行但還沒產生實際的格子,初始化後才會產生格子
 
ex:
ex2 n1=new ex2();
ex2 n2=new ex2();
System.out.println(n1);
System.out.println(n2);
*因為class有很多筆資料,所以不能直接給值,要用new新增一張表的資料給n1
*如果把上述程式編譯後執行,會出現如下列內容,ex2=>代表n1和n2屬於哪個reference,@......,後面是一個16進位的序號代表n1和n2的記憶體位置
 
(三)new執行的步驟
**ex2=>代表n1和n2屬於哪個reference(要去執行哪個class,以後要查reference可以用這個辦法)
(1)配發記憶體=>實體化(stack)
=>new的背後就是一張記憶體表,如下圖,每一個class會有一個不同的記憶體
=>以上述例子來說,要查n1就是查ex2@(在ex2中)的xxxxxxx(n1的位置),後面的欄位代表n1的name, n1的add, n1的tel
(這邊的name、add、tel是沒有配記憶體的)
=>以ex2的例子來說,new就是給n1和n2一個記憶體位置
=>以java.util.Scanner sc = new java.util.Scanner(System.in);來說,new就是給sc一個記憶體位置
 
(2)產生初始值=>heap
=>heap是class中的每一個值所放的位置
=>heap這個動作是由new ex2()中的ex2來做
=>會把n1,n2的 name,add,tel給好初始值
=>不同資料類型的初始值不同,String的初始值為null,int的初始值為0, double的初始值為0.0,布林的初始值為false
=>如果程式要呼叫n1的name欄位,就要用n1.name
ex2:
String name;
int add;
double tel;
 
ex1:
ex2 n1=new ex2();
ex2 n2=new ex2();
System.out.println(n1);
System.out.println(n1.name); //null
System.out.println(n1.add);  //0
System.out.println(n1.tel);  //0.0
System.out.println(n2);
 
(3)如果有設計建構式(constructors),會執行建構式的動作=> new ex2() 的()部分  
 
例子:有一個輸入成績單的程式,要傳到資料庫
先分析欄位標題(即每筆資料的屬性)=>去分析除了使用者輸入的資料還需要保留多少資料(ex:這邊多了總分和平均)
1.先訂定管理的class(訂好所有人的共同規則or屬性)
class student{
String name;
int chi;
int eng;
int sum;
double ave;
void show(){
System.out.println(
"名:"+name+
"\t國文 :"+chi+
"\t英文:"+eng+
"\t總分:"+sum+
"\t平均:"+ave);
}
}
*定義5個屬性/欄位名稱和要重複使用的println功能=>當new的時候會一起使用
*java可以用enter換行程式碼,且不影響執行
**在設定管理的class時(在student.class),可以預設初始值,且初始值可以計算
**但在add.java新增資料時,機器不知道sum會隨著chi和eng的變動而變動
**當new的時候,他的步驟是
   1.student@xxxx配給s1記憶體位置
   2.查從String name;......到show()的資料(但show()這個method要呼叫才會執行),
   並且查是否有和此class相同名稱的contractor,有就會去執行
class student{
     String name;
int chi=60;
int eng=70;
int sum=chi+eng;
double ave;
}
 
add.java
s1.chi=90;
s1.eng=70;
s1.sum=s1.chi+s1.eng;
s1.show();//這邊outputs chi和eng分別為90和70,但sum會是130而非160
 
原因如下:
當在add.java指定s1.chi=65時,已經到堆疊第二層了,可是當執行s1.show()的時候,
機器只知道chi要抓第二層資料,但並不知道應該在sum上面再堆疊一層新的加總值
(因為機器不知道sum會隨著chi和eng的變動而變動)
所以某個變數有變動或是要做計算會影響到其他變數時,
要在new之後重新計算/run一次,變成s1.chi+s1.eng=s1.sum
所以用contructor(在new的時候產生)或method(事後修改用method)來設計就不需要再重新run一次了
 
 
*封裝的權限(被使用/呼叫的權限)=>public、protect、default、private
  當加了private以後,就無法直接引用
  ex:在student.class中,如果設定private int chi;到add.java用si.chi=65;,
  再去compiler,會出現無法存取的錯誤訊息
2.新增資料如果不使用建構式,可以在add.java直接給值,但這樣有很多問題,
像是想加規則條件都不能做 ex:要設定不接受負號"-"(負數),若沒有用private,
設定s1.chi=-65是可以過的
所以不建議這麼做,用建構式給定規則會比較好
ex:
sutdent s1=new student();
s1.show();//outputs皆為初始值
s1.name="aaa"; 
s1.chi=60;
*這邊指的是s1的name要為aaa,s1的chi要為60
(四)Contructours(相當於資料庫的驗證規則)
(1)"new"新增物件時最後執行的步驟
(2)名字必須與"class"名稱一樣
(3)語法:建構式名(引數){ 執行的步驟 }
=>建構式名與class名相同
eX:
class student{
String name;
private int chi;
private int eng;
private int sum;
private double ave;
student(){
     System.out.println("請輸入一位學生");  
}  //建構式
}
**新增資料時,所有要設定的規則都可以在建構式做
(包含:設定初始值、計算式、判斷式...)
class student{
...
student(){
chi=60;
eng=60;
sum=chi+eng;
ave=sum/2;
}
...
}
 
(4)Local(區域)/global(全域)變數的生命週期
=>this:當無法判斷是全域還是區域變數時(如ex3),
要指回物件本身的屬性(就是指我們在new一個物件時,一開始就定義的屬性)就要在前面加this
 
ex1:
class student{
String name;
private int chi;
private int eng;
private int sum;
private double ave;
 
student(){
int chi=60; //區域變數,只要在{}重設int就會產生一個新的變數
int eng=60; //區域變數
//這邊相加的時候,會先找在同一個 {}內的chi和eng,所以總分會是120
sum=chi+eng;
ave=sum/2;
}
 
void show(){
System.out.println(
"名:"+name+
//在找chi和eng時,會找同一層{}內的chi和eng,
//如果找不到就會往外找,找到最上面一開始定義student的chi和eng屬性,
//初始值都為0
"\t國文 :"+chi+
"\t英文:"+eng+
//因為sum在student()建構式中沒有另外定義,所以還是抓一開始定義的sum
"\t總分:"+sum+
"\t平均:"+ave);
}
}//輸出會得到國文:0 英文: 0 總分:120
**但是區域變數並不會這樣使用,而是用在引數(參數)處
**引數:用來引用外部資料(把外部key的資料帶入),如果沒有引數,就無法接收外部資料
ex2:
1.先將student建構式改成如下
student(int chi,int eng){  }
2.去compiler add.class會出現錯誤訊息
add.java內容如下:
student s1=new student ();
s1.show();
 
*錯誤訊息:因為contructor要求兩個int引數,可是add中沒有
 
3.帶入引數的方法為,在add.java中改為
student s1=new student (90,89);
s1.show();
**這邊的90,89的資料類型必須和student建構式中的引數int chi及int eng的資料類型相同
 
ex3:
student(int x, int y){
chi=x;
eng=y;
}
去run add.class,會有output 國文:90 英文:89
 
但java為了之後寫文件需要,會把引數的名字和欄位定義為一樣的單字
這時將x,y改為chi和eng,output會變成 國文:0 英文:0
student( int chi , int eng ){
chi=chi;
eng=eng;
}
這是因為chieng(紅色的)又被限定在這個{}內,所以又會去找同層的chi和eng,
就會找到 chieng,被指回int chi和int eng
但是在執行show()的時候,找的是一開始定義的屬性private int chi; 
private int eng;,沒有被上述建構式指到,所以還是0
**所以這邊要能跑出資料,要指回物件(student class)本身的屬性,
  要在chi和eng前面加上this,this指的就是student物件本身
  (this=>attribute of the object)
 
 
student.class
class student{
String name;
private int chi;
private int eng;
private int sum;
private double ave;
 
student(int chi,int eng){
if(chi>=0 && chi <=100 && eng>=0 && eng<=100){
this.chi=chi;
this.eng=eng;
sum=chi+eng;
ave=sum/2;
}else{
     System.out.println("0~100");
}
}
 
void show(){
System.out.println(
"名:"+name+
"\t國文 :"+chi+
"\t英文:"+eng+
"\t總分:"+sum+
"\t平均:"+ave);
}
}
 
add.class
class add{
public static void main(String args[]){
student s1=new student (-5,89);
s1.show();
     }
}
*在編譯add時,如果有查到裡面有其他的class,會連同這些class一起編譯
 
(5)Overloading(多載化;多種狀況)=>7/31
=>名稱一樣
=>引數不一樣
 
(五)UML(Unified Modeling Language)=>類別圖,是一種模組化的概念
1.類別名稱(class)
2.field區=>每一筆物件詳細的細目(變數)/attribute,其中"-"代表private
3.constructors
4.methods
=>每一個類別圖代表一個class,裡面只要寫摘要不要寫內容(內容是流程圖)
=>紅色的兩項最重要
 
 
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

● Loop迴圈,重複結構(連續)
(一)for(1;2;3){
      重複連續步驟.....
      }
1=>次數索引變數,要給初始值
2=>判斷loop是否停止或繼續做
  =>true:執行
      false:停止
*這邊2不一定要跟1有關,可以用迴圈之外的變數做判斷
  2其實和if是一樣的意思,所以可以用多個條件,但是不建議
3=>設計如何讓loop停止的規則=>計算是與2有關
ex1:
for(int x=1;x<6;x++){
System.out.println("x="+x+"\thello");
}
 
ex2:
int y=2;
for(int x=0; x<=50 && y<=30 ; x+=2 , y++){
System.out.println("x="+x+"\thello");
}
*這邊因為當x++超過50時,就變成false &&中斷機制發揮
,所以也不會再去判斷y<=30
 x++後面要加上,才能加第二個條件
 int y的宣告也可以放在for迴圈中
,變成 for(int x=0 , y=2; x<=50 && y<=30 ; x+=2 , y++)
 但建議for的條件不要設得太複雜
 
ex3:
for(int x=0,y=0; x<=100 && y<=30 ;){
System.out.println("x="+x+"\thello");
x=x+2;
x=2*x+1;
y=3*x-1;
} /
/outputs
x=0    hello
x=5    hello 
*也可以3的設定停止規則不寫,改放到迴圈中,如上述例子
 
ex4:
java.util.Scanner sc = new java.util.Scanner(System.in);
int n=sc.nextInt();
for(int x=0;x<=n;x++){
System.out.println("x="+x+"\thello");
}
 
(二)while(條件式) 步驟..... }=>條件式(true/false)
      =>不確定總次數為多少時使用
ex:
int x=1;
while(x<=10){
System.out.println("x="+x+"\thello");
x++;
}
*while的條件式只能放一個,且不能定義變數,變數要先在外面定義好
 while的停止規則要放在{}中
 
(三)do步驟....     }while(條件式);
      =>和while的差別在於,當條件不符合時
      ,do...while會執行一次才停, while不會執行
      =>判斷式的起始值如果是固定值,兩者就會相同,
     但如果起始值是個不確定數(變數),結果就可能會不同
ex:
int x=1;
do{
System.out.println("x="+x+"\thello");
x++;
}while(x<=10);
    
(四)break(符合條件就停止)和contiune(不執行符合條件的那一次,其他繼續,只能在loop中使用)
ex:
java.util.Scanner sc = new java.util.Scanner(System.in);
int n=sc.nextInt();
for(int x=0;x<=n;x++){
if(x==51) break;
System.out.println("x="+x+"\thello");
}
*break要搭配if來使用,如果這邊條件設定為if(n==51) break;
 代表當n輸入為51時才會break,輸入52還是會跑52個迴圈
 for/do...while/while可以在{}內加另外的條件設定
 
ex1:
java.util.Scanner sc = new java.util.Scanner(System.in);
int n=sc.nextInt();
for(int x=0;x<=n;x++){
if(x==51) continue;
System.out.println("x="+x+"\thello");
}
*continue要搭配if來使用,執行時會直接跳過x==51不做,往下繼續做,如下圖
 
ex2:
java.util.Scanner sc = new java.util.Scanner(System.in);
int n=sc.nextInt();
for(int x=0;x<=n;x++){
if(x>=41 && x<=51) continue;
if(x>=71 && x<=80) continue;
if(x==101) break;
System.out.println("x="+x+"\thello");
}
*當x在41~51中跳過,x在71~80中也跳過,x=101後停止執行,如下圖
  
  
(五)label標籤=>與巢狀迴圈搭配使用
=>類似網頁的錨點功能,作為位置的標記
=>java的標記功能只能用在loop,針對loop給一個編碼(可任意取名字)
=>做法為在迴圈的前一行給個代號,如: a:
ex:九九乘法表
for(int x=1;x<=9;x++){
     for(int y=1;y<=9;y++){
          System.out.print(x+"*"+y+"="+(x*y)+"\t"); 
     }
     System.out.println();
}
* System.out.print()是不換行, System.out.println()是要換行,
  且可單獨列出來不帶入內容作為換行之用
  所有的regular expression都是針對字串使用,所以都要加上""
 
ex:
java.util.Scanner sc = new java.util.Scanner(System.in);
int n=sc.nextInt();
int m=sc.nextInt();
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
System.out.print(x+"*"+y+"="+(x*y)+"\t");
}
System.out.println();
*當n=4,m=7時,結果如下圖,可以知道,
 第一個for決定多少列(橫),第二個for決定多少欄(直)
 
ex:
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.println("請輸入列數");
int n=sc.nextInt();
System.out.println("請輸入欄數");
int m=sc.nextInt();
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
System.out.print(" *");
}
System.out.println();
}
*可以用*做表格,如下圖
 
ex:
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.println("請輸入列數");
int n=sc.nextInt();
System.out.println("請輸入欄數");
int m=sc.nextInt();
for(int x=1;x<=n;x++){
for(int y=1;y<=m;y++){
     if(x==7) break;
     if(y==8) break;
     System.out.print(x+"*"+y+"="+(x*y)+"\t");
}
     System.out.println();
}
*break的限制條件:當遇到巢狀迴圈時,break只能控制所在的那一層迴圈停止
  所以上述例子,只停了x=7*1 ,7*2 ,7*3...那一層
 
調整的作法有兩種:
(一)把 if(x==7) break;拉到上一層迴圈(迴圈很多層的時候容易出問題)
for(int x=1;x<=n;x++){
     if(x==7) break;
for(int y=1;y<=m;y++){
     if(y==8) break;
     System.out.print(x+"*"+y+"="+(x*y)+"\t");
}
     System.out.println();
}
(二)使用label
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.println("請輸入列數");
int n=sc.nextInt();
System.out.println("請輸入欄數");
int m=sc.nextInt();
a:
for(int x=1;x<=n;x++){
b:
for(int y=1;y<=m;y++){
     if(x==7) break a;
     if(y==8) break;
     System.out.print(x+"*"+y+"="+(x*y)+"\t");
}
     System.out.println();
}
*  if(x==7) break a;代表把迴圈從標記為a的那一層開始使用停止條件
 
實作練習
(一)找零錢程式(尺:26元/筆:39元/圓規:45元)
1.需求:
a)使用者輸入數量(X,Y,Z)=>計算總價(Sum)(應付)
b)輸入使用者付款金額(pay)=>計算找零多少元?
class ex3{
public static void main(String args[]){
java.util.Scanner sc = new java.util.Scanner(System.in);
 
int pay,sum;
 
System.out.println("請輸入尺的數量");
int x=sc.nextInt();
System.out.println("請輸入筆的數量");
int y=sc.nextInt();
System.out.println("請輸入圓規的數量");
int z=sc.nextInt();
sum=26*x+39*y+45*z;
System.out.println("一共"+sum+"元\n");
System.out.println("請輸入付款金額");
pay=sc.nextInt();
System.out.println("找你"+(pay-sum)+"元");
}
}
*變數可以一次定義多個,用","隔開即可
 
class ex3{
public static void main(String args[]){
java.util.Scanner sc = new java.util.Scanner(System.in);
 
int pay,sum;
 
System.out.println("請輸入尺的數量");
int x=sc.nextInt();
System.out.println("請輸入筆的數量");
int y=sc.nextInt();
System.out.println("請輸入圓規的數量");
int z=sc.nextInt();
sum=29*x+39*y+49*z;
System.out.println("一共"+sum+"元\n");
System.out.println("請輸入付款金額");
pay=sc.nextInt();
int h=(pay-sum)/100;
int t=(pay-sum-100*h)/10; //((pay-sum)%100)/10
int o=(pay-sum-100*h-10*t);//(pay-sum)%10
System.out.println("找你"+h+"張一百元\n");
System.out.println("找你"+t+"個十元\n");
System.out.println("找你"+o+"個元\n");
System.out.println("總共找你"+(pay-sum)+"元");
}
*上例變化,利用%算出百元、10元、1元個找多少
 
(二)設計一程式判斷是否錄取(學校)
需求:
1.輸入3科目=>國(chi)、英(eng)、數(math)
2.分2階段篩選
a)第一階段:總分滿200分(sum)
b)第二階段:數學75分=>兩階段都符合才錄取
程式要求:
1.輸入分數項目
2.判斷
a)是否錄取
b)不錄取的原因為何
=>第一階段未滿200
    第二階段滿200,數學未達標
class ex4{
public static void main(String args[]){
java.util.Scanner sc = new java.util.Scanner(System.in);
System.out.println("請輸入國文分數");
int chi=sc.nextInt();
System.out.println("請輸入英文分數");
int eng=sc.nextInt();
System.out.println("請輸入數學分數");
int math=sc.nextInt();
int sum=chi+eng+math;
if(sum>=200){
if(math>=75){
System.out.println("總分:"+sum+"分,數學:"+math+"分,錄取!");
}else{
System.out.println("總分:"+sum+"分,數學:"+math+"分,未錄取!");
}
}else{
System.out.println("總分:"+sum+"分,數學:"+math+"分,未錄取!");
}
}
}
 
(三)等差數列(1+2+3+x+....+n=sum)
1.堆疊=>用總分作堆疊 (sum=sum+1=>sum+=1往上疊的概念)
2.迴圈
x=1=>sum=1
x=2=>sum=1+2=sum+2
x=3=>sum=1+2+3=sum+3
x=4=>sum=1+2+3+4=sum+4
導出公式=>sum=sum+x
class ex5{
public static void main(String args[]){
     java.util.Scanner sc = new java.util.Scanner(System.in);
     int sum=0;
     int n=sc.nextInt();
     for(int x=1;x<=n;x++){
     sum=sum+x;
     System.out.println("x="+x+"\tsum="+sum);
}
}
}
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

main(String args[])中的[]如果沒寫,可以compilier,
但不能執行,會出現錯誤訊息:找不到主方法,這就代表main有錯!
 
class name最好和檔名一致,
因為compilier後產生的*.class檔名會以前面的class name命名
 
● Operator 運算子、元、符號
(一)算術運算子( +-*/% )
int x=10;
int y=3;
 
System.out.println("x+y="+(x+y));
System.out.println("x+y="+(x-y));
System.out.println("x+y="+(x*y));
System.out.println("x+y="+(x/y));
//要有小數點要先把分子或分母任一變成double
System.out.println("x+y="+(double)(x/y));
//在x/y的時候已經先把結果視為int,去掉小數才轉型為double
System.out.println("x+y="+((double)x/y));
System.out.println("x+y="+(x%y));
 
(二)指定運算子(遞增/減)
1.   =  :等號的左邊一定要是變數(將變數視為容器),不能為計算式,
右邊可為值、變數或計算式 ,所以程式一定會先run右邊得到一個結果再給左邊
Int x=10;
x =20;
這時候,10還是存在,是一種資料堆疊的概念,有兩個不同時間點的x,
但在java中會永遠保持兩層,有第3層時會把第1層刪掉
Ex:
int x=10; // 第一層x
System.out.println("x="+x);
x=x+20; //第二層x
System.out.println("x="+x);
x=2*x+25; //第三層x已抽掉第一層x,用第二層x計算
System.out.println("x="+x);
 
2.+=、-=、*=、/=、%=
Ex:
int Chinese=98;
//Chinese=Chinese+10;
Chinese+=10;
System.out.println(Chinese);
 
//Chinese=Chinese-10;
Chinese-=10;
System.out.println(Chinese);
 
//Chinese=Chinese*10;
Chinese*=10;
System.out.println(Chinese);
 
//Chinese=Chinese/10;
Chinese/=10;
System.out.println(Chinese);
 
//Chinese=Chinese%3;
Chinese%=3;
System.out.println(Chinese);
 
 
3.++,--
X++=>x+1
X--=>x-1
運算符號有先後順序,所以++x和x++會不一樣
Ex:
int x=10;
int y;
++x; y=x //output x=11,y=11
y=x++; //output x=11,y=10,因為先做y=x;再做x=x+1;
y=++x; //output x=11,y=11,因為先做x=x+1;再做y=x;
 
(三)關係運算子(relation)=>判斷式用
1.結果(True/false)
2.>、<、>=、<=、==、!=
Ex:
int chi=65;
 
System.out.println("chi>60---->"+(chi>60)); //outputs true
System.out.println("chi<60---->"+(chi<60)); //outputs false
System.out.println("chi>=60---->"+(chi>=60)); //outputs true
System.out.println("chi<=60---->"+(chi<=60)); //outputs false
System.out.println("chi==60---->"+(chi==60)); //outputs false
System.out.println("chi!=60---->"+(chi!=60)); //outputs true
 
(四)條件運算子=>多個判斷條件
1.&&(AND)、||(OR)
EX:
int chi=70;
int eng=80;
System.out.println("chi>65 && eng>90---->"+(chi>65 && eng>90)); //outputs false
System.out.println("chi>65 || eng>90---->"+(chi>65 && eng>90)); //outputs true
 
2.^(XOR):至少一個true,但全都為true時會變false
Ex:
int chi=70;
int eng=95;
//outputs true
System.out.println("chi>65 || eng>90---->"+(chi>65 ^ eng<90));
//outputs true
System.out.println("chi>65 ^ eng>90---->"+(chi>65 ^ eng>90));
 
3.!(not):反轉結果把true=>false把false=>true
int chi=70;
int eng=95;
//outputs false
System.out.println("chi>65 && eng>90---->"+(!(chi>65 && eng>90)));
//outputs true
System.out.println("chi>65 ^ eng>90---->"+(!(chi>65) ^ eng>90));
 
(五)位元,位移運算子=>會轉成2進位計算,再轉10進位顯示成果
1.位元 :
&(AND=>乘):
5=>00000101
2=>00000010
=>00000000 =>10進位的0
EX:
int chi=70;
int eng=80;
// outputs false
System.out.println("chi>65 & eng>90---->"+(chi>65 & eng>90));
作法為:判斷chi>65為true=>1 eng>90為false=>0 1&0=>false
 
|(OR=>加):
5=>00000101
2=>00000010
=>00000111 =>10進位的7
 
^(XOR) :
7=>00000111
5=>00000101
=>00000010=>10進位的2
 
~(補數):正整數和負整數相對應到相同位置的值,
如:正整數開始為0對應到負整數開始為-1
Ex:
//outputs 整數5是第6個位置,去找負整數第6個位置就是-6
System.out.println(~5);
//outputs負整數-5是第5個位置,去找數第5個位置就是4
System.out.println(~(-5));
 
2.位移 :>>(向右移2位)、<<(向左移2位)
Ex:
System.out.println(5>>2); //outputs 1
5=>00000101 右移兩位=>000001,前面補0=>00000001=>10進位的1
System.out.println(5<<2); //outputs 20
5=>00000101 左移兩位=>000101,後面補0=>00010100=>10進位的20
 
●流程圖
代表開始/結束
代表一般的步驟;輸出(計算式,定義變數…)
代表輸入;鍵盤
 
流程圖範例
X:int; =>代表變數x的reference為int
ex:
class ex3{
     public static void main(String args[]){
          java.util.Scanner sc=new java.util.Scanner(System.in);
          System.out.println("請輸入一個數字");
          int x;
          x=sc.nextInt();
          System.out.println("您輸入的是:"+x);
     }
}
 
Java前一定要有功能文件
java.util.Scanner sc =>sc為變數,變數前即為reference(功能文件)
Scanner只能在dos下輸入資料
x=sc.nextInt(); =>nextInt()只能輸入整數,把key進去的值放入x
“.”代表把nextInt()從java.util.Scanner sc call出來
 
實作:尺25元,筆39元
流程圖
java.util.Scanner sc=new java.util.Scanner(System.in);
System.out.println("請輸入尺的數量");
int x;
x=sc.nextInt();
System.out.println("請輸入筆的數量");
int y;
y=sc.nextInt();
System.out.println("一共是"+(25*x+39*y)+"元");
 
在int y;前面可以再new一次java.util.Scanner作出第二個物件sc2
java.util.Scanner sc2=new java.util.Scanner(System.in);
 
在這邊這兩個做法都是可以的,一個是同一物件執行兩次,
一個是兩個物件各執行一次
 
流程控制 =>條件判斷(true/false)
1.if(單選)
圖示法:代表圖為菱形,右邊的點代表 true(blue),左邊和下面的點代表false(orange)
(1)單一條件,單一選項
     語法:
     If(條件) 符合動作;
Ex: java.util.Scanner sc=new java.util.Scanner(System.in);
int chi=sc.nextInt();
if(chi>=60) System.out.println("及格");
*注意當只有一行的時候才可以省略{},如果有兩行以上敘述不可省略
 
(2) 單一條件,兩個選項
語法:
If(條件){ 符合……}else{不符合…..}
 
ex:
java.util.Scanner sc=new java.util.Scanner(System.in);
int chi=sc.nextInt();
if(chi>=60) {
System.out.println("及格");
System.out.println("恭喜");
}
else{
System.out.println("不及格");
System.out.println("加油");
}
 
(3)多個條件,單一選項
語法:
If(條件1){符合1…..}
  else if(條件2) {符合2…..}
  else if(條件3) {符合3…..}
  ….
  else{ 皆不符合}
 
Ex:
java.util.Scanner sc=new java.util.Scanner(System.in);
int chi=sc.nextInt();
if(chi>=91 && chi<=100){
     System.out.println("A");
}else if(chi>=76 && chi <=90){
     if(chi>=82){
          System.out.println("B+");
     }else{
          System.out.println("B-");
}
}else if(chi>=60 && chi <=75){
     System.out.println("C");
}else if(chi>=0 && chi <=59){
     System.out.println("D");
}else{
     System.out.println("0~100");
}
=>由分數高的往下做
 
(4) 三元運算子=>與if…else….一樣
語法 :條件? 符合(true): 不符合(false)
=>兩者都必須產生”值”,不能出現一個計算式或變數
=>?的用法和if一樣
=>通常三元運算會在程式只run一行且功能一樣或同樣為計算式時
Ex:
java.util.Scanner sc=new java.util.Scanner(System.in);
int chi=sc.nextInt();
System.out.println(chi>=60? "ok":"no");
 
 
(5) switch=>可單選/複選(資料類型和變數類型需要一致)
語法:
Switch(變數){
case 值1:
變數之值為1的動作
[break;]
case 值2:
變數之值為2的動作
[break;]
case 值3:
變數之值為3的動作
[break;]
…..
default:
皆不符合
}
=>調整break的位置,可以做成複選
(ex:case 2不放break,case3才放break,當符合case2會一直執行到case3)
=>break只能在switch和loop中使用
=>變數的限定
1.整數:byte,short,int
2.字元:char
3.字串:String
Ex:
 
java.util.Scanner sc=new java.util.Scanner(System.in);
System.out.println("會員等級:\n1)VIP\n2)金卡\n3)銀卡\n4)普通");
int member=sc.nextInt();
switch(member)
{
    case 1:
    System.out.println("VIP");
break;
case 2:
System.out.println("金卡");
break;
case 3:
System.out.println("銀卡");
break;
case 4:
System.out.println("普通");
break;
default:
System.out.println("1~4");
}
 
 
 
 
 
 
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

java跨平台
   Java 程式compilier後產生的*.class必須透過各個不同版本的jre
    才能跨平台與不同電腦溝通
   *.class=>jre=> mac os/windows/linux…
 
●所有純物件導向程式都會以class開頭
 
關於進位與位元
  
    因為是64位元電腦,10進位的0,在機器語言就是640
   8進位就會是201的組合
   16進會就會是401的組合
    依此類推
 
錯誤訊息說明
  看第一個error
  因為java開頭會有三種: class、interface、enum(小寫),用來定義功能
  出現下列錯誤訊息就是開頭定義功能有錯 
  
  ex1.java:5表示在第五行,^指出錯誤的地方,通常代表有字拼錯
    
 
Data type 資料類型前述
   1.=>功能
   2.文字/數字(可以加減乘除),不論變數或值,只要被” “框住全部都當作字串
   3.+的用法:
   數字+數字=數字中的加法
   文字+文字=兩個字串合併為一個字串
   文字+數字會把數字當作文字,變成一個字串
   System.out.println("10+20="+10+20);   //10+20=10+20
    在此,先判斷”10+20=”+10=>為文字+數字變字串
    再判斷”10+20=”+10為文字+20(數字)=>變字串
    compilier時,先確定  Call by reference(data type/java 的來源文件-jdk)
    compilier時,Call by values 後確定
    System.out.println("10+20="+(10+20));//10+20=30
    如果要用加法,先用括號括起來
 
Data type 基本類型
   數字:
   整數:long,int,short,byte
 (差別只在於位元大小)(byte:正整數0~127,負整數:-1~-128 )
  *整數會去小數:以下列為例,
     判斷時會先判斷10(int)/3(int)的結果是取用int
    所以要取整數去小數
   System.out.println(10/3); //outputs 3
   System.out.println(1/3); //outputs 0
     轉型為浮點數的方法,加上小數點,預設轉為double
  System.out.println(10/3.);
   浮點數:double,float,
   位階大小由大到小double>float>long>int>short>byte 
  (浮點和整數的大小不是用記憶體大小來看,
   因為浮點數是用計概的精準數換算的)
  
   字元:char只能有一個字元,並且用單引號框住,如果輸入數字,
  會自動對應到ASCII表去查找對應的字元
   char x='a'; //outputs a
   char x3=97; //outputs a
  
   布林:Boolean只有truefalse,在c就是1或0
   boolean x4=true;
 
*非基本類型因為有函式庫=>字串String:要加””
 
*當有兩個以上不同位階的數字混和運算時會取最大位階來運算,
  int x5=10+10+1.2 ;// error因為1.2變成double
  int x6=10+10+1.2f ;// error因為1.2f變成float
  int x7=(int)(10+10+1.2); //ok 因為右邊轉整數
  int x8=(int)(10+10+1.2f); //ok因為右邊轉整數
  long x9=(int)(10+10+1.2f); //ok因為右邊轉int 位階比long
  long x10=10+10+(int)(1.2f); //ok
 
變數 identify
   語法:DataType 變數=初始值(只有網頁語言不需要給datatype)
   變數在定義時,會先決定等號右邊的資料類型是否一致,
  且右邊位階不能比左邊大,最後才看值去計算
 
變數的定義錯誤
    x=20;
  
   因為當call by reference時,比對x java來源文件中有沒有資料(沒有給定datatype)
   因為沒有,所以顯示cannot find symbol
 
變數的 初始值:
   int x;
   System.out.println(x);
    錯誤訊息顯示x沒有初始值,在java中如果變數沒有給值,是無法使用的,
    連compilier都會有問題
    但如果只是int x;沒有使用這個變數,compilier是可以過的
  
 
變數的命名規則(先給初始值並定義資料類型)
   1.有大小寫的區分
   2.有功能的單字不能用來命名ex:class
   3.可搭配數字,但數字不能放在第一位
   4.可用的符號只有$_,其他符號不可用
   5.可用萬國碼unicode
 ex:int國文=98; System.out.println(國文-20); //outputs 78
 
c訂的規則
   輸入數字時,預設為int,但此時byte x=128; byte只到127所以出現錯誤訊息
   因為在compilier時,如果整數的設定類型不是int會自動由int轉換為所設定類型
 
 
數字位階大小晉升與轉型
       整數
   1.promotion=>晉升(變數)
   a)byte,short,(int因為記憶體空間夠大沒有這個問題)
      byte x=10;
      byte y=20;
      byte z=10+20;
      =>沒有問題,因為右邊為兩個值相加後的值小於127
      byte z2=x+y;
      =>有問題,因為這邊xy變數都是byte此時他不會管它實際上的數字,
          直接當作是 byte x + byte y
     (因為call by reference,他先看作是兩個byte相加)
          兩者相加是有可能超過127(假設兩者=127的話),會有問題,
          這時就會自動提升 x+y變成int且可能超過127
           所以會出現無法把int轉換為byte的問題
     
 
  2.casting轉型
  如上述問題,解決辦法有兩個
   a)int byte z2=x+y;直接升級為int但因為int32位元所占記憶體空間較大,
     如果不要占太多記憶體就不能用此方法
   b)轉型:byte z2=(byte)(x+y);x+yint轉為byte
    若是short則可以改為short z2=(short)(x+y);short z2=(byte)(x+y);
    轉型時,右邊可以轉為同等級會比較小(站記憶體空間比較小)的等級
 
浮點
  a)float
     10=>int
     10.0=>double,浮點數預設為double
     b)轉型:
     float x=10;
     //float y=10.0; =>因為.0double會有問題
     *double轉變為float的作法有三種
     float y2=(float)10.0;
     float y3=10.0f;
     float y4=10.0F;
 
跳脫字元(只有在字串時使用)
   \” \’ 可以正確顯示為一個字符
   \n:換行
   \t:跳格(一次空大約四個空格)
 
正規表示法regular expression(所有語言通用)=>之後教api一起提
 
 
 
文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()

開始前先簡單地分享一下為什麼想寫筆記:

2017年在親友的鼓勵與支持下,

報名了勞動力發展署委外辦的智慧APP設計與行銷課程,

因為要面試與口試,所以很認真的準備了,畢竟自己是門外漢不是本科生,

又實在很喜歡很想要更有系統的學習寫程式,真的很擔心最後沒有上。

過程不多說,總之很幸運的成為這個課程的學員。

雖然上課前在網路上看到有人對這類課程的評價不高,

但實際上完課還是覺得受益匪淺。

所以想把自己的筆記分享出來,跟有興趣的朋友們一起學習討論。

 


 
(一) java環境工具:
 
1.JDK/JRE=>因為JDK無法打字,所以要先用Notepad++打字
2.Notepad++
3.測試=>DOS(cmd)
=>實務上會用netbeams(官網開發工具)或是eclipse(android),其他還有很多
 
(二)撰寫java步驟
 
1.原始碼(英文+代碼/source code):即自然語言,存檔時要加上.java(*.java)
  =>如果加了.java執行時還是不行,可以檢查副檔名是否被隱藏了
2.compiler編譯器(在dos環境):
=>javac *.java(把java都去compiler) =>可run的話,可確認jdk安裝成功
=>可以檢查語法,並同時產生機器碼/byle code(*.class)   
3.測試(抓bug):執行
=>java * (這邊不需要加副檔名,會自動抓上面產生的*.class)
=>這同時可確認jre可執行
 
(三)dos執行外部指令設定(只有在微軟的dos中要這樣做)
 
輸入javac ex1.java 會出現不是內部或外部指令,因為外部指令要指定路徑
1.javac和java這兩個指令的路徑在
C:\Program Files\Java\jdk1.8.0_141\bin下(看安裝在哪個位置)
2.電腦=>右鍵=>內容=>進階系統設定=>環境變數=>新增
名稱:path
值:貼上上述路徑,但如果已有路徑要先加上";"再貼上,不然其他程式可能會出問題
(如果加在上方會限定使用帳號,如果加在下方就不限定使用者)
3.關閉dos重開,再key一次 javac ex1.java
 
 
(四)dos用到指令(大小寫皆可)
 
1.查詢(清單):dir/w
=>查詢(詳細資料):dir
2.回上一層:cd..
3.回最上層:cd\
4.查詢所訂路徑資料夾:cd 資料夾\資料夾
5.清除畫面:cls
6.切換磁區:d:
7.指令的歷史紀錄:上下鍵
8.強迫中止執行:ctrl+c (所有介面都一樣)
 
(五)notepad++設定
 
1.因為使用dos,不認識utf編碼,所在使用時編碼要用ansi,否在註解在compiler時會出現亂碼,但只有dos環境需要這樣,在netbeam和eclips
=>設定:使用者自訂=>開新文件,編碼改為ansi
2.可增加設定字詞自動完成功能,如下圖
 
*安裝 java se (oracle=>trails and download=>middleware,這邊會放所有相關資源軟體)
=>安裝好會有jdk和jre的資料夾
 
* win7一般安裝軟體如果是32位元會放在programfiles x86,如果是64位元會放在 programfiles下
 
*如果再mac os 要使用terminal文字模式
 
 
 
 
 
 
 

 

文章標籤

muchone 發表在 痞客邦 留言(0) 人氣()