Object Oriented Programming

What is Object Oriented Programming

Object Oriented Programming (OOP) is a software development methodology that models real-world objects and builds software based on how these objects interact with each other.

In OOP, objects in software are made up of data properties and methods that operate on that data. These objects can be seen as entities within the software, and they work together to accomplish specific tasks. For example, a bank account object might have properties such as balance and account number, and methods such as deposit and withdraw.

The fundamental concepts of OOP are “classes” and “objects”. Classes describe the blueprint or template for objects, and objects are instances created from these classes. In OOP, objects can be made more flexible through concepts such as inheritance and polymorphism, making the code more organized, reusable, and easier to maintain.

OOP provides a way to break down complex programs into smaller, more manageable parts. By breaking a program into classes and objects, we can create code that is easier to understand, modify, and maintain. Additionally, OOP can increase the reusability of software, as developers can use existing objects to develop new functionality. It is widely used in modern programming languages such as Java, Python, and Ruby, among others.

The core concepts of OOP are:

1. Object-oriented programming three features

  • Encapsulation: Encapsulation is the technique of hiding the internal details of an object and only exposing the public interface. It groups related properties and methods into a class, and separates them from other classes’ properties and methods. Encapsulation prevents external code from accessing and modifying an object’s properties and methods improperly, improving code security and reliability.

  • Inheritance: Inheritance is the mechanism that enables a new object to acquire properties and methods from an existing object. It promotes code reuse and structuring. Inheritance allows the programmer to create new code based on existing code, saving development time and improving code reusability.

  • Polymorphism: Polymorphism refers to the ability of objects to take on multiple forms, where the same operation can behave differently on different objects. Polymorphism allows for flexibility and extensibility, improving code readability, maintainability, and reusability. Polymorphism can be achieved through method overloading, method overriding, and interfaces.

2. Object-oriented programming two abstractions:

  • Abstract: an abstract class cannot be directly instantiated, but can be inherited, and can contain both abstract and implemented methods.

  • Interface: a definition of a set of methods that a class must implement to fulfill the contract.

Abstraction: Abstraction is the process of representing complex real-world objects as simpler classes or interfaces, which hides the implementation details and only exposes the object’s functionality and properties. By abstracting objects, the programmer can simplify the system’s complexity, making it easier to understand and manage.

3. Good object-oriented programming principles: SOLID

  • S (Single Responsibility Principle): a class should have only one function.
  • O (Open/Closed Principle): software entities should be open for extension but closed for modification.
  • L (Liskov Substitution Principle): objects of a superclass shall be replaceable with objects of its subclasses.
  • I (Interface Segregation Principle): a client should not be forced to depend on methods it does not use.
  • D (Dependency Inversion Principle): high-level modules should not depend on low-level modules, both should depend on abstractions.

These concepts are interrelated and are usually used together to implement complex code. OOP can help programmers write code that is easy to understand, reuse, and maintain, while improving the quality and productivity of the code.

什麼是物件導向設計(Object Oriented Programming)

Object Oriented Programming (OOP) 是一種軟體開發的方法,它將現實世界中的物件模型化,以物件之間的互動方式來建立軟體。

在 OOP 中,軟體中的物件由資料屬性和操作資料的方法所構成。這些物件可以被看做軟體中的實體,它們能夠合作來完成特定的任務。例如,一個銀行帳戶物件可以有屬性如餘額、帳戶號碼等,而方法則可以是存款、提款等。

OOP 的基本概念是「類別」和「物件」。類別是用來描述物件的藍圖或模板,而物件是透過這些類別來建立的實體。在 OOP 中,物件能夠透過繼承和多型等概念來增加彈性,讓程式碼更有組織性、可重複使用性和易於維護性。

OOP 提供了一種將複雜程式拆解成更小、更易管理的部分的方式。透過將程式拆解成類別和物件,我們可以創建出更容易理解、修改和維護的程式碼。此外,物件導向程式設計也可以增加軟體的可重用性,因為開發者可以使用現有的物件來開發新的功能。它廣泛地應用於現代程式語言,如 Java、Python 和 Ruby 等。

OOP的核心概念包括:

1. 物件導向三特性:

  • Encapsulation(封裝):封裝是一種隱藏物件細節的技術。它將相關的屬性和方法組合起來形成一個類別,同時將其與其他類別的屬性和方法分開。封裝可以防止外部代碼不當地訪問和修改物件的屬性和方法,從而提高代碼的安全性和可靠性。

  • Inheritance(繼承):繼承是指一個物件可以獲得另一個物件的屬性和方法,從而可以重複利用代碼並實現代碼的結構化。透過繼承,程式設計師可以建立基於現有代碼的新代碼,從而節省開發時間並提高代碼的可重複利用性。

  • Polymorphism(多態性):多態性是指相同的操作可以作用於不同的物件上,產生不同的行為。它可以實現代碼的靈活性和擴展性,從而提高代碼的可讀性、可維護性和可重用性。多態性是OOP中最重要的概念之一,它可以通過方法重載、方法重寫和介面實現。

透過這些核心概念的運用,程式設計師可以寫出易讀、易維護、可重複利用、彈性及可擴充的程式。

2. 物件導向兩抽象 (Abstraction)

  • Abstract:抽象類別是不能直接實例化的類別,只能被繼承,且可以包含抽象方法和實作方法。
  • Interface:介面是一個定義了一系列方法的抽象型別,實現這個介面的類別必須實現所有定義的方法。

抽象化是將具體事物抽象成一個類別或介面,使程式設計師可以隱藏實現細節,只關注物件的功能和特性。透過抽象化,程式設計師可以簡化系統的複雜性,使其易於理解和管理。

3. 好的物件導向原則:SOLID

  • S (Single Responsibility Principle):單一職責原則,一個類別只負責一個職責。
  • O (Open/Closed Principle):開放封閉原則,對擴展開放,對修改封閉。
  • L (Liskov Substitution Principle):里氏替換原則,衍生類別必須能夠替換基類別。
  • I (Interface Segregation Principle):介面隔離原則,介面應該是客戶端所需要的最小介面。
  • D (Dependency Inversion Principle):依賴反轉原則,高層模組不應該依賴低層模組,而是依賴抽象介面。

Example 1

下面是一個簡單的例子,展示如何使用 Ruby 的物件導向程式設計來建立一個簡單的人物件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Person
  attr_accessor :name, :age

  def say_hello
    puts "Hello, my name is #{@name} and I'm #{@age} years old."
  end
end

# Create a new Person object
my_person = Person.new
# Set the name and age attributes
my_person.name = "Alice"
my_person.age = 30
my_person.say_hello #"Hello, my name is Alice and I'm 30 years old."

In this example, the Person class defines two attributes using the attr_accessor method: name and age. This automatically creates getter and setter methods for the attributes, so we can set their values using person.name = “Alice” and person.age = 30.

The say_hello method uses the name and age attributes to output a message introducing the person. We can call this method on the Person object by using person.say_hello.

Using attr_accessor instead of an initialize method can simplify the code for simple cases like this where we just need to define a few attributes for an object.

這個程式碼定義了一個 Person 類別,該類別具有 name 和 age 兩個屬性以及一個 say_hello 方法。使用 attr_accessor 來定義存取器方法,用於設置和獲取實例變數。在 say_hello 方法中,會顯示一條簡單的消息,顯示人的名字和年齡。

在這個例子中,我們創建一個名為 my_person 的 Person 物件,並設置其 name 和 age 屬性,最後呼叫它的 say_hello 方法來顯示人的資訊。

使用 attr_accessor 而不是 initialize 方法可以簡化像這樣的簡單情況的代碼,我們只需要為一個對象定義一些屬性。

Example 2

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Person
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def introduce
    puts "Hi, my name is #{@name} and I'm #{@age} years old."
  end
end

person1 = Person.new("John", 30)
person2 = Person.new("Jane", 25)

person1.introduce
person2.introduce

In this example, the Person class has an initialize method that takes two parameters, name and age. These parameters are used to set the instance variables @name and @age, respectively. The attr_accessor method is used to define getter and setter methods for these instance variables.

The introduce method is used to print out a message introducing the person by name and age. Two instances of the Person class are created with the new method, and the introduce method is called on each of them to introduce them.

Example 3

 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
class Game
  def initialize
    @number = rand(1..100)
    @guesses = 0
    @game_over = false
  end

  def play
    puts "Let's play a guessing game!"
    until @game_over
      guess = get_guess
      check_guess(guess)
    end
  end

  private

  def get_guess
    puts "Enter a number between 1 and 100:"
    gets.chomp.to_i
  end

  def check_guess(guess)
    @guesses += 1
    if guess == @number
      puts "Congratulations, you guessed the number in #{@guesses} tries!"
      @game_over = true
    elsif guess < @number
      puts "Sorry, that's too low. Guess again."
    else
      puts "Sorry, that's too high. Guess again."
    end
  end
end

game = Game.new
game.play

In this example, we define a Game class to represent a guessing game. In the initialize method, we use the rand method to generate a random number between 1 and 100, and initialize some game-related variables such as the number of guesses (@guesses) and whether the game is over (@game_over).

In the play method, we use a until loop to keep getting guesses from the player until the game is over. In each guess, we call the get_guess method to get a number from the player, and then call the check_guess method to check whether the guess is correct.

In the get_guess method, we use the puts method to print a prompt message, and the gets method to get input from the player. In the check_guess method, we first increment the number of guesses, and then check whether the guess is correct. If the guess is correct, we print a congratulatory message and set @game_over to true. Otherwise, we print a message telling the player whether the guess was too high or too low.

Finally, we create a Game object and call the play method to start the game. Each time the player enters a number, the game tells the player whether the guess was correct or not.

Example 4

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Person
  attr_accessor :name, :age, :gender

  def initialize(name, age, gender)
    @name = name
    @age = age
    @gender = gender
  end

  def say_hello
    puts "Hi, my name is #{@name}. I'm #{@age} years old and #{@gender}."
  end
end

# 創建一個人物件
person1 = Person.new("David", 25, "male")

# 訪問和修改屬性
puts person1.name  # David
person1.age = 30
puts person1.age   # 30

# 呼叫方法
person1.say_hello  # Hi, my name is David. I'm 30 years old and male.

這個例子中,我們定義了一個 Person 類別,這個類別具有 name、age 和 gender 三個屬性,以及一個 say_hello 方法。在創建一個人物件時,我們需要提供姓名、年齡和性別等屬性值。我們可以通過使用 attr_accessor 簡化屬性的定義,並使用 initialize 方法來初始化屬性值。在 say_hello 方法中,我們使用實例變數 @name、@age 和 @gender 輸出人物件的屬性值。

這個例子展示了如何使用 Ruby 物件導向程式設計來建立一個簡單的人物件,並演示了如何訪問和修改物件的屬性,以及如何呼叫物件的方法。

Example 5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Dog
  def initialize(name, breed)
    @name = name
    @breed = breed
  end

  def bark
    puts "Woof! My name is #{@name} and I'm a #{@breed}."
  end
end

# 創建一個名為 Spot,品種為柴犬的狗物件
my_dog = Dog.new("Spot", "Shiba Inu")

# 使用 bark 方法讓狗叫
my_dog.bark

這個程式定義了一個 Dog 類別,該類別有一個 initialize 方法用來初始化名稱和品種的實例變數,以及一個 bark 方法,該方法會讓狗顯示它的名字和品種。程式還創建了一個 my_dog 物件實例,該物件代表一隻名為 “Spot” 的柴犬,然後使用 bark 方法讓狗叫。

Example 6

 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
class Car
  def initialize(make, model, year)
    @make = make
    @model = model
    @year = year
    @speed = 0
  end

  def speed_up(num)
    @speed += num
    puts "The car is now going #{@speed} mph."
  end

  def brake(num)
    @speed -= num
    puts "The car is now going #{@speed} mph."
  end

  def shut_off
    @speed = 0
    puts "The car is now off."
  end
end

# 創建一個名為 my_car 的 Car 物件實例
my_car = Car.new("Toyota", "Camry", 2015)

# 使用 speed_up 方法增加汽車的速度
my_car.speed_up(20)

# 再次使用 speed_up 方法增加汽車的速度
my_car.speed_up(30)

# 使用 brake 方法減少汽車的速度
my_car.brake(10)

# 使用 shut_off 方法關閉汽車
my_car.shut_off

這個程式定義了一個 Car 類別,該類別有一個 initialize 方法用來初始化汽車的屬性(品牌、型號、年份、速度),以及三個方法 speed_up、brake 和 shut_off。這些方法可以讓汽車加速、減速和關閉。程式還創建了一個 my_car 物件實例,該物件代表一輛品牌為 Toyota,型號為 Camry,年份為 2015 的汽車,然後使用 speed_up、brake 和 shut_off 方法操作該汽車的速度和狀態。

Example 7

 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
class Account
  attr_reader :balance, :name

  def initialize(name, balance = 0)
    @name = name
    @balance = balance
  end

  def deposit(amount)
    @balance += amount
  end

  def withdraw(amount)
    if amount > @balance
      puts "Error: insufficient balance."
    else
      @balance -= amount
    end
  end
end

class Bank
  def initialize
    @accounts = []
  end

  def create_account(name, balance = 0)
    @accounts << Account.new(name, balance)
  end

  def get_account(name)
    @accounts.each do |account|
      if account.name == name
        return account
      end
    end
    return nil
  end
end

my_bank = Bank.new
my_bank.create_account("Alice", 1000)
my_bank.create_account("Bob", 500)

alice_account = my_bank.get_account("Alice")
bob_account = my_bank.get_account("Bob")

puts alice_account.balance    # 輸出 1000
puts bob_account.balance      # 輸出 500

alice_account.withdraw(200)
puts alice_account.balance    # 輸出 800

bob_account.deposit(100)
puts bob_account.balance      # 輸出 600

alice_account.withdraw(1000)  # 輸出 "Error: insufficient balance."

在這個範例中,我們建立了兩個類別(Class),分別是 Account 和 Bank。Account 類別表示一個銀行帳戶物件,它有一個名字(name)和一個餘額(balance)。Bank 類別表示一個銀行系統物件,它可以創建帳戶(create_account)和查詢帳戶(get_account)。

在 Account 類別中,我們定義了三個方法,分別是 initialize、deposit 和 withdraw。initialize 方法用於初始化一個帳戶,deposit 方法用於存款,withdraw 方法用於取款。在 withdraw 方法中,我們判斷取款金額是否超過帳戶餘額,如果是,就輸出一個錯誤訊息。

在 Bank 類別中,我們定義了兩個方法,分別是 initialize、create_account 和 get_account。initialize 方法用於初始化一個銀行系統物件,create_account 方法用於創建一個帳戶,get_account 方法用於查詢一個帳戶。

接著,我們使用 new 方法創建了一個 Bank 物件,並將它儲存在 my_bank 變數中。我們可以使用 my_bank 這個變數,來創建帳戶和查詢帳

updatedupdated2023-04-262023-04-26