JAVA程式語法_物件導向Part1_資料欄位屬性_屬性封裝(get/set)_override方法_overloading方法



JAVA物件導向

一個  車子物件

我們可能會定義如下屬性

make    : 廠牌 (英文用語)
model   : 車款 (英文用語)
Miles    : 哩程數
Year     : 出廠年


UML (Unified Modeling Language)



建構子 / get..set...

Car 類別
程式有時候很長是因為  getXXX  , setXXX 這兩個公開接口方法一直出現的關係
這類型程式設計寫法有點類似
C#中的  get set 存取器觀念
防止外面的一些語法操作
對我們的class內部做些 不正當操作
對內部宣告變數進行封裝不讓外部直接進行存取
若getXXX ,setXXX成對出現則代表前人當時設計時主要認為該變數應該可讀可寫
則說明外部有些地方正在被調用使用中
若只有 getXXX  method 的時候  則代表供唯讀而已
當有需要擴充時候才去擴充 setXXX

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

/**
 *
 * @author chous
 */
public class Car {
    private String _make;
    private String _model;
    private int _year;
    private double _miles;
    /**
     * A new Car with No Parameters
     */
    public Car()
    {
        
    }
    /**
     * A new Car with Parameters
     * @param make the make
     * @param model the model
     * @param year the year
     * @param miles the miles
     */
    public Car(String make,String model,double miles,int year)
    {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
    }
    
    public String getMake(){
        return this._make;
    }
    public void setMake(String value){
        this._make = value;
    }
    public String getModel(){
        return this._model;
    }
    public void setModel(String value){
        this._model = value;
    }
    public double getMiles(){
        return this._miles;
    }
    public void setMiles(double value){
        this._miles = value;
    }
    public int getYear(){
        return this._year;
    }
    public void setYear(int value){
        this._year = value;
    }
    
}






主程式


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

import java.util.Scanner;

/**
 *
 * @author chous
 */
public class Driver {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("We're creating a new car:");
        Scanner in = new Scanner(System.in);
        
        Car userCar = new Car();
        
        System.out.println("What is the make of the car?");
        userCar.setMake(in.nextLine()) ;
        
        System.out.println("What is the model of the car?");
        userCar.setModel(in.nextLine()) ;
        
        System.out.println("What is the miles of the car?");
        userCar.setMiles(Double.parseDouble(in.nextLine()) ) ;
        
        System.out.println("What is the year of the car?");
        userCar.setYear(Integer.parseInt(in.nextLine())) ;
        
        //using Object as our base --> toString();
        //System.out.println(userCar);
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar.getMake()
                        ,userCar.getModel()
                        ,userCar.getMiles()
                        ,userCar.getYear());
        
        Car userCar2 = new Car("NISSAN","TIDA", 3244.5 ,2013);
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar2.getMake()
                        ,userCar2.getModel()
                        ,userCar2.getMiles()
                        ,userCar2.getYear());
    }
}

輸出之測試結果
可自行輸入
也可於建構子多載後續有參數去做設數值


在介紹完兩種OO的參數賦予數值  以及  輸出打印之後

你可能會想覺得這樣子的指派各個數值去進行呈現的模式有點麻煩
所以想直接針對整個物件實體做內容輸出

因此而嘗試了直接指派 物件給 print
這麼輸出會有捨麼效果


這裡我們可以看到在使用第一種一個一個輸入帶入數值
輸出之後 會產生一串奇怪類似亂碼的結果
你可能會問為捨麼會輸出這種亂碼

System.out 的 println()之相關打印方法
如果直接給它一個物件作為參數,預設則會自動呼叫該物件的 toString()方法

其實主要是因為  來自於 繼承到的 Bas類別 Object 當中  toString  預設回傳物件之格式
官方網站檔案
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#toString()

(PS: Object 類別是 Java 程式中所有類別的父類別,
JAVA中所有物件都隱含的擴充了 java.lang.Object 類別)

Object 中定義了許多個方法
像是:
公開的(public)
equals()、toString() 、 hashCode() 、 getClass() 、 wait() 、 notify() 、notifyAll()
這些在一些開發上有些時機可以讓開發者去進行覆寫進行功能擴充


所以原因在於我們未去implement  toString的方法
所以它預設回傳一組唯一的hash code給我們,藉此我們可以去透過override去改寫此方法。


在現行你我所創建出來的這個 Car物件當中
表面上看似未有任何繼承的細節
其實它已經有預先直接繼承 JAVA  Object Class 的血統


在 NetBeans IDE 中  開發者可使用 CTRL 按鍵  按著不放去點選特定
結構 類別查看一些關聯


Override (覆寫)


你可以想做去覆蓋之前的結構、 去重新改寫某一個舊有的一段程式(方法...)
來自於繼承的父類或是基底類(Base Class)

What we need to do is be able to supersede our base class methods


如何去override 官方網站上原先繼承自Object Base類中的toString方法呢??

Step1.複製官方網站上的這個語句

貼至 Car類別之中 ,
並附上該有對應意義之Annotation(註釋文)->通常可以用來描述該方法是有捨麼含意用途




你也可以用 /** Enter
去寫一些 Method Signature  --> parameter 定義註解

PS:一個完整的 Method Signature會包含
1.Return Type
2.Name of the method
3.Number of Parameters / Type of Parameters in order



那回去我們的Driver主程式區域看一下這樣做的好處(節省Code)

那我們不想要每次一有一個 Car 物件  new 出來然後要輸出打印裡面對應特性資訊
就一直寫這一段  ㄌㄡˋㄌㄡˋㄉㄥˊ~~  的程式碼

所以就包在這裡做




經過改寫後  未來我們就只需要call此方法獲得回傳之String結果
就能節省打一長串printf的內容

捨麼意思???
在改造之前的主程式寫法

改造之前的程式碼  : 
要寫很多重複 難維護, 容易寫錯對應實體屬性打印


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

import java.util.Scanner;

/**
 *
 * @author chous
 */
public class Driver {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        Car userCar1 = new Car("Toyota","vios",3452.8,2010);
        Car userCar2 = new Car("NISSAN","TIDA", 3244.5 ,2013);
        Car userCar3 = new Car("Toyota","Yaris", 3244.5 ,2012);
        Car userCar4 = new Car("honda","CITY", 3242.5 ,2015);
        Car userCar5 = new Car("honda","HR-V", 3248.5 ,2015);
        //using Object as our base --> toString();
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar1.getMake()
                        ,userCar1.getModel()
                        ,userCar1.getMiles()
                        ,userCar1.getYear());
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar2.getMake()
                        ,userCar2.getModel()
                        ,userCar2.getMiles()
                        ,userCar2.getYear());
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar3.getMake()
                        ,userCar3.getModel()
                        ,userCar3.getMiles()
                        ,userCar3.getYear());
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar4.getMake()
                        ,userCar4.getModel()
                        ,userCar4.getMiles()
                        ,userCar4.getYear());
        System.out.printf("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\n"
                        ,userCar5.getMake()
                        ,userCar5.getModel()
                        ,userCar5.getMiles()
                        ,userCar5.getYear());
        
        
    }
}




改造之後(Override了toString方法)優化寫法
只需要一行就能獲得所有屬性資訊且格式都只需定義一次


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

import java.util.Scanner;

/**
 *
 * @author chous
 */
public class Driver {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        
        Car userCar1 = new Car("Toyota","vios",3452.8,2010);
        System.out.println(userCar1);
        Car userCar2 = new Car("NISSAN","TIDA", 3244.5 ,2013);
        System.out.println(userCar2);
        Car userCar3 = new Car("Toyota","Yaris", 3244.5 ,2012);
        System.out.println(userCar3);
        Car userCar4 = new Car("honda","CITY", 3242.5 ,2015);
        System.out.println(userCar4);
        Car userCar5 = new Car("honda","HR-V", 3248.5 ,2015);
        System.out.println(userCar5);

    }
}



有沒有感覺到  Override的強大力量




講到 Override(覆寫)  一定會有人把它跟  overloading搞混

那  overloading (多載)  又是捨麼???

Overloading(多載)


overloading  從外觀表面語法

就是相同method名稱
但有不同參數 不同回傳型態的多重定義

可能同樣一種方法是  加總的叫做 Sum
可是又可能分成回傳型態不同 , 傳入參數可能針對兩個或三個甚至多個加總的差異
int Sum(int num1,int num2)
int Sum(int num1,int num2,int num3)
double Sum(double num1,double num2)
double Sum(double num1,double num2)


以剛剛我們建立的Car  建構子來看


一個車子我們還會想看他的時速(speed per hour)
甚至希望能去修改車子之加速(我們會去採油門改增加的速度)

增加油門改加速機制的相關方法及屬性、屬性相應存取方法
建構子擴充定義



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

/**
 *
 * @author chous
 */
public class Car {

    private String _make;
    private String _model;
    private int _year;
    private double _miles;
    private double _speed;

    /**
     * A new Car with No Parameters
     */
    public Car() {

    }
    public Car(String make, String model, double miles, int year) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = 0;
    }
    /**
     * A new Car with Parameters
     * @param make the make
     * @param model the model
     * @param year the year
     * @param miles the miles
     * @param speed the speed per hour
     */
    public Car(String make, String model, double miles, int year,double speed) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = speed;
    }

    public String getMake() {
        return this._make;
    }

    public void setMake(String value) {
        this._make = value;
    }

    public String getModel() {
        return this._model;
    }

    public void setModel(String value) {
        this._model = value;
    }

    public double getMiles() {
        return this._miles;
    }

    public void setMiles(double value) {
        this._miles = value;
    }

    public int getYear() {
        return this._year;
    }

    public void setYear(int value) {
        this._year = value;
    }
    
    public double getSpeed() {
        return this._speed;
    }

    public void setSpeed(double value) {
        this._speed = value;
    }

    /**
     * Overrides Base toString() on Object.
     *
     * @return the string representation of the object.
     */
    @Override
    public String toString() {
        return String.format("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\t"
                    + "Speed: %.2f Miles Per Hour\n"
                ,this.getMake()
                ,this.getModel()
                ,this.getMiles()
                ,this.getYear()
                ,this.getSpeed());
    }
    /**
     * default Increment by 10
     * @return 
     */
    public boolean accellerate()
    {
        _speed += 10;
        return true;
    }
    /**
     * 
     * @param numMPH Miles per hour
     * @return 
     */
    public boolean accellerate(int numMPH)
    {
        _speed += numMPH;
        return true;
    }
    public double accellerateGetSpeed()
    {
        _speed += 10;
        return this.getSpeed();
    }
    public double accellerateGetSpeed(int numMPH)
    {
        _speed += numMPH;
        return this.getSpeed();
    }
}


建構子  多載  
--> 
車子空車位
有車子停進來未發動
有車子停進來已發動(有初速)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    public Car() {

    }
    public Car(String make, String model, double miles, int year) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = 0;
    }
    /**
     * A new Car with Parameters
     * @param make the make
     * @param model the model
     * @param year the year
     * @param miles the miles
     * @param speed the speed per hour
     */
    public Car(String make, String model, double miles, int year,double speed) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = speed;
    }



返回數值型態Boolean 之 是否已加速方法 多載

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
     * default Increment by 10
     * @return 
     */
    public boolean accellerate()
    {
        _speed += 10;
        return true;
    }
    /**
     * 
     * @param numMPH Miles per hour
     * @return 
     */
    public boolean accellerate(int numMPH)
    {
        _speed += numMPH;
        return true;
    }

預設加速區段  設置為 10

那又多增設  擴充給我們自己設置加速區間的 overloading方法
可以讓我們多填充參數設置自己想要油門踩加速度為多少

調用  userCar1.accellerate(35);
速度累加上去後結果




返回數值型態double 
獲取再加速某速之後去度區段方法 多載


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    public double accellerateGetSpeed()
    {
        _speed += 10;
        return this.getSpeed();
    }
    public double accellerateGetSpeed(int numMPH)
    {
        _speed += numMPH;
        return this.getSpeed();
    }






現行Code

主程式部分

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

import java.util.Scanner;

/**
 *
 * @author chous
 */
public class Driver {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Car userCar1 = new Car("Toyota","vios",3452.8,2010);
        System.out.println("一台車剛初始化未發動狀態特性:");
        System.out.println(userCar1);
        System.out.println("一台車發動後調成空檔預設加速往前速度特性:");
        userCar1.accellerate();
        System.out.println(userCar1);
        System.out.println("一台車發動後調成空檔後又踩了油門加速了35m速度特性:");
        userCar1.accellerate(35);
        System.out.println(userCar1);
        System.out.println("第二台車剛發動且以15mph初速出發");
        Car userCar2 = new Car("NISSAN","TIDA", 3244.5 ,2013,15);
        System.out.println(userCar2);
        boolean isSuccess = userCar2.accellerate();// default + 10
        System.out.println("是否已經成功發動:" + isSuccess + "  當前車速為:"+userCar2.getSpeed());
        double currentSpeedOfCar2 = userCar2.accellerateGetSpeed(20);
        System.out.println("再多加速20mph之後的車速:"+currentSpeedOfCar2);
        
//        Car userCar2 = new Car("NISSAN","TIDA", 3244.5 ,2013);
//        System.out.println(userCar2);
//        Car userCar3 = new Car("Toyota","Yaris", 3244.5 ,2012,45);
//        System.out.println(userCar3);
//        Car userCar4 = new Car("honda","CITY", 3242.5 ,2015,50);
//        System.out.println(userCar4);
        

    }
}


Car類別 部分

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package objectclasses;

/**
 *
 * @author chous
 */
public class Car {

    private String _make;
    private String _model;
    private int _year;
    private double _miles;
    private double _speed;

    /**
     * A new Car with No Parameters
     */
    public Car() {

    }
    public Car(String make, String model, double miles, int year) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = 0;
    }
    /**
     * A new Car with Parameters
     * @param make the make
     * @param model the model
     * @param year the year
     * @param miles the miles
     * @param speed the speed per hour
     */
    public Car(String make, String model, double miles, int year,double speed) {
        this._make = make;
        this._model = model;
        this._miles = miles;
        this._year = year;
        this._speed = speed;
    }

    public String getMake() {
        return this._make;
    }

    public void setMake(String value) {
        this._make = value;
    }

    public String getModel() {
        return this._model;
    }

    public void setModel(String value) {
        this._model = value;
    }

    public double getMiles() {
        return this._miles;
    }

    public void setMiles(double value) {
        this._miles = value;
    }

    public int getYear() {
        return this._year;
    }

    public void setYear(int value) {
        this._year = value;
    }
    
    public double getSpeed() {
        return this._speed;
    }

    public void setSpeed(double value) {
        this._speed = value;
    }

    /**
     * Overrides Base toString() on Object.
     *
     * @return the string representation of the object.
     */
    @Override
    public String toString() {
        return String.format("Make: %s\tModel: %s\tMiles: %.1f\tYear: %d\t"
                    + "Speed: %.2f Miles Per Hour\n"
                ,this.getMake()
                ,this.getModel()
                ,this.getMiles()
                ,this.getYear()
                ,this.getSpeed());
    }
    /**
     * default Increment by 10
     * @return 
     */
    public boolean accellerate()
    {
        _speed += 10;
        return true;
    }
    /**
     * 
     * @param numMPH Miles per hour
     * @return 
     */
    public boolean accellerate(int numMPH)
    {
        _speed += numMPH;
        return true;
    }
    
    public double accellerateGetSpeed()
    {
        _speed += 10;
        return this.getSpeed();
    }
    public double accellerateGetSpeed(int numMPH)
    {
        _speed += numMPH;
        return this.getSpeed();
    }
}





留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題