目录
把现实世界中的主体中的属性和方法书写到类的里面的操作,这种操作称为封装
- class Person():
- # 封装属性
- # 封装方法
注意:
封装可以为属性和方法添加私有权限
属性和方法分类 ---
公有(属性、方法):无论在类的内部还是外部都可以对属性和方法进行操作
私有(属性、方法):外部直接应用或修改类内部的数据不安全,所以不允许在类的外部对类内部的属性和方法进行操作 --- 通过封装私有属性或方法实现
方法 --- 在属性名或方法名前面增加两个下划线
例:
- class Girl():
- def __init__(self, name):
- self.name = name
- self.__age = 18 # 私有属性
-
-
- fangfang = Girl('方方')
- print(fangfang.name)
- print(fangfang.__age) # 报错 无法访问
注意:
以上代码运行可知,私有属性不能在类的外部访问,若需要在外部访问私有属性可以通过定义访问接口(函数)来实现
类中的私有属性和方法不能被类继承
Python中一般定义函数名为‘get_xx’都是用来获取私有属性,通过‘set_xxx’来修改私有属性
例:
- class Girl():
- def __init__(self, name):
- self.name = name
- self.__age = 18 # 私有属性
-
- def get_age(self): # 用于引用访问属性
- # 本人访问时直接访问
- # 外人访问时加上限制条件
- return self.__age
-
- def set_age(self, age): # 用于修改属性
- self.__age = age
-
-
- fangfang = Girl('方方')
- fangfang.set_age(19)
-
- print(fangfang.name)
-
- print(fangfang.get_age())
定义方式与私有属性基本一致,在方法名前面增加两个下划线 _ _ 方法名()
封装数据属性 --- 明确区分内外,控制外部对隐藏的属性进行操作
例:
- class People():
- def __init__(self, name, age):
- self.__name = name
- self.__age = age
-
- def tell_info(self):
- print('Name:<%s> Age:<%s>' % (self.__name, self.__age))
-
- def set_info(self, name, age):
- if not isinstance(name, str): # isinstance()判断name是否为字符串
- print('名字必须为字符串类型')
- return
- if not isinstance(age, int): # 判断age是否为整数型
- print('年龄必须为数字')
- self.__name = name
- self.__age = age
-
-
- p = People('jack', 18)
- p.tell_info()
-
- p.set_info('andy', 10)
- p.tell_info()
-
- p.set_info(123, 19)
- p.tell_info()
-
- 结果:
- Name:
Age:<18> - Name:
Age:<10> - 名字必须为字符串类型
- Name:
Age:<10>
封装方法的意义 --- 降低程序复杂度
- class Atm:
- def __card(self):
- print('请插卡')
-
- def __auth(self):
- print('用户认证')
-
- def __input(self):
- print('请输入取款金额:')
-
- def __print_bill(self):
- print('打印账单')
-
- def __take_money(self):
- print('取款')
-
- def withdraw(self): # 定义一个对外提供服务的公共方法
- self.__card()
- self.__auth()
- self.__input()
- self.__print_bill()
- self.__take_money()
-
-
- atm = Atm()
- atm.withdraw()
作用 --- 通过@property装饰器讲一个方法转为属性,从而实现用于计算的属性,转换后可以通过方法名来访问,不需要小括号,代码更简洁
格式 ---
- @property
- def 方法名(self):
- 方法体
方法名要求小写,最后作为属性名存在
方法体中一般return结束
例
- class Rect():
- def __init__(self, width, height):
- self.width = width
- self.height = height
-
- @property
- def area(self):
- return self.width * self.height
-
-
- rect = Rect(600, 800)
- print('面积为:', rect.area) # 调用时方法名变为属性,不需要小括号
类是用来描述现实世界中同一组事物的共有性的抽象模型
类也有上下级和范围之分,如:生物->动物->不如动物->灵长类动物->人类->黄种人
描述共性和个性之间的关系
继承 --- 一个类从另一个已有的类获得其他成员的相关特性,称为继承
派生 -- 从一个已有的类产生一个新的类,称为派生
注意:
继承和派生其实是从不同角度方向来描述相同的概念,本质上为一个东西
父类 --- 也称为基类,就是指已有被继承的类
子类 --- 也称为派生类和扩展类
扩展 --- 在子类中增加一些自己特有的特性,称为扩展,没有扩展则继承无意义
单继承 --- 一个类只能继承自一个其他的类,不能继承多个其他类。使用较多
多继承 --- 一个类共同继承了多个父类
假设A类要继承B类中的所有属性和方法(私有除外)
- class B(object):
- pass
-
-
- class A(B): # A继承B
- pass
-
- a = A()
例:Person类与Teacher、Student类之间的继承
- class Person(object):
- def eat(self):
- print('i an eat food !')
-
- def speak(self):
- print('i can speak !')
-
-
- class Teacher(Person): # 继承Person类
- pass
-
-
- class Student(Person):
- pass
-
-
- teacher1 = Teacher()
- teacher1.eat()
- teacher1.speak()
-
- student1 = Student()
- student1.eat()
- student1.speak()
单继承 --- 一个类能继承自一个其他类,不能多继承
格式 ---
- 1.定义一个父类
- class Person(object):
- pass
-
- 2.定义一个子类
- class Teacher(Person):
- pass
类object --- 类object是所有类的父类,在该类中定义了所有类的公有默认方法,如:new( )、 init( ),当定义类时,只有类名没有继承相关参数,此时可以省略object
单继承 --- 具有传递性 如:A类继承B类,B类继承C类,根据传递性,A类也就会自动继承C类中的所有公共属性和方法。
定义 --- Python少数几个支持多继承的语言,允许一个类继承多个类
格式 ---
- class B(object):
- pass
-
- class C(object):
- pass
-
- class A(B,C):
- pass
例:
- class GasolineCar(object): # 汽油车
- def run_with_gasoline(self):
- print('I can with gasoline')
-
-
- class EletriCar(object): # 电动车
- def run_with_eletric(self):
- print('I can with eletric')
-
-
- class HybridCar(GasolineCar, EletriCar):
- pass
-
-
- tesla = HybridCar()
- tesla.run_with_eletric()
- tesla.run_with_gasoline()
-
注意:
尽量少用多进程,容易造成名称冲突
扩展特性 --- 继承让子类拥有了父类的所有公共属性和方法,但如果仅仅是为了继承属性和方法就失去了继承的意义,应该子类拥有自己的属性和方法
重写 --- 也叫做覆盖,子类成员与父类成员名字相同时,从父类继承的成员会重新定义,此时起效的为子类中定义的成员
注意:
类方法的调用顺序 --- 先在子类中查找,若找不到则在父类中查找
super()--- 调用父类属性和方法
完整的写法:
super(当前类名称,self).属性或方法()
Python3版本以后
- super().属性
- # 或
- super()方法名()
例:Car
- class Car(object):
- def __init__(self, brand, model, color):
- self.brand = brand
- self.model = model
- self.color = color
-
- def run(self):
- print('I can run')
-
-
- class GasolineCar(Car): # 继承Car类
- def __init__(self, brand, model, color):
- super().__init__(brand, model, color) # 调用父类Car的__init__()方法
-
- def run_with_gasoline(self):
- print('I can with gasoline')
-
-
- class EletriCar(Car): # 电动车父类
- def __init__(self, brand, model, color):
- super().__init__(brand, model, color)
- self.battery = 70
-
- def run(self):
- print(f'I can run with eetric,remain:{self.battery}')
-
-
- bmw = GasolineCar('宝马', 'x5', '白色')
- bmw.run()
-
- tesla = EletriCar('特斯拉', 'Model S', '黑色')
- tesla.run()
MRO属性或方法
作用 --- 获得类的层次结构
格式 ---
- 类名.__mro_ _
- #或
- 类名.mro()
例:上述Car的例子
- class Car(object):
- def __init__(self, brand, model, color):
- self.brand = brand
- self.model = model
- self.color = color
-
- def run(self):
- print('I can run')
-
-
- class GasolineCar(Car): # 继承Car类
- def __init__(self, brand, model, color):
- super().__init__(brand, model, color) # 调用父类Car的__init__()方法
-
- def run_with_gasoline(self):
- print('I can with gasoline')
-
-
- class EletriCar(Car): # 电动车父类
- def __init__(self, brand, model, color):
- super().__init__(brand, model, color)
- self.battery = 70
-
- def run(self):
- print(f'I can run with eetric,remain:{self.battery}')
-
- print(EletriCar.__mro__) # 查看集成化层次结构
- print(EletriCar.mro())
-
- 结果:
- (<class '__main__.EletriCar'>, <class '__main__.Car'>, <class 'object'>)
- [<class '__main__.EletriCar'>, <class '__main__.Car'>, <class 'object'>]
指事物的多种状态,是一种适用对象的放射式,子类重写了父类方法,调用不同子类对象时的相同父类方法,可以产生不同的执行结果。
多态依赖于继承
子类方法必须重写父类方法
过程 --- 首先定义一个父类,其可能拥有多个子类对象,当调用一个公共方法时,传递的对象不同则返回结果不同
公共接口 --- 是多态的体现,随着传入参数不同,返回结果不同
- class Fruit(object):
- # 公共方法
- def makejuice(self):
- print('I can make juice')
-
-
- class Apple(Fruit):
- def makejuice(self):
- print('I can make apple juice')
-
-
- class Banana(Fruit):
- def makejuice(self):
- print('I can make banana juice')
-
-
- class Orange(Fruit):
- def makejuice(self):
- print('I can make orange juice')
-
-
- class Peach(Fruit):
- def makejuice(self):
- print('I can make peach juice')
-
-
- # 定义公共接口,相当于上述类的进入接口
-
- def servce(obj):
- obj.makejuice()
-
-
- apple = Apple()
- banana = Banana()
- orange = Orange()
- peach = Peach()
-
- for i in (apple, banana, orange, peach):
- servce(i)
-
- 结果:
- I can make apple juice
- I can make banana juice
- I can make orange juice
- I can make peach juice
调用灵活,有了多态,更容易编写通用代码,实现通用的编程,适应不同变化需求