面向对象的三大特性
简单介绍
封装 :就是将属性和行为书写到类,隐藏属性和实现细节,仅对外提供公共的访问方式。
封装会隐藏对象的属性和行为,仅对外提供访问权限
- 优势:能够提高代码的安全性、复写性
- 弊端:代码量增加(用继承可以缓解这个问题)
继承:多个类中的内容重复性较高时,将重复的内容提炼到一个类中,其他类继承这个类
优势:提高复写性、可维护性
弊端:耦合增强(类与类之前关联过高,父类增加一个成员子类也会增加,但可以使用私有成员缓解这个问题)
多态:同一事物的不同状态(伪多态,java是真多态)
优势:提高可维护性,降低耦合性,高内聚低耦合
高内聚:类独立解决问题的能力
低耦合:类与类之间的关系
一、封装
封装:定义函数的动作叫封装
定义类,这个类中包含属性和方法也叫封装
私有成员:类内的属性和方法定义时前面加上两个下划线
- 私有属性:可以区分 类内外,控制外部对隐藏属性的操作
- 私有方法:可以简化 代码的逻辑,降低代码的复杂性。
私有成员 通过在类内设置对外访问的接口(方法),在类外进行访问。
一般定义函数名' get_xx '方法获取私有属性,定义' set_xx '修改私有属性值。
私有成员 不可被继承。
私有属性案例:
#私房钱案例
class Person:
def __init__(self, name):
self.name = name
self.__money = 1000 #私有属性不可被访问
#获取共有多少钱
def get__money(self):
return self.__money
#存入多少钱
def set_money(self, money):
if not isinstance(money, (int, float)):
print("存入必须是数值")
return
self.__money += money
return self.__money
if __name__ == '__main__':
p=Person("小明")
#print(p.__money) #私有属性不可访问
print(f"配偶看到{p.name}的私房钱有{p.get__money()}") #配偶看到小明的私房钱有1000
p.set_money(500.2)
print(f"又存了一些私房钱,总计:{p.get__money()}元") #又存了一些私房钱,总计:1500.2元
私有方法案例:
#上一个案例中增加了一个私有方法
class Person:
def __init__(self, name):
self.name = name
self.__money = 1000
#判断存入的是否为数值
def __validate_money(self, money):
return isinstance(money, (int,float)) and money > 0 #返回布尔值
def set_Money(self, money):
if self.__validate_money(money): #判断布尔值
self.__money += money #布尔值返回结果为True时执行这行代码
#使用公开方法返回私有属性,这样外部就可以访问到私有属性
def get_Money(self):
return self.__money
if __name__ == '__main__':
p=Person("小明")
#print(p.__money) #不可访问
print(f"配偶看到{p.name}的私房钱有{p.get_Money()}元")
p.set_Money(500)
print(f"又存了一些私房钱,总计:{p.get_Money()}元") #最后调用获取,因为要现存
二、继承
继承:一个类从其他类获取属性和行为
所有的类都继承object类
父类=基类=顶级类=超类;子类=派生类=扩展类
重写:子类继承父类后有独有的需求时,通过使用同名私有成员不同值,进行覆盖父类的改写。
子类重写父类成员后,在子类内部访问父类成员的三种方式:
- 父类名.父类方法名(self)
- super().父类方法名()
- super(子类名.self).父类方法名()
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def teach(self):
print(f"{self.name},1")
class Father(Person):
def teach(self):
super().teach()
print(f"{self.name},3")
class Monther(Person):
def teach(self):
super().teach()
print(f"{self.name},2")
class Child(Father, Monther):
def teach(self):
Father.teach(self)
Monther.teach(self)
print(f"{self.name},4")
if __name__ == '__main__':
# 2:创建对象
c = Child("张三", 18)
c.teach()
# 通过子类名.mro()或者__mro__属性获取继承关系
print(Child.mro())
#输出顺序为123124,原因如图

三、多态(python中只有伪多态)
多态:同一函数 不同对象 得出不同结果
优势:提高代码的 扩展性
条件:
- 继承
- 复写(重写)
- 父类引用指向子类对象(子类对象赋值给父类对象)
class Animal:
def speak(self):
print("voice")
class Dog(Animal):
def speak(self):
print("www")
class Cat(Animal):
def speak(self):
print("mmm")
class Phone(Animal):
def speak(self):
print("lll")
def fun(animal: Animal):
animal.speak()
if __name__ == '__main__':
dog = Dog()
cat = Cat()
phone = Phone()
fun(dog) #www
fun(cat) #mmm
fun(phone) #lll
面向对象的其他特性
一 、对象属性(实例属性)
是每个对象的属性值,是私有的属性。
#定义格式
对象名.属性名=属性值
self.属性名=属性值
#获取格式
对象名.属性名
self.属性名
二、类属性
在类中,函数外的变量。类属性属于该类所有对象的属性,是共享的属性,a改了这个属性值,b调用后得到的是更改后的
#定义格式
属性名=属性值
#调用格式
类名.类属性名
对象名.类属性名
三、类方法与静态方法
共同点:都是共享的方法,都可以使用 '类名.类属性名' 调用
不同点:
#类方法:需要至少一个参数,一般用cls(class)
@classmethod
def 类方法名(cls)
#静态方法:没有参数,不需要传参
@staticmethod
def 类方法名()
#演示案例
class Student(object):
teacher_name="张三"
@classmethod
def method1(cls):
print(cls.teacher_name)
@staticmethod
def method2():
print(Student.teacher_name)
if __name__ == '__main__':
Student.method1() #类名.类属性名 调用 #张三
Student.method2() #张三
8936




被折叠的 条评论
为什么被折叠?



