智泊Python–Day12
Day12 进入 面向对象编程(OOP)——Python 从这一刻从「写函数」升级到「建模现实」。核心心法:类(class)是模板、对象(object)是实例;用类把「数据(属性)」和「行为(方法)」打包在一起。这一天的链条是:先对比面向过程 / 面向对象的思想差异,再定义类与对象、理解 self、搞清构造 / 析构方法,最后分清「类属性」与「对象属性」的优先级,并用四个综合作业把 OOP 真正用起来。
1.面向对象
两种编程思想:
- 面向过程:关心「先做什么、再做什么」的步骤
- 面向对象:关心「谁来做」,用类把对象的功能封装起来
下面「小狗吃食物」用两种写法对比最直观——过程版是三个独立函数依次调用,对象版是 Dog 类把「闻 / 舔 / 咬」作为方法挂在对象上,由 dog 这个具体对象去调用。
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
|
def smell(): print('闻一闻')
def touch(): print('舔一舔')
def bite(): print('咬一咬')
smell() touch() bite() print('-----------------')
class Dog: def __init__(self, name, age): self.name = name self.age = age
def smell(self): print('闻一闻')
def touch(self): print('舔一舔')
def bite(self): print('咬一咬')
dog = Dog('小白', 1) dog.smell() dog.touch() dog.bite()
|
2.类和对象
类是同一类事物的抽象统称(不占内存),对象是类的具体实例(占内存,每个对象独立)。自定义类默认继承 object,__init__ 是初始化方法(构造方法),里面用 self.xxx = xxx 定义对象属性。同一个类可以 new 出任意多个对象,彼此数据互不干扰。
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
|
class Person:
def __init__(self, name, sex): self.name = name self.sex = sex
def run(self): print(self.name, '在跑步')
p1 = Person('张三', '男') print(p1.name) print(p1.sex) p1.run() p2 = Person('李四', '女') print(p2.name) print(p2.sex) p2.run() print('-----------------')
class Phone: def __init__(self, color, size, price): self.color = color self.size = size self.price = price
def call(self): print('打电话打电话')
def play_game(self): print('玩游戏')
def chat(self): print('聊天')
iphone16 = Phone('白色', '6.1英寸', 9999)
|
3.self详解
self 不是 Python 关键字,只是一个约定俗成的第一个形参。你不用手动给它传值——谁调用方法,self 就指向谁。它的作用是:在方法内部通过 self.xxx 访问「当前这个对象」的其它属性和方法。理解 self 是理解面向对象的关键。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
class Dog: def __init__(self, name, age): self.name = name self.age = age def say(self): print(f'我是{self.name},我今年{self.age}岁')
dog = Dog('旺财', 1) dog.say()
|
4.构造方法和析构方法
两个特殊方法:**__init__ 构造方法在「创建对象时」自动调用,用来初始化;__del__ 析构方法**在「对象被销毁时」自动调用(一般不用管,了解即可)。下面 Animal('小白') 一创建就打印「被创建了」,等程序结束对象回收时打印「被销毁了」。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
class Animal: def __init__(self, name): self.name = name print(f'{self.name}被创建了')
def __del__(self): print(f'{self.name}被销毁了')
cat = Animal('小白')
|
5.对象属性和类属性
属性分两种:类属性写在类里(用 类名.属性 调用,所有对象共享),对象属性写在 __init__ 里(用 对象名.属性 调用,每个对象独立)。当对象属性和类属性同名时,通过对象访问会优先拿到「对象属性」。下面 Rerson 演示了:改类属性 Rerson.age 只影响类层面,改 p.age 只影响这个对象。
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
|
class Rerson: sex = '男' age = 30
def __init__(self, name, age): self.name = name self.age = age
p = Rerson('张三', 18) print(p.age) print(p.sex) print(Rerson.sex)
print(Rerson.age) print(p.age) print('-----------------')
Rerson.age = 20 print(Rerson.age) p.age = 25 print(p.age) print('-----------------')
class Dog:
likes = ['bone', 'ball']
def __init__(self, name): self.name = name self.likes2 = ['bone', 'ball']
dog1 = Dog('小白') dog2 = Dog('小黑')
Dog.likes.append('meat') print(Dog.likes) print(dog1.likes) print(dog2.likes) print('-----------------')
dog1.likes2.append('meat') print(dog1.likes2) print(dog2.likes2) print('-----------------')
|
6.作业
四个 OOP 实战,难度递进:①Person 带 run(place, shoes) 方法;②Person2 + Pig 两个类协作「找猪」;③Circle + Point 组合,求圆周长面积、判断点与圆的位置关系;④Account 银行账户,含存钱 / 取钱(余额不足要提示)/ 查余额。
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
|
class Person: def __init__(self, name): self.name = name
def run(self, place, shoes): print(f'{self.name}穿着{shoes}在{place}跑步')
p1 = Person('小明') p1.run('奥林匹克公园', '白色特步运动鞋') print('-----------------')
class Person2: def __init__(self, name, pig, place): self.name = name self.pig = pig self.place = place
def find_pig(self): print(f'{self.name}在找他的{self.place}:{self.pig}')
class Pig: def __init__(self, name, place): self.name = name self.place = place
pig1 = Pig('笨笨','荷兰宠物猪') p2 = Person2('王梅', pig1.name, pig1.place) p2.find_pig()
class Circle: def __init__(self, r, point): self.r = r self.point = point
def perimeter(self): return 2 * 3.14 * self.r
def area(self): return 3.14 * self.r ** 2
class Point: def __init__(self, x, y): self.x = x self.y = y
def relation(self, circle): if (self.x - circle.point.x) ** 2 + (self.y - circle.point.y) ** 2 == circle.r ** 2: return '在圆上' elif (self.x - circle.point.x) ** 2 + (self.y - circle.point.y) ** 2 > circle.r ** 2: return '在圆外' else: return '在圆内'
c1 = Circle(6, Point(0, 0)) print(c1.perimeter()) print(c1.area())
p1 = Point(3, 4) print(p1.relation(c1)) print('-----------------')
class Account: def __init__(self, name, balance): self.name = name self.balance = balance
def save_money(self, money): self.balance += money print(f'{self.name}存钱{money},余额为{self.balance}')
def get_money(self, money): if self.balance >= money: self.balance -= money print(f'{self.name}取钱{money},余额为{self.balance}') else: print(f'{self.name}余额不足,取钱失败')
def show_balance(self): print(f'{self.name}的余额为{self.balance}')
A1 = Account('张三', 1000) A1.save_money(500) A1.get_money(200) A1.show_balance() print('-----------------')
|