Oop 1
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
471
On Slideshare
471
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
3
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Object-Oriented Programming (OOP) - Part I Intro. to Computer Science (II) Dept. of Communication Engineering Instructor: Ting-Yu Lin
  • 2. Agenda• Review: parameter passing• Review: design and implement a STACK• 物件導向 (Object-Oriented) 程式設計概念• 建構元與解構元 (Constructor & Destructor)• 繼承關係 (Inheritance) 與軟體再利用• 多型概念 (Polymorphism) 或叫“同名異式” 以繼承為基礎 2
  • 3. Review: Pass-By-Value• A value parameter in a function becomes a copy of the argument that is passed in• Changing the value of a value parameter: – Does change the memory associated with the parameter – Does not change the memory associated with the argument passed in void valFunc(float val) { val = 50; This assignment changes the } memory associated with this variable (only)! int main() (mains mainVal is unaffected) { int mainVal = 9; valFunc(mainVal); mainVal: 9 cout << "mainVal: " << mainVal << endl; return (0); } 3
  • 4. Review: Pass-By-Reference• A reference parameter in a function "references" the same physical memory location as the argument passed in• Changing the value of a reference parameter: – Does change the memory associated with the argument passed in – Therefore – arguments memory must not be constant or literal void refFunc(float &val) { This assignment changes the memory val = 50; associated with this variable! } int main() { int mainVal = 9; refFunc(mainVal); mainVal: 50 cout << "mainVal: " << mainVal << endl; return (0); } 4
  • 5. Review: Encapsulation• Hide the objects nucleus from other objects in the program. – The implementation details can change at any time without affecting other parts of the program. 實做細節隱藏• It is an ideal representation of an object, but – For implementation or efficiency reasons, an object may wish to expose some of its variables or hide some of its methods.• Benefits: 存取控制 – Modularity (模組化程式設計) • The source code for an object can be written and maintained independently of the source code for other objects. – Information hiding (提供外界標準的溝通介面) • An object has a public interface that other objects can use to communicate with it. 5
  • 6. 用 array 來做 STACK (1/2)• void push (int y) { Initialization: ++sptr; x[sptr] = y; int x[99]; sptr = -1; /*empty*/ } 98 push (456) ; sptr push (3388) ;Stack Pointer int ans = pop( );int sptr; int pop ( ) { int tmp = x[sptr]; 3388 1 456 0 --sptr; -1 return tmp;需要一個array 和一個整數 } 6
  • 7. 用 array 來做 STACK (2/2) static int x[99]; /* static 使得別的檔案看不到這 */ static int sptr = -1; /* empty stack */ void push(int y) { ++sptr; /* move stack pointer */ x[sptr] = y; /* put the data y there */ } int pop( ) { return x[sptr--]; /* 注意 -- 寫後面 */ } /* 其它相關 functions 例如 isEmpty( ), isFull() */ 7 喔~ 模仿class的封裝功能 (encapsulation)
  • 8. 使用 STACKextern void push(int); /* 宣告 */extern int pop( );#include <stdio.h>int main( ) { push(543); push(881); printf( "%dn", pop( ) ); } /* 可以用! 但若要兩個 Stack 呢? */ 8
  • 9. More about STACK (1/3)/* 若要兩個 Stack 呢? */解法之一==> 使用兩個 array, 並把 array 當參數 push(ary2, x); ans = pop(ary2);但是這樣該些 array 必須 開放讓使用者知道 要讓宣告 extern就看得到, 不可再用 static Global 違反不必讓使用者知道push到哪去的 Information Hiding 原則 ! 只要看得到就可能不小心改到(或是該些 array 要定義在使用者程式裡面) 9
  • 10. More about STACK (2/3)/* 若要兩個 Stack 呢? */解法之二==> 整個檔案複製到另一個 file, 並把各相關函數名稱都改掉, 例如 push2, pop2, …==> array 與變數名稱不用改! Why? (因為 static Global)但是這樣 也不是很方便, 函數名稱一大堆 若要三個 Stack 呢? 四個呢? …(不過這比前面使用不同 array 的方法好!) Why? 因為沒違反資料隱藏原則 10
  • 11. More about STACK (3/3)/* 若要兩個 Stack 呢? *//* 若要三個 Stack 呢? 四個? 五個 . . . *//* 有沒有更方便直接的方法? */ solution ==> using C++ Class to define a Stack as a Software Component 可否讓堆疊用起來像物件? (軟體元件或零件)Stack x;Stack y;x.push(13579);y.push(258);y.push( x.pop( ) ); 11
  • 12. 宣告部份Stack -- class example (1/2) mystk.hclass Stack { // private: long data[99]; /* 直接寫 99 不是好習慣 */ int sptr; // 不能寫 int sptr = -1; public: Stack( ) ; /* constructor */ void push( long ); long pop( ); bool isEmpty( );}; /* class Stack */ bool 要新版的 C++ 才有, 如果不能用 bool 就改用 int 12
  • 13. 真正定義Stack -- class example (2/2) mystk.cpp #include "mystk.h" Initialization 工作 #include <iostream.h> 要寫在特殊函數 Stack::Stack( ) { sptr = -1; } /* constructor */ void Stack::push(long xx) { /* 注意 Stack:: */ data[ ++sptr ] = xx; } long Stack::pop( ) { return data[sptr--]; } bool Stack::isEmpty( ) { return sptr == -1; } // bool 要新版的 C++ 才有 這是實作出 Stack, 前面 mystk.h 只是宣告 13
  • 14. Stack (之使用) mymain.cpp #include "mystk.h" 注意: #include <iostream.h> #include <iostream.h> 是int main( ) { 舊的寫法; Stack xo, brandy; 新的寫法是: xo.push(880); #include <iostream> xo.push(770); 而且要寫: xo.push(53); while( !xo.isempty( ) ) { using namespace std; cout << " " << 因為 C++程式庫在 std xo.pop( ); 命名空間內 } cout << endl; return 0; } 14
  • 15. Stack (之使用) 如何執行?#include "mystk.h" g++ mymain.cpp mystk.cpp#include <iostream.h>int main( ) { ./a.out Stack xo, brandy; xo.push(880); g++ -c mystk.cpp xo.push(770); g++ mymain.cpp mystk.o xo.push(53); ./a.out while( !xo.isempty( ) ) { cout << " " << xo.pop( ); } cout << endl; return 0; 53 770 880 } 15
  • 16. Information hiding (資訊隱藏 1/3) 使用 Stack 時不必知道如何 push 如何 pop 等細節!• Stack 只能用 Array 實作嗎? 就是說不必知道 Stack 是如何實作的! ==> can be implemented by Linked List (鏈結串列) How to do it? Hint: 使用 struct/class 配合 pointer 16
  • 17. Information hiding (資訊隱藏 2/3) 使用 Stack 時不必知道如何 push 如何 pop 等細節!class Animal { // private: private 的 data 與 functions 也都不可在 long height; class 以外的 functions 中直接用! double haha; 只有 class 內宣告的 member function 才 可以直接存取 private 的 data 與 function public: Animal( ); int main( ) { float weight; Animal x; /* local variable */ void talk( ) { /***/ } /* … */ 自己try try看}; cout << sizeof(x) << endl;Animal::Animal( ) { cout << x.weight << endl; /* OK */ height = 170; haha = 38.49; cout << x.height << endl; /* error */ weight = 59.66; }} 17
  • 18. friend 關鍵字的用法 Information hiding (資訊隱藏 3/3)class Animal { 俗話說: What is the friend for? long height; double haha; 子路曰:「願車馬衣裘與朋友共, public: 敝之而無憾。」 Animal( ); float weight; int main( ) { void talk( ) { /***/ } Animal x; friend int main ( ); /* … */}; cout << sizeof(x) << endl;Animal::Animal( ) { cout << x.weight << endl; height = 170; haha = 38.49; cout << x.height << endl; /* OK now */ weight = 59.66; }} C++ Joke: Friend is the only one who can touch your private ! 18
  • 19. Information Hiding Summary3 access control clauses for class members private: clause for hidden entities public: clause for interface entities protected: clause - for inheritance (extension)friend functions - to provide access to privatemembers in some unrelated program units orfunctionsfriend functions are not member functions of class– Defined outside of class scopeif B a friend of A, A not necessarily a friend of B 你宣告我為你朋友, 並不代表我也認你 19 為朋友 (一定要我正式宣告才算)
  • 20. 認真看 class 事實上C++裡 struct 也可包含 method/function• C語言的 struct 目的是把相關資料 group 在一起• class (類別) 就是原來的 struct with some regulations• class is an extension of user-defined data type, 自訂的, 抽象的• 所以 class 是 Abstract Data Type (ADT)• ADT 就是把 data 以及對這些 data有關的動作 (method, 就是 function) 一起封藏 (Encapsulate) 在一個程式單元 (program unit) 之內, 例如 C++ 用 class 來封藏• Class 可用來設計軟體元件 (Software Component)• Class 內的 data member/method member 存取控制: – private, protected, public (C++ 與 Java 寫法不同)• Constructor? Destructor? Default Constructor? …• Java 沒有 Destructor, 但有 finalize 函數 20
  • 21. ADT --- Data Abstraction• An Abstract Data Type (ADT) is a user-defined data type that satisfies the following two conditions: (Encapsulation + Information Hiding) – The representation of, and operations on, objects of the type are defined in a single syntactic unit; also, other program units can create objects of this type. – The representation of objects of this type is hidden from the program units that use these objects, so the only operations (methods) possible are those provided in the types definition which are known as interfaces. class 裡開放為 public 的 functions 21
  • 22. ADT in C++class / struct can be used as the encapsulationdevice (只有一開始 default access 屬性不同)All of the class instances of a class share asingle copy of the member functionsEach instance of a class has its own copy ofthe class data membersclass instance of a class = object object is an instance (variable) of some class (type) 22
  • 23. OO featuresEncapsulationInformation Hiding The concept of abstraction is fundamental in programming 抽象化的概念以前 就有: 函數/副程式 Subprogram / function增加: Process abstraction Inheritance ADT Polymorphism Data abstractionSoftware Reuse 23
  • 24. Class vs. Object• Object is an instance of some class – int x; float yy;• Object (物件, 個體, 東西) -- 就是以前所謂的變數#include <iostream> #include <iostream>class Student { struct Student { long sid; long sid; char name[9]; char name[9];}; };Student x, y[99], tempstu; Student x, y[99], tempstu;int main( ) { int main( ) { x.sid = 38; // Error! x.sid = 38; // OK! cout << x.sid; // Error! cout << x.sid; // OK!} } 24
  • 25. Struct vs. Class (1/3) 重要觀念#include <iostream> 考!!class Student { // 若在此寫 public: ? long sid; // default is private for class}; // default is public for structint main( ) { Student x; x.sid = 123; // compile 錯, access not allowed cout << "== " << x.sid << endl; // compile 錯 return 0;} 若改為 struct Student 則變沒錯! Why? 25
  • 26. Struct vs. Class (2/3)#include <iostream>class Student { long sid; // default is private for class friend int main( );}; // default is public for structint main( ) { Student x; x.sid = 123; // 變對了 Why? cout << "== " << x.sid << endl; // compile OK return 0;} C++ Joke: Friend is the only one who can touch your private ! 26
  • 27. 開放 data members Struct vs. Class (3/3) 違反資料封裝原則#include <iostream> 正確概念是透過class Student { // private: member functions long sid; public: long showNumber( ) { return sid; } void setId( long xx ) { sid = xx; }};int main( ) { Student x, y; x.setId(123); // OK, 透過 public function setId( ) cout << "== " << x.showNumber( ) << endl; // OK! return 0;} 27
  • 28. Class (Object) Constructor (1/4) #include <iostream> class Student { // private: long sid; public: long showNumber( ) { return sid; } void setId( long xx ) { sid = xx; } }; 使用 default constructor int main( ) { 沒有參數 Student x, m, n; Student y(456); // Error! x.setId(123); Student y(456) ; 有問題! return 0; 因為 default constructor } 就是不能有參數 28
  • 29. Class (Object) Constructor (2/4) #include <iostream> class Student { // private: long sid; public: long showNumber( ) { return sid; } void setId(long xx) { sid = xx; } Student(long x) { sid = x; } 加入這constructor }; Student x; 有問題! int main( ) { 因為 default constructor Student x; // Error.. 不能用了 – Student y(456); // OK now! 有兩種解決方法: x.setId(123); return 0; Student y(456) ; 現在OK了 } 29
  • 30. Class (Object) Constructor (3/4) #include <iostream> class Student { // private: long sid; public: long showNumber( ) { return sid; } void setId(long x) { sid = x; } Student(long x = 0) { sid = x; } }; int main( ) { Student x, y(456); // OK! Student x; 有問題 x.setId(123); 解決方法一 使用 default 參數 return 0; } 30
  • 31. Class (Object) Constructor (4/4) #include <iostream> class Student { // private: long sid; public: long showNumber( ) { return sid; } void setId(long xx) { sid = xx; } Student(long x) { sid = x; cout << "Hehehen"; } Student( ) { sid = 0; cout << "Hahan"; } }; int main( ) { Student x, y(456); // OK! Student x; 有問題 x.setId(123); 解決方法之二 return 0; 再加一個沒參數的constructor } 31
  • 32. Summary of ConstructorConstructor 就是與 Class 同名的函數Constructor 函數沒有 type, 不可以寫 return typeConstructor 將在 object 被安排好記憶體後立即執行, 所以通常用來設定初值 (initial value)Student x; // 這樣會幫 x 安排一塊記憶體, 並執行 x.Student( );Student *p; // 這樣只有指標, 沒有生出 Student, 不會執行constructor, 要 p = new Student( ); 才會執行 constructorObject 就是 Class 的一個 instance (案例); 就是 變數 啦Constructor 可以不寫, 此時等於有一個沒參數且不做事的Default Constructor只要寫了一個 Constructor, 則原先的 Default Constructor就自動消失不能用了Constructor 也可以寫很多個, 自動依參數決定用哪個 此即 Function name overloading (函數名稱重複用) 的概念 32
  • 33. Destructor在 object 佔用之記憶體還掉之前 被瞬間執行的程式 (函式) 33
  • 34. Object Destructor dtest.cpp#include <iostream>using namespace std;class Student { // private: long sid; public: long showNumber( ) { return sid; } void setId(long xx) { sid = xx; } Student(long x) { sid = x; cout << x << " Hohohon"; } Student( ) { sid = 38; cout << "Hahan"; } ~Student( ) { cout << sid << " Arrrrh 死了n"; }}; 這是 destructorvoid test( ) { Student x; cout << " ==到此一遊== "; }Student xxx(123);int main( ) { cout << " *** 開飯了 ***n"; Student y(456); test( ); // 會跳入 test( ) , 注意會做哪些事? return 0;} 34
  • 35. 人體 compiler告訴我 output 是啥? 35
  • 36. 不要偷偷翻頁喔~~ 36
  • 37. Output of previous program dtest.cppmytest/> g++ dtest.cppmytest/> ./a.out123 Hohoho *** 開飯了***456 HohohoHaha ==到此一遊== 38 Arrrrh 死了456 Arrrrh 死了123 Arrrrh 死了mytest/> exit 37
  • 38. Constructor vs. Destructor Compiler 可以分辨的• Constructor 可以寫很多個 原則之下 – 必須符合 overloading 的規定, 依照參數決定 – 在 object 安排好記憶體之後要立刻被執行的程式• Destructor 最多只能有一個, 也可以不寫 – 不能有任何參數 – 就是與 Class 同名且左邊帶有尾巴 ( ~ ) 的函數 – 在 object 佔用之記憶體還掉之前被瞬間執行的程式• 一般函數都有 return type• Constructor 和 Destructor 都沒有 return type 連 void 都不能寫 38