Class 类别
想像一下,假如我们要做一个有关食谱和食物的程式。首先,什么是食谱呢?食谱是一个告诉我们如何做一道菜的指南,里面会写着需要的材料和做法。这就像是一个「类别」,它定义了一种事物的特性和行为。
现在,我们可以把不同的食物想像成「物件」,每一道菜都是一个物件。比如,我们有一个叫做「巧克力蛋糕」的食谱,这个食谱里面会告诉我们需要的巧克力、麵粉、鸡蛋等等。这个食谱就是我们的「类别」,里面定义了製作巧克力蛋糕的方法。
当我们根据这个食谱做出一个巧克力蛋糕时,这个巧克力蛋糕就是一个「物件」,它具体实现了食谱中的方法。我们可以做出很多不同的巧克力蛋糕,但它们都是根据同一个食谱来製作的,所以它们有相同的特性和做法。
同样地,当我们做其他的菜时,比如「水果沙拉」或「披萨」,每道菜都是一个物件,它们都有各自的特性和做法,但都是根据不同的食谱(类别)来做的。
所以,「类别」就像是一个模板或者指南,告诉我们如何创造不同的物件。这种方式让我们可以用更有组织的方式来写程式,就像是根据食谱来做不同的美食一样。希望这个比喻可以帮助你们更好地理解「类别」这个概念喔!
创建类别与实例化物件
类别(Class)是面向物件程式设计(Object-Oriented Programming,简称 OOP)中的一个重要概念。在 Python 中,你可以使用 class 关键字来定义类别,类别用于创建物件,并定义了物件的属性和方法。
以下是一个简单的类别示範:
class MyClass: x = 5# 依据类别创建物件p1 = MyClass()p1.x # 5
定义一个类别 MyClass,以及如何基于这个类别创建物件 p1,并且访问物件的属性 x。
建构函示 init() 与实例方法
以下是一个简单的类别示範:
class Dog: def __init__(self, name, age): self.name = name self.age = age def bark(self): print(self.name + "正在叫!") def describe(self): print(self.name + "的年龄是" + str(self.age) + "岁。")# 创建 Dog 类别的物件dog1 = Dog("旺财", 3)dog2 = Dog("小黑", 2)# 使用物件的方法dog1.bark() # 旺财正在叫!dog2.describe() # 小黑 的年龄是 2 岁。
在这个示範中,我们定义了一个名为 Dog 的类别,它有两个属性 name 和 age,以及两个方法 bark 和 describe。init 方法是一个特殊的方法,用于初始化物件的属性。在方法中,第一个参数 self 代表物件自身。
你可以创建多个基于这个类别的物件,每个物件都有自己的属性值和可以呼叫的方法。这种方式使你能够更好地组织和管理你的程式码,同时也促进了程式码的重用性。
类别继承
当你创建基础类别(Base Class)时,你正在定义一个用于建立其他类别的模板。这个基础类别可以包含共用的属性和方法,供其他衍生类别(Derived Class)继承和扩展。
以下是一个简单的基础类别的示範,以及如何实例化物件:
class Animal: def __init__(self, name): self.name = name def make_sound(self): pass # 在基础类别中,这个方法不做任何事情# 衍生类别 Dog,继承自 Animalclass Dog(Animal): def __init__(self, name, breed): super().__init__(name) # 呼叫基础类别的初始化方法 self.breed = breed def make_sound(self): return "汪汪!"# 衍生类别 Cat,继承自 Animalclass Cat(Animal): def __init__(self, name, color): super().__init__(name) self.color = color def make_sound(self): return "喵喵!"# 创建 Dog 和 Cat 的物件dog = Dog("旺财", "柴犬")cat = Cat("小花", "灰色")# 使用物件的属性和方法print(dog.name + "是一只" + dog.breed + "。" + dog.make_sound())print(cat.name + "是一只" + cat.color + "的猫。" + cat.make_sound())
在这个示範中,我们创建了一个基础类别 Animal,它具有一个共用的属性 name 和一个未实作的方法 make_sound。然后,我们创建了两个衍生类别 Dog 和 Cat,它们分别继承了 Animal 类别,并在其中实作了 make_sound 方法。
透过使用 super() 函式,我们可以在衍生类别的 init 方法中呼叫基础类别的初始化方法,以确保共用的属性能够正确初始化。
最后,我们创建了 Dog 和 Cat 的物件,并使用它们的属性和方法来显示相关讯息。
封装(Encapsulation)
封装是将资料(属性)和操作资料的方法(方法)包装起来的概念。这意味着外部程式码不能直接访问类别内部的资料,只能通过公开的方法(接口)进行访问。这样的设计方式可以隐藏内部的实现细节,同时确保资料的安全性和一致性。
class BankAccount: def __init__(self, account_number, balance): self.__account_number = account_number # 私有属性 self.__balance = balance # 私有属性 def deposit(self, amount): if amount > 0: self.__balance += amount def withdraw(self, amount): if 0 < amount <= self.__balance: self.__balance -= amount def get_balance(self): return self.__balance # 私有方法,用于内部计算手续费 def __calculate_fee(self): return max(self.__balance * 0.01, 5) # 公开方法,用于提取现金并扣除手续费 def withdraw_with_fee(self, amount): if 0 < amount <= self.__balance: fee = self.__calculate_fee() self.__balance -= (amount + fee) return amount # 创建银行帐户account = BankAccount("123456", 1000)# 存款和提款account.deposit(500)account.withdraw(200)# 使用公开方法提取现金并扣除手续费withdrawn_amount = account.withdraw_with_fee(300)print("提取金额(扣除手续费):", withdrawn_amount)print("帐户余额:", account.get_balance())
在这个範例中,BankAccount 类别具有两个私有属性 __account_number 和 __balance,这些属性被双下划线(__)开头,表示它们是私有的。这样外部程式码就不能直接访问这些属性。相反,我们提供了公开的方法 deposit、withdraw、get_balance 和 withdraw_with_fee 来操作这些属性,这些方法可以访问私有属性并进行适当的操作。
另外,我们还在类别中定义了一个私有方法 __calculate_fee,用于内部计算手续费。这个方法只能在类别内部被访问,无法从外部呼叫。
这个範例演示了如何使用封装的原则,保护数据的完整性,同时只提供必要的接口进行操作。这种设计方式可以确保银行帐户的一致性和安全性。
抽象化(Abstraction)
抽象化是将複杂的现实世界映射到简单的模型,并隐藏不必要的细节。在程式设计中,抽象化通常是指将共同的特性和行为提取到基础类别,然后在衍生类别中进行扩展。以下是一个抽象化的範例,使用 Python 的类别来模拟不同类型的动物:
from abc import ABC, abstractmethodclass Animal(ABC): def __init__(self, name): self.name = name @abstractmethod def make_sound(self): passclass Dog(Animal): def make_sound(self): return "汪汪!"class Cat(Animal): def make_sound(self): return "喵喵!"# 创建动物的物件dog = Dog("旺财")cat = Cat("小花")# 使用物件的方法print(dog.name + "发出声音:" + dog.make_sound())print(cat.name + "发出声音:" + cat.make_sound())
在这个範例中,我们定义了一个抽象基础类别 Animal,它继承自 ABC 类别(Abstract Base Class),并定义了一个抽象方法 make_sound。这个抽象方法在基础类别中不实作,而是留给衍生类别来实现。衍生类别 Dog 和 Cat 都继承自 Animal,并分别实作了 make_sound 方法。
由于 Animal 是抽象类别,你无法创建它的实例。而衍生类别必须实作基础类别的抽象方法,这样才能被创建实例并使用。
这个範例展示了如何使用抽象化的概念,将共同的特性抽象到基础类别中,然后在不同的衍生类别中实作具体的行为。这样的设计方式让程式码更容易理解和扩展,同时也能保持一致性。
多重继承(Multiple Inheritance)
多重继承是指一个类别可以同时继承自多个基础类别,从而获取多个基础类别的特性和行为。在 Python 中,你可以通过列出多个基础类别来实现多重继承。
以下是一个多重继承的範例
class Swimmer: def swim(self): return "在水中游泳"class Flyer: def fly(self): return "在空中飞行"class Walker: def walk(self): return "在陆地上移动"# 衍生类别 Penguin,同时继承自 Swimmer 和 Walkerclass Penguin(Swimmer, Walker): def speak(self): return "咕咕!"# 衍生类别 Sparrow,同时继承自 Flyer 和 Walkerclass Sparrow(Flyer, Walker): def speak(self): return "叽叽!"# 创建动物的物件penguin = Penguin()sparrow = Sparrow()# 使用方法print("企鹅:" + penguin.speak()) # 企鹅:咕咕!print("企鹅:" + penguin.swim()) # 企鹅:在水中游泳print("企鹅:" + penguin.walk()) # 企鹅:在陆地上移动print("麻雀:" + sparrow.speak()) # 麻雀:叽叽!print("麻雀:" + sparrow.fly()) # 麻雀:在空中飞行print("麻雀:" + sparrow.walk()) # 麻雀:在陆地上移动
在这个範例中,我们定义了三个基础类别 Swimmer、Flyer 和 Walker,分别代表可以在水中游泳、在空中飞行和在陆地上移动的动物特性。然后,我们创建了两个衍生类别 Penguin 和 Sparrow,它们分别同时继承了不同的基础类别,实现了不同的特性。
Penguin 类别同时继承自 Swimmer 和 Walker,因此可以在水中游泳和在陆地上移动。Sparrow 类别同时继承自 Flyer 和 Walker,因此可以在空中飞行和在陆地上移动。
当我们创建 Child 的物件并呼叫方法时,可以看到它同时继承了两个基础类别的方法,以及自己的方法。
多型(Polymorphism)
多型(Polymorphism)是面向物件程式设计中的一个重要概念,它允许不同的类别使用相同的介面来执行不同的操作。多型让你可以以一种统一的方式处理不同类型的物件,从而提高程式码的灵活性和可读性。
在 Python 中,多型通常是通过继承和方法覆写来实现。当不同的子类别继承自同一基础类别并覆写相同名称的方法时,这些子类别的物件可以以相同的方式呼叫这个方法,但实际上执行的是各自子类别中的实作。这就是多型的应用。
class Animal: def __init__(self, name): self.name = name def speak(self): passclass Dog(Animal): def speak(self): return "汪汪!"class Cat(Animal): def speak(self): return "喵喵!"class Parrot(Animal): def speak(self): return "叽叽!"# 创建不同类型的动物dog = Dog("旺财")cat = Cat("小花")parrot = Parrot("彩虹")# 使用多型呼叫 speak 方法animals = [dog, cat, parrot]for animal in animals: print(animal.name + "发出声音:" + animal.speak())
在这个範例中,我们创建了不同类型的动物物件,并将它们放入一个列表 animals 中。然后,我们使用迴圈遍历这个列表,每个动物物件都可以呼叫 speak 方法,但实际上执行的是该物件所属类别的实作。这就是多型的效果,不同类型的物件可以使用相同的介面来进行操作。
多型让程式码更加灵活,并能够更好地处理不同类型的物件,同时提高程式码的可读性和维护性。
总结
类别(Class)是面向物件程式设计(OOP)的核心概念之一,它允许你创建複杂的资料结构,包含属性和方法,用于模拟现实世界中的实体和行为。以下是关于类别用法的总结:
定义类别: 使用 class 关键字定义类别,你可以在类别中定义属性和方法。
属性(Properties): 类别的属性是与该类别相关的资料,它们储存物件的状态。你可以使用 self 关键字来定义属性,并在 init 方法中初始化它们。
方法(Methods): 类别的方法是与该类别相关的函式,用于操作类别的属性,执行特定的任务。
初始化方法(init): 这是一个特殊的方法,用于初始化物件的属性。它在创建物件时自动呼叫。
继承(Inheritance): 继承允许你创建一个新的类别,基于现有的类别,并继承其属性和方法。这促进了程式码重用和组织。
封装(Encapsulation): 封装是隐藏物件的内部细节,只公开必要的介面。这可以防止外部程式码直接访问物件的属性,确保资料的安全性。
抽象化(Abstraction): 抽象化是提取类别的共同特性和行为,以形成一个简化的模型。这提高了程式码的可读性和可维护性。
多重继承(Multiple Inheritance): 多重继承允许一个类别同时继承自多个基础类别,获取它们的特性和方法。
多型(Polymorphism): 多型允许不同的子类别使用相同的介面来执行不同的操作,提高程式码的灵活性。
使用範例: 通过定义不同类型的类别、创建物件、访问属性和呼叫方法,你可以在程式中模拟现实世界的情况。
总之,类别是一种强大的程式设计工具,它允许你组织程式码、模拟现实世界中的概念,并提供了结构化和模组化的方式来开发複杂的应用程式。
系列文章
分享所学贡献社会
[Python教学]开发工具介绍
[开发工具] Google Colab 介绍
[Python教学] 资料型态
[Python教学] if判断式
[Python教学] List 清单 和 Tuple元组
[Python教学] for 和 while 迴圈
[Python教学] Dictionary 字典 和 Set 集合
[Python教学] Function函示
[Python教学] Class 类别
最后最后有一件小小的请求,请大家帮我填写一下问卷,
让我们知道你想上怎么样课程,感激不尽。
问卷这边
Facebook 粉丝页 - TechMasters 工程师养成记
程式教育 - 工程师养成记
Python程式种子班-现正开放报名中
同步分享到部落格