【Python】面向对象--OOP

目录

面向对象的三大特征

1.封装:提高程序的安全性

2.继承:提高代码的复用性

继承和多继承

方法重写

object类

3.多态:提高程序的课扩展性和可维护性


面向对象编程——是一种以对象为中心的程序设计思想

面向过程编程——是一种以过程为中心的程序设计思想

问题:把大象装进冰箱,需要几步?

答案:三步

第一步:打开冰箱

第二步:把大象装进去

第三步:关闭冰箱

一、面向过程编程

面向过程是把问题拆分成一个个函数和数据,按照一定的顺序来执行这些方法

上面的答案就是面向过程的编程,遇到问题,一步步解决

二、面向对象编程

面向对象是把问题抽象成一个个对象,给这些对象绑上属性和方法,即以功能而非步骤划分问题

首先面向对象要解决这个问题,需要先建立出抽象模型,比如:打开和关闭冰箱的门,都是属于冰箱的功能;大象走进去,是大象的功能。此时就出现了两个抽象的模型,一个是冰箱,一个是大象。

面向对象的思想,就是要创建冰箱和大象这两个对象,最终完成这个程序。

冰箱对象—开门,大象对象—走进去,冰箱对象—关门

面向对象就是调用对象去解决问题,不管具体的对象如何去解决的,对于我们来说,就是调用了这个对象,而对象去完成这个任务

三、如何学习面向对象的编程

1.学习面向对象编程的思想

2.学习面向对象编程的语法

四、面向过程和面向对象的优缺点

1.面向过程

面向过程的核心是过程,过程就是指解决问题的步骤

优缺点:

✦ 优点:将负责的问题流程化,进而实现简答化

✦ 缺点:扩展性更差(更新,维护,迭代)

总结:完成一些简单的程序时,可以用面向过程去解决。但面对复杂的程序或者任务,而且需要不断的进行迭代和维护时,则优先选择面向对象的编程。

2.面向对象

面向对象的核心是对象,是一个特征和功能的综合体

优缺点:

✦ 优点:可扩展性高

✦ 缺点:编程复杂度相对更高一些。指的是计算机在执行面向对象的程序时的性能表现

3.面向对象的一些名称(术语)

:类是对象的一个抽象

对象(实例):对象就是由类创建的实例

类和对象的关系就是 模具和铸件的关系

  • 类是由对象总结而来的,总结的过程叫抽象
  • 对象是由类具体实施出来的,这个过程叫做实例化

五、面向对象编程的基本实现

1.创建类

语法:

class Student():  
    pass

如果需要实例一个对象,那么需要先抽象一个类

# 面向对象  oop  基本实现
'''
类名的书写规范,建议使用驼峰命名法:
    大驼峰:MyCar,XiaoMi
    小驼峰:myCar,xiaoMi
​
一个类有特征和功能两个内容组成:
    特征:颜色:白色,品牌:奥迪,排量:2.4 ……
    功能:拉货、带美女兜风
​
    特征在编程中就是一个属性,在类中称为  变量
    功能在编程中就是一个函数,在类中称为  方法
'''

类中一般属性在前面定义,方法在后面定义

示例:

#定义一个汽车的类
class Cart():
    #属性 ==> 特征 ==> 变量
    color = '白色'
    brand = '奥迪'
    pailiang = 2.4
​
    #方法 ==> 功能 ==> 函数
    def lahuo(self):
        print('小汽车能拉货')
​
    def doufeng(self):
        print('小汽车能兜风')
​
    def bamei(self):
        print('带妹去嗨……')

如何通过类实例化去使用?

# 如何使用这个类?
# 通过类实例化一个对象
aodiobj = Cart()
print(aodiobj,type(aodiobj))
​
# 调用对象的方法
aodiobj.doufeng()
​
# 获取对象的属性
print(aodiobj.brand)

2.对象成员的操作

什么是对象的成员?一个对象通过类实例化之后,那么在类中定义的属性和方法,可以使用实例化的对象进行操作 类中定义的属性也称为 成员属性,类中定义的方法,也称为 成员方法

# 实例化对象
a = Cart()
b = Cart()
print(a)
print(b)

'''
a 和 b都是对象,都是通过Cart这个类实例化出来的,但是他们是两个对象
<__main__.Cart object at 0x000001B3FFA19FD0>
<__main__.Cart object at 0x000001B3FFA19FA0>
'''
# 对象成员的操作
# 在类的外部,使用对象操作成员
# 访问成员属性:先访问a对象自己的color属性,如果没有,就去访问这个对象的类的属性

res = a.color # 通过对象访问类中的属性
a.color = '黑色' # 修改对象的属性

# 此时 b 对象的color属性是什么?
print(b.color) # b对象的属性依然是原来的值
​

a.name = 'A6' # 给对象添加属性,此时的'name'属性只属于a这个对象
# 此时 b 对象中不会有'name'这个属性
​

# del a.brand # AttributeError: brand 不能删除
del a.name # 可以删除


'''
删除一个对象的属性时,只能删除当前这个对象自己的属性才可以,
brand这个属性并不属于a对象自己的属性,而是属于Cart这个类的,因此不能删除
name这个属性,是单独给a添加的属性,因此可以删除
'''
​
# 在类的外部操作对象的方法
# 访问对象的方法:如果这个对象没有自己独立的方法,那么就会访问对象的类的方法
# res = a.lahuo() # 通过对象访问类中的方法

def func():
    print('这是一个新的方法')
​
a.lahuo = func # 把一个函数值赋给成员
a.lahuo() #调用方法
​
# 添加新的方法
a.func2 = func
​
# 删除方法
del a.func2 # 可以删除,对象单独添加的方法
del a.lahuo # 可以删除对象改过的方法
del a.bamei # AttributeError: bamei 类的方法,不能删除

3.总结

实际上,在创建对象的时候,不会把类的属性和方法复制一份给对象,而是在对象中引用父类的方法 因此在访问对象的属性时,也会先去找对象自己的属性,如果没有就去找这个对象的类的属性和方法

一个对象由类创建以后,是一个独立的对象,可以引用父类中的属性和方法 如果在对象创建以后,给对象的属性或方法 进行修改或添加,等于给这个对象创建了一个属于自己的属性和方法 所以在删除时,只能删除对象被修改或添加的成员

六、面向对象的三大特征

1.封装:提高程序的安全性

将特征(属性)和功能(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。

在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个"_"

示例:

# 封装
class Student:
    def __init__(self,name,age):
        self.name = name
        self.__age = 20 # 表示变量age在类外部不能被访问
​
    def func(self,name,age):
        print(f'{name}的年龄是{age}')
​
stu1 = Student('张三',30)
print(stu1.name)
# print(stu1.age) # AttributeError: 'Student' object has no attribute 'age'
print(dir(stu1))
print(stu1._Student__age) # 私有属性可以通过_Student__age访问

2.继承:提高代码的复用性

继承和多继承
语法格式:
        class 子类类名(父类1,父类2,……)
            pass
    如果一个类没有继承任何类,则默认继承object
    Python支持多继承
    定义子类时,必须在其构造函数中调用父类的构造函数

示例:

class Person:
​
    def __init__(self,name,age):
        self.name = name
        self.age = age # 表示变量age在类外部不能被访问
​
    def func(self):
        print(f'{self.name}的年龄是{self.age}')
        
class Student(Person):
​
    def __init__(self,name,age,score):
        super().__init__(name,age)
        self.score = score
​
class Teacher(Person):
​
    def __init__(self,name,age,tyear):
        super().__init__(name,age)
        self.tyear = tyear
​
stu = Student('lucy',20,80)
teacher = Teacher('jack',35,7)  # 实例化
stu.func()
teacher.func()  # 调用父类的方法       
方法重写

应用场景: 当父类的方法不能满足子类的需求时,可以对方法进行重写(override)

1)覆盖父类方法 子类中定义同名的方法即可,本质来说,调用方法会先在子类中寻找,如果子类没有该方法则到父类中寻找。

2)对父类方法进行扩展 如果子类方法实现中包含了父类方法实现,那么不使用覆盖的方式而是对父类方法进行扩展。 子类中定义同名方法,在需要的位置使用super().父类方法即可

示例:

class Student(Person):
​
    def __init__(self,name,age,score):
        super().__init__(name,age)
        self.score = score
​
    def func(self):  # 方法重写
        super().func()  # 通过super().func()调用父类中的方法
        print(self.score)
 
stu = Student('lucy',20,80)
stu.func() # 调用重写的方法 ##80
object类

object类是所有类的父类,因此所有类都有object类的属性和方法。

内置函数dir() 可以查看 指定对象所有的属性

object有一个str() 方法,用于返回一个对于“对象的描述”,对应于内置函数str() ,经常用语print() 方法,帮我们查看对象的信息,所以经常会对str() 进行重写

示例:

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
​
    def info(self):
        print('姓名:{},年龄:{}'.format(self.name,self.age))
​
    def __str__(self):
        return '姓名:{},年龄:{}'.format(self.name,self.age)
o = object()
p = Person('jack',20)
print(dir(o))
print(dir(p))
print(p) # 姓名:jack,年龄:20

3.多态:提高程序的课扩展性和可维护性

简单来说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法。

多态: 不同的子类对象调用相同的父类方法,产生不同的执行结果。

实现步骤:

  • 子类继承父类
  • 子类重写父类的同名方法
  • 定义一个共同的方法,参数为父类对象,在方法中调用子类和父类同名的方法

示例:

class Animal():
    def eat(self):
        print('动物会吃')
​
class Cat(Animal):
    def eat(self):
        print('猫吃鱼')
​
class Dog(Animal):
    def eat(self):
        print('狗吃肉')
​
class Person(Animal):
    def eat(self):
        print('人吃五谷杂粮')
​
def fun(obj):
    obj.eat()
​
#开始调用函数
fun(Cat())
fun(Dog())
fun(Animal())
print('-------------------------')
fun(Person())

多态指同一个方法调用,由于对象不同可能会产生不同的行为。

  • 多态是方法的多态,属性没有多态
  • 多态的存在有两个必要条件:继承、方法重写

七、特殊属性和方法

1.特殊属性

__ dict __ :获得类对象或实例对象所绑定的所有属性和方法的字典

2.特殊方法

__ len__()通过重写len() 方法,让内置函数len()的参数可以是自定义类型
__ add__()通过重写add()方法,可使用自定义对象具有“+”的功能
__ new__()用于创建对象
__ init__()对创建的对象进行初始化
__ new__()方法

示例:

class Person():
​
    def __new__(cls, *args, **kwargs):
        print('__new__被执行调用了,cls的id值是{}'.format(id(cls)))
        # __new__被执行调用了,cls的id值是2605846583216  3
        obj = super().__new__(cls)
        print('创建的对象的id为:{}'.format(id(obj)))
        # 创建的对象的id为:2605854928656  4
        return obj
​
    def __init__(self,name,age):
        print('__inti__方法被调用了,self的id值为:{}'.format(id(self)))
        # __inti__方法被调用了,self的id值为:2605854928656   5
        self.name = name
        self.age = age
​
​
print('object这个类对象的id为{}'.format(id(object))) 
# object这个类对象的id为140719232921088  1
print('Person这个类对象的id为{}'.format(id(Person))) 
# Person这个类对象的id为2605846583216     2
​
# 创建Person类的实例对象
p1 = Person('张三',20)
# 创建对象的时候,Person被传给了 __new__方法中的cls
# 返回的obj赋值给了__init__方法里的self,self传给p1
print(f'p1这个Person类的实例对象的id为{id(Person)}')
# p1这个Person类的实例对象的id为2605846583216   6
'''
创建对象时,先调用new,返回,再执行inti,cls地址对应类的地址,self地址对应创建的实例的地址
'''

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值