面向对象
面向对象是一种编程思想,是一种通过多个对象互相协作完成的处理流程的编程思路,在核心处理过程中,又主要区分为类的声名定义,对象的创建使用,面向对象拥有的的三个特征【三大特征:封装, 继承, 多态】
封装:体现了对象对于敏感数据的保护特征
继承:体现了代码的复用和功能的扩展
多态:体现了不同操作环境中代码的多样性【程序的健壮性】
类和对象:是面向对象编程思想的一种实现
类的声明语法和注意事项
声明一个类型:就是表示生活中的一个事物
操作步骤:
从大量的实际存在的物体【实体】中抽象他们拥有的共同特征
从大量实际存在的物体中抽象他们拥有的共同行为
代码操作:声明一个人,电脑
class Person:
"""
定义类型的特征/属性
人的类型
"""
def __init__(self, name, age, gender):
"""类型的初始化方法:固定手法 方法名称固定"""
# 当前类型如果创建对象,对象的属性赋值的操作
self.name = name
self.age = age
self.gender = gender
def eat(self):
"""
定义类型的行为
"""
print("吃药时间到,我爱吃药我爱吃药,吃药吃药,爱爱爱爱爱爱")
class Person:
"""
定义类型的特征/属性
人的类型
"""
def __init__(self, name, age, gender):
"""类型的初始化方法:固定手法 方法名称固定"""
# 当前类型如果创建对象,对象的属性赋值的操作
self.name = name
self.age = age
self.gender = gender
def eat(self):
"""
定义类型的行为
"""
print(self.name,"吃药时间到,我爱吃药我爱吃药,吃药吃药,爱爱爱爱爱爱")
类:类型的简称,是数据类型的简称,是对一类事物的抽象出来的名称
双下划线开头和结尾的方法:类型的魔法方法
对象的创建语法和注意事项
# 创建对象的语法
da_shen = Person('悟空', 45, '公')
# 再创建一个对象
ba_jie = Person('八戒',34, '公')
对象操作属性
# 使用对象的属性
print(da_shen.name)
# 修改属性的值
da_shen.name = "泼猴"
print(da_shen.name)
使用对象的行为
# 使用对象的行为
da_shen.eat()
ba_jie.eat()
类和对象的区别
类是一堆属性和行为,对象是一堆属性和行为的赋值
面向对象封装的意义
体现的是对隐私数据、敏感数据的保护,不容许外界直接访问当前对象的属性数据,而是要通过提供的访问方法进行访问,在方法中添加限制访问条件
封装的操作步骤
我们定义了私有属性就是两个下划线开头的属性
完成封装
def __init__(self, username, password, nickname):
self.__username = username
self.__password = password
self.__nickname = nickname
通过我们提供的set/get方法间接访问
def set_username(self, username):
self.__username = username
def get_username(self):
return self.__username
封装时的注意事项
不提供set/get方法不能正常访问
class Person:
def __init__(self, name):
self.__name = name
p = Person("tom")
print(p.__name)
出错
AttributeError: 'Person' object has no attribute '__name'
私有属性破坏性访问方式:要知道,但是严禁使用
class Person:
def __init__(self, name):
self.__name = name
p = Person("tom")
p.Person__name = "jerry"
print(p.Person__name)
封装后存在的问题和解决方案
关于对象属性的扩展
class Goods:
def __init__(self, name, price):
self.__name = name
self.__price = price
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_price(self, price):
self.__price = price
def get_price(self):
return self.__price
car = Goods("奥迪", 1234556)
print("奥迪的价格是:", car.get_price())
car.__price = 234566
print("car的价格", car.__price, "----", car.get_price())
car.__price = 234566
print("car的价格", car.__price, "----", car.get_price())
这样的扩展方式,破坏了原有 的封装语法,让代码的可读性出现了严重下降
解决方案:在类型中,先使用__slots__定义好,该对象可以出现的属性
class Pet:
"""宠物类型:限制该类型只能出现哪些属性"""
__slots__ = ['__name', '__age', '__gender', '__color']
def __init__(self, name, age, gender, color):
self.__name = name
self.__age = age
面向对象继承的意义【代码冗余,功能扩展】
继承的基本语法
子类继承父类class 类型名称(要继承的类型): 注意:访问属性时~可能会出错
class Person:
"""人的类型"""
def __init__(self, name):
self.name = name
class Men(Person):
"""男人的类型"""
pass
继承的操作步骤。
子类中访问父类的属性: super().方法名称()
子类中访问父类的行为: super().方法名称()
class Child(Person):
def speek(self):
""""子类的行为"""
# 访问父类的属性
print("子类speek中访问父类的属性", super().name)
# 访问父类的行为
super().say()
# 将子类赋值给一个对象
c = Child("tom", 34, "男")
# 运行子类的行为
c.speek()
子类的__init__()方法 1. 如果子类中不写__init__()方法,直接使用父类的__init__()方法初始化数据
class Child(Person):
def __init__(self, name, age, gender):
super().__init__(name, age, gender)
2. 如果子类中写了自己的__init__()方法,一定要调用执行父类的__init__()方法
什么时候子类写自己的__init__()方法,子类中出现独立属性时!
class Child(Person):
def __init__(self, name, age, gender, email, phone):
super().__init__(name, age, gender)
self.email = email
self.phone = phone
子类中的独立属性 父类不可用
# 将子类赋值给一个对象
c = Child("tom", 34, "男", "damu@163.com", "23354657345")
# 运行子类的行为
c.speek()
print(c.email)
p = Person("jerry", 45, "女")
print(p.email)
继承中的方法重写,怎么操作
子类中可以重新定义从父类中继承的方法【方法名称和方法参数一致】:方法重写 方法重写:子类中重写父类中已经存在的方法
在执行过程中~如果子类中重写了方法,执行子类的方法,如果没有重写则执行父类中的方法【运行过程中的多种状态切换:运行时多态】
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def say(self):
print(self.name, "滚去学习")
def play(self):
print(self.name, "混去玩")
def sleep(self):
print(self.name, "滚去说教")
class Child(Person):
def __init__(self, name, age, gender, email, phone):
super().__init__(name, age, gender)
self.email = email
self.phone = phone
def play(self):
print("子类重写")
def speek(self):
""""子类的行为"""
# 访问父类的属性
# print("子类speek中访问父类的属性", super().name)
# 访问父类的行为
super().say()
# 将子类赋值给一个对象
c = Child("tom", 34, "男", "damu@163.com", "23354657345")
# 运行子类的行为
c.speek()
print(c.email)
# 子类重写
c.play()
继承时从父类中默认承认的什么方法
双下划线开头和结尾的方法:类型的魔法方法
运行查询
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("tom", 34)
print(dir(p))
python中的多继承操作语法
多继承的意义:一个对象在不同的场景中,可能扮演不同的角色
多继承的方法查询顺序【python 3|python2经典类】
python3中是横向查询:广度优先
python2中经典类是纵向查询:深度优先
总结两种多态的实现方式
运行时多态
在执行过程中~如果子类中重写了方法,执行子类的方法,如果没有重写则执行父类中的方法【运行过程中的多种状态切换:运行时多态】
设计时多态
class Son:
def xiao_shun(self):
print("百善孝为先")
class Student:
def xue_xi(self):
print("好好学习,天天向上")
class Friend:
def play(self):
print("吃喝玩乐.....")
class Person(Son, Student, Friend):
"""人的类型:继承儿子、学生、朋友"""
pass
p = Person()
# 家庭环境
if isinstance(p, Son):
p.xiao_shun()
# 学习环境中
if isinstance(p, Student):
p.xue_xi()
# 朋友
if isinstance(p, Friend):
p.play()
def xue_tang(person):
# 作为一个学员,在教室要好好学习
if isinstance(person, Student):
# person.play()
person.xue_xi()
多态~和封装以及继承不同的是:多态没有固定的语法,没有固定的思路,只有操作方式
从项目中体现
|