python面向对象—01-类、属性、方法
Part One :面向对象
面向对象 问题引入
问题一: 什么是对象 ?
- 一切皆对象 !
- 可以简单的将“对象”理解成“某个东西” !
- “对象”一词表示它应该拥有属于它自己的“特征”与“行为” !
问题二: 什么是面向对象 && 面向对象的意义?
面向对象是相对于面向过程而言的。首先我们先介绍下面向过程的特点以及问题:
- 变量和函数。 “散落” 在文件的各个位置,甚至是不同文件中。
- 看不出变量与函数的相关性,非常不利于维护,设计模式不清晰。
- 经常导致程序员,忘记某个变量的相关性,而导致无法检测的错误。
而面向对象针对面向过程的不足,提出的一种新的编程思想使得程序设计简明清晰,有利于代码管理与维护总结如下:
- 相关的变量和函数都“封装” 在对象里,以对象为单位来管理代码。
- 变量与函数的相关性清晰,利于维护,设计模式清晰。
- 程序员可以配合“继承” 来提高代码的可重用性,加强合作开发。
Part Two :类和实例
类和实例 问题引入
问题一: 你觉得“类”或“实例”是对象嘛 ?
- 一切事物皆对象,‘一个类的实例’与一个类的对象说的是一个意思。类在某种情况下,是一种带属性和方法的数据类型,数据类型也可以认为是一种数据对象。
问题二: “类”和“实例”的区别 ?
- 类是一类事物的抽象,不是真是存在的。描绘了该类事物的共性,例如:“人”、“动物”、“家具”
- 实例某类事物的具体个体,是该类事物的具体表现,它是真实存在的。例如:“马云”是具体的某个“人”, “加菲猫”是具体的某个“动物”。
问题三: 如何创建一个“类”和“实例” ?
创建“类”
class Person:#驼峰命名规则 pass #类的嵌套块 属性和方法
创建”实例”
p = Person() #实例化一个具体的人 #类似于函数调用, 返回一个具体“实例” !
问题四: 如何确定类和实例之间的关系 ?
isinstance 判别函数
isinstance(对象, 类)
判断“对象”,是不是“类”的实例
isinstance(对象, 类的元组)
判断“对象”,是不是“类的元组”中的某一个“类”的实例
class Person :#人类
pass
class Animal :#动物类
pass
p1 = Person() #实例化第一个具体的人
p2 = Person() #实例化第二个具体的人
a =Animal() #实例化一个具体的动物
print(p1 is p2) #False ,同一个类,可以对应许多不同的实例
print(isinstance(p1,Person)) #True
print(isinstance(a,Animal)) #True
print(isinstance(p1,Animal)) #False
print(isinstance(p1,(Person,Animal)) #True 判断是否属于某一类
Part Three :属性封装
属性封装 问题引入
问题一: 单纯的看类,它有什么效果 ?
- 实例也是独立的变量空间
问题二: 为什么叫“属性” ?
- 封装在“实例”里面的变量,表征了实例的特点或特征
问题三:“类”和“实例”都可以封装属性嘛?
- 类就是一个独立存放变量的空间与属性查找
运算符“.”— 用于进行变量空间的运算
class Person:
var1 = '直接封装在类中的变量'
print(Person.var1)
Person.var2 = '后来封装在类中的变量'
print(Person.var2)
p = Person() #实例化
print(p.var1)#实例化中也可以看到类封装中的变量
print(p.var2)#实例中找不到后来转到类中的变量
实例也是一个独立存放变量的空间
每个实例都是一个独立的变量空间。不同实例之间的空间互相不可见。
class Person:
pass
p1 = Person()
p2 = Person()
p1.var = '在实例中封装的变量'
print(p1.var)
print(Person.var)#AttributeError ,类中找不到,不会去实例中找
print(p2.var)#p2没有,去找Person ,也没有
一个“实例”的“特征”,就是“属性”
Part four:属性封装
封装方法 问题引入
问题一: 什么是方法?
- “实例方法”就是封装在类里的一种特殊的函数
- “实例方法”表示的是“实例”的行为
问题二: 方法代表了什么?
- 该类事物的实例所共有的行为
- “实例方法”表示的是“实例”的行为
问题三: 为什么要把属性和方法封装?
- 实例方法是一个类中所有实例公共的行为。因此,通常不会每个实例里存放一个, 而是存在于类中。
- 方法总是定义在类中的,但是却叫“实例方法”,因为它表示该类所有实例所共有的行为
- 这多个个对象,通过封装,深度的绑定在了类与实例中
“实例方法”就是封装在类里的一种特殊的函数
错误写法:
class Person:
def func():
print('方法实现')
Person.func()
p = Person()
p.func() #TypeError ,多传入了一个参数
正确写法:
class Person:
def func(arg):
print('参数:',arg)
Person.func('直接通过类调用')
p = Person()
print(p)
p.func() #默认传入p对象自身
输出结果:
参数: 直接通过类调用
<__main__.Person object at 0x000000FAB419A470>
参数: <__main__.Person object at 0x000000FAB419A470>
“实例方法”表示的是“实例”的行为
class Person:
def eat(self):
print('{name} eating...'.format(name = self.name))
p1 = Person()
p1.name = 'Tuple'
p2 = Person()
p2.name = 'Bob'
p1.eat() #Person.eat(p1)
p2.eat() #Person.eat(p2)
这样,就将name变量与eat函数,这两个相关对象,通过封装,深度的绑定在了类与实例中
“实例方法” 的调用过程与 self
通常,将默认会传入的那个参数命名为 self,用来表示 调用这个方法的实例对象本身。
方法总是定义在类中的,但是却叫“实例方法”,因为它表示该类所有实例所共有的行为
对面向对象的总结
知识点一: 所谓面向对象,就是从事物的内部联系, 与事物与事物间的外部联系来考虑我们的代码设计的。
知识点二: 类与实例,是现实对象在代码中的体现。它们也提供了专门的变量空间。
知识点三: 属性表示的是实例的特征,通常标识了一个实例。因此,通常存在于实例中。
知识点四: 实例方法是一个类中所有实例公共的行为。因此,通常不会每个实例里存放一个, 而是存在于类中。
面向对象练习:
class Account:
def account(self,name,number,balance):
'''
:param name: 账户名称
:param number: 账户号
:param balance: 账户余额
:return: 返回一个acct对象
'''
self.name =name
self.number = number
self.balance = balance
def deposit(self,amount):
'''
:param self: 账户对象
:param amount: 存款金额
:return: 没有返回值(None)
'''
if amount <= 0:
print('存款金额不得为负')
else:
self.balance += amount
def withdraw(self,amount):
'''
:param self: 账户对象
:param amount: 取款金额
:return: 没有返回值(None)
'''
if amount > self.balance:
print('余额不足')
else:
self.balance -= amount
def desc(self):
'''
:param self: 账户对象
:return: 返回该账户的字符串表示
'''
return "Account({name},{number},{balance})".format(name=self.name,number=self.number,balance=self.balance)
print('请按要求输入账户信息:')
name = input('请输入用户姓名:')
number = input('请输入用户账户:')
balance = input('请输入用户余额:')
acct =Account()
acct.account(name,number,int(balance))
print('%s账户创建成功!!!'%acct.name)
print(acct.desc())
amount = input('请输入存款金额:')
acct.deposit(int(amount))
print(acct.desc())
amount = input('请输入取款金额:')
acct.withdraw(int(amount))
print(acct.desc())
使出结果:
请按要求输入账户信息:
请输入用户姓名:li
请输入用户账户:234
请输入用户余额:111
li账户创建成功!!!
Account(li,234,111)
请输入存款金额:11
Account(li,234,122)
请输入取款金额:32
Account(li,234,90)
进程已结束,退出代码0