Python面向对象编程

2.1 面向对象与面向过程

面向过程:从机器角度出发考虑问题

面向对象:从人的角度出发考虑问题

比如:学生上学

面向过程

起床
洗刷刷,穿衣打扮
出门,往教室方向走
if 走到十字路口:
    while 红灯亮:
        等待绿灯
    
走到教室
while 上课时间未到:
    等待上课
开始上课
while 下课时间未到:
    等待下课
吃饭
睡觉
打豆豆

面向对象

定义一个学生类
定义学生类的属性:姓名、性别、年级、专业、班级、……
定义学生类的方法:吃饭()、睡觉()、上课()、下课()、……
定义一个教室类
定义教室类的属性:位置、容量、类别、……
定义教室类的方法:开门()、关门()、……
定义一个学生类的对象:张三
定义一个教室类的对象:bz201
张三.上课(bz201)

面向过程适合底层开发、快速开发

面向对象适合上层开发、组织大规模团队开发

2.2 什么是对象

天上飞的:飞机、大炮、鸟、鹰、……

地上跑的:鸡鸭鹅、狗猫人、猪牛羊、……

水里游的:鱼虾蟹、……

抽象的概念:作业、项目、工作、公式……

世界上万事万物都是对象

2.3 区分类和对象

思考:

1 狗是类 狗是对象

2 张三是类 张三是对象

结论:对象是具体的概念,具体的某个事物。类是抽象的概念,是多个个体的结合

一个类中可以包含多个对象

对象是类的特殊表现

因为是面向对象编程,所以是对实际的个体,比如张三李四进行编程

张三.xxx
李四.yyy
王五.zzz

2.4 Python中声明类和创建对象

声明类:使用关键字 class

编码规则:类名首字母必须大写

class 类名:
    类的实现代码

比如:

# 声明一个狗类
class Dog:
    pass

# 创建类的对象
dog1 = Dog()
print(dog1) # <__main__.Dog object at 0x000001B9BB3AF7F0>
print(type(dog1)) # <class '__main__.Dog'>

2.5 属性

属性是类中的特性

设置属性

# 声明一个狗类
class Dog:
    pass


dog1 = Dog()
# 设置狗的属性
# 对象名.属性名 = 属性值
dog1.name = '旺财'
dog1.age = 8
dog1.sex = 'male'
# 读取狗的属性
# 对象名.属性名
print(dog1.name)
print(dog1.age)
print(dog1.sex)

如果想要查看对象或类的属性,可以通过 dir() 函数查看

dog1 = Dog()
print(dir(dog1)) # 没有 'age', 'name', 'sex'
# 设置狗的属性
# 对象名.属性名 = 属性值
dog1.name = '旺财'
dog1.age = 8
dog1.sex = 'male'
print(dir(dog1)) # 有 'age', 'name', 'sex'
# 读取狗的属性
# 对象名.属性名
print(dog1.name)
print(dog1.age)
print(dog1.sex)

发现,name、age、sex属性是临时添加上去的

如果希望属性固定在类中,可以把属性写到类的实现代码中

class Dog:
    name = ''
    age = 0
    sex = 'male'

dog1 = Dog()
print(dir(dog1)) # 有 'age', 'name', 'sex'
dog2 = Dog()
print(dir(dog2)) # 有 'age', 'name', 'sex'

 2.6 方法

方法是类中进行的一系列操作

定义方法:

class 类名:
    ...
    def 方法名(方法参数列表):
        方法体
        [return 返回值]

方法的首字母必须小写。

与函数不同的是:函数可以独立存在,方法则必须依赖于类

方法的参数列表,首个参数必须是self

class Dog:
    # 狗叫的方法
    def bark(self):
        print('旺')

dog1 = Dog()
dog1.bark()

方法可以传递参数

class Dog:
    ...
    # 狗吃的方法
    def eat(self, something):
        print('狗吃' + something)

dog1 = Dog()
...
dog1.eat('骨头')

方法中访问类的属性,使用self

class Dog:
    name = ''
    ...
    # 设置狗的名字
    def setName(self, name):
        self.name = name
    # 获取狗的名字
    def getName(self):
        return self.name

dog1 = Dog()
...
dog1.setName('小花')
print(dog1.getName())

2.7 __init__

__init__是Python自带的方法,表示初始化

当创建类的对象时,进行初始化操作,比如:网络连接、连接数据库、打开文件

当类的对象被创建的适合就会触发该方法的调用

class Dog:
    # 初始化
    def __init__(self, name, age):
        self.name = name
        self.age = age

dog1 = Dog('旺财', 8)
print(dog1.name)
print(dog1.age)
dog2 = Dog('小花', 12)
print(dog2.name)
print(dog2.age)

2.8 __del__

删除对象的适合清理用过的内容,两种情况会触发这个方法:

1 当程序退出的适合,系统清理对象,该方法会被调用

2 程序员主动调用 del 命令,主动触发该方法

class Dog:
    # 初始化
    def __init__(self, name, age):
        self.name = name
        self.age = age
    # 退出
    def __del__(self):
        print('__del__')
        self.name = ''
        self.age = 0

dog1 = Dog('旺财', 8)
print(dog1.name)
print(dog1.age)
del dog1 # __del__
print('over')

2.9 封装

面向对象的三大特征:封装、继承、多态

封装是指把属性私有化(private)

Python中描述属性的私有化,通过前置下划线来表示

1 _xxx:单前置下划线(包外部不能访问)

2 __xxx:双前置下划线(其他类不能访问)

3 __xxx__:双前置双后缀下划线(类中自带的)

私有化后,类的外面无法直接获取该属性

一般需要通过 setXxx() 修改属性,通过 getXxx() 获取属性

class Dog:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    def getAge(self):
        return self.__age
    def setAge(self, age):
        if age > 0:
            self.__age = age

# 创建对象
dog1 = Dog('旺财', 8)
dog1.setAge(-3)
print(dog1.getAge())

2.10 继承

子类继承父类

class 子类(父类):
    子类的实现代码

父类中所有非私有的属性和方法,子类中都可以获取并使用

# 父类
class Animal:
    def eat(self):
        print('Animal eat')
# 子类
class Dog(Animal):
    pass
#
dog1 = Dog()
dog1.eat()
print(dir(dog1))

子类中可以重写父类的方法
 

# 父类
class Animal:
    def eat(self):
        print('Animal eat')
# 子类
class Dog(Animal):
    ### 重写父类的方法 ###
    def eat(self):
        super().eat() # 调用父类的方法
        print('Dog eat')
#
dog1 = Dog()
dog1.eat() # 调用子类的方法
print(dir(dog1))

子类还可以继续派生子类(孙类?)

# 子类的子类
class HabaDog(Dog):
    ### 重写父类的方法 ###
    def eat(self):
        super().eat() # 调用父类的方法
        print('HabaDog eat')
#
dog2 = HabaDog()
dog2.eat()

如果一个类没有继承任何父类,则默认继承 object 类

下面两种写法等效

class Animal:
    def eat(self):
        print('Animal eat')
class Animal(object):
    def eat(self):
        print('Animal eat')

更推荐使用后者

2.11 多态

不同事物,对于同一个操作所表现出来的不同形态

外科医生、厨师、演员 cut...

动手术……切菜……下班

# 父类
class Animal:
    def eat(self):
        print('Animal eat')
# 子类
class Dog(Animal):
    def eat(self):
        print('Dog eat')
class Man(Animal):
    def eat(self):
        print('Man eat')
class Woman(Animal):
    def eat(self):
        print('Woman eat')
# 函数
def doEat(obj):
    obj.eat()
#
dog1 = Dog()
man1 = Man()
woman1 = Woman()
doEat(dog1)
doEat(man1)
doEat(woman1)

doEat()方法中,理论上可以传递任意类型的对象

如果该对象中没有eat()方法,则会报错

考虑规定doEat()的参数必须是Animal或子类的对象

推荐使用 isinstance() 函数,判断对象是否为某个类的对象

a1 = Animal()
print(isinstance(dog1, Dog)) # True
print(isinstance(dog1, Animal)) # True
print(isinstance(a1, Animal)) # True
print(isinstance(a1, Dog)) # False
print(isinstance('hello', Animal)) # False

在doEat()方法中判断输入的参数 obj 是否为Animal 对象,只有Animal对象才能调用eat方法

# 函数
def doEat(obj):
    if isinstance(obj, Animal):
        obj.eat()

以后处理多态的代码时,都建议加上 isinstance() 的判断

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值