- 继承 : 提高代码的重用性,规范代码(要就继承父类的子类都实现相同的方法:抽象类、接口)
- 当你开始编写两个类的时候,出现了重复的代码,通过继承来简化代码,把重复的代码放在父类中
- 单继承
- 重用性 :减少代码的重复,子类可以复用父类的方法
- 派生 :子类在父类的基础上又创建了自己的新的方法和属性
- 子类中有父类的同名方法 : 只用子类的
- 还希望用到父类中的方法 : 父类名、super调用
- 抽象类 :只能被继承 不能被实例化 模板、规则
- 单继承
from abc import ABCMeta,abstractmethod
class A(metaclass=ABCMeta):
@abstractmethod
def func(self):pass
-
多继承 python / c++
- java/c#没有
- 每个类中有每个类能完成的方法
创建子类的时候只需要挑选和我相符合的父类来继承就能够完成父类的功能了
接口 :java中的一种数据类型
-
经典类和新式类的区别:
- 经典类 不主动继承object、没有mro方法、没有super、继承的时候 深度优先
- 新式类 主动继承object、有mro方法、有super、继承的时候 广度优先
-
方法和函数的区别
- 只有被对象调用的类中的方法才能被成为一个方法
class A:
def func(self):pass
a = A()
print(a.func)
print(A.func)
from types import MethodType,FunctionType
print(isinstance(a.func,MethodType))
print(isinstance(a.func,FunctionType))
print(isinstance(A.func,FunctionType))
print(isinstance(A.func,MethodType))
初始化函数 __init__
构造函数 __new__
class User:
def __init__(self,name,pwd):
self.name = name
self.pwd = pwd
class Account:
def __init__(self):
self.user_list = []
def login(self):
username = input('username : ')
password = input('password : ')
for usr in self.user_list:
if usr.name == username and usr.pwd == password:
print('登录成功')
return True
def register(self):
username = input('username : ')
password = input('password : ')
usr = User(username,password)
self.user_list.append(usr)
def run(self):
for i in range(2):
self.register()
for i in range(3):
if self.login():
break
else:
print('登录失败')
obj = Account()
obj.run()
多态
1
- 什么是多态
- 多态性是指在不考虑实例类型的情况下使用实例
- 一个类表现出的多种状态 : 通过继承来实现的
- 在python中:函数的参数不需要指定数据类型,所以我们也不需要通过继承的形式来统一一组类的类型,
换句话说 所有的对象其实都是object类型,所以在python当中其实处处是多态
2
- 鸭子类型
- Python崇尚鸭子类型
- 如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子
def len(obj)
len() # str list tuple dict set range(3)
print() # 所有的对象都是鸭子类型
不是明确的通过继承实现的多态
而是通过一个模糊的概念来判断这个函数能不能接受这个类型的参数
3
封装
- 广义上的封装 :对象只能调用自己类的属性和方法
- 广义上的封装 :把属性函数都放到类里
- 狭义上的封装 :定义私有成员
class 类名:
def 方法1(self):pass
是为了只有这个类的对象才能使用定义在类中的方法
- 仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问
- 封装的真谛在于明确地区分内外,封装的属性可以直接在内部使用,而不能被外部直接使用
- 外部要想用类隐藏的属性,需要我们为其开辟接口
把一个名字藏在类中
- 在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
#正常情况
>>> class A:
... def fa(self):
... print('from A')
... def test(self):
... self.fa()
...
>>> class B(A):
... def fa(self):
... print('from B')
...
>>> b=B()
>>> b.test()
from B
#把fa定义成私有的,即__fa
>>> class A:
... def __fa(self): #在定义时就变形为_A__fa
... print('from A')
... def test(self):
... self.__fa() #只会与自己所在的类为准,即调用_A__fa
...
>>> class B(A):
... def __fa(self):
... print('from B')
...
>>> b=B()
>>> b.test()
from A
- 封装方法
- 目的:是隔离复杂度
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()
a=ATM()
a.withdraw()
私有变量不能被继承,不能在外部定义
-
类中的私有成员:
- 私有的静态属性
- 私有的对象属性
- 私有的方法
-
我为什么要定义一个私有变量呢:
- 我不想让你看到这个值
- 我不想让你修改这个值
- 我想让你在修改这个值得时候有一些限制,保证了数据的安全
- 有些方法或者属性不希望被子类继承
property是一个装饰器函数 ---># 将一个方法伪装成一个属性
装饰器的分类:
装饰函数
装饰方法 : property
装饰类
class Student:
def __init__(self,name,age):
self.__name = name
self.age = age
@property # 将一个方法伪装成一个属性
def name(self):
return self.__name
a = Student('诸葛',20)
print(a.name)
-
判断是函数还是方法
from types import FunctionType,MethodType
property
一个方法被伪装成属性之后
应该可以执行一个属性的增删改查操作
那么增加和修改 就对应这被setter装饰的方法 :这个方法又一个必传的参数new,表示赋值的时候等号后面的值
删除一个属性 对应着 被deleter装饰的方法,这个方法并不能在执行的时候真的删除这个属性,而是你在代码中
执行什么就有什么效果
class Goods:
__discount = 0.8
def __init__(self,price):
self.__price = price
self.name = 'apple'
@property
def price(self):
return self.__price * Goods.__discount
@price.setter
def price(self,new):
self.__price = new #改变私有对象属性的值
@price.deleter #删除私有对象属性
def price(self):
del self.__price
apple = Goods(10) #实例化
print(apple.price)
print(apple.__dict__)
del apple.price
apple.price = 8 #改变私有对象属性
print(apple.price)
print(apple.__dict__)
del apple.name #删除
print(apple.__dict__)
运行结果
8.0
{'_Goods__price': 10, 'name': 'apple'}
6.4
{'name': 'apple', '_Goods__price': 8}
{'_Goods__price': 8}
Process finished with exit code 0
- @classmethod 类方法
- 类方法的特点
- 只使用类中的资源,且这个资源可以直接用类名引用的使用,那这个方法应该被改为一个类方法
class Goods:
__discount = 0.8 # 静态属性
def __init__(self,price):
self.__price = price # 对象属性
self.name = 'apple'
@property
def price(self):
print(self)
return self.__price * Goods.__discount
@classmethod
def change_discount(cls,new): # 类方法
cls.__discount = new
- @staticmethod 静态方法
class Student:
@staticmethod
def login(usr,pwd):
print('IN LOGIN',usr,pwd)
Student.login('user','pwd')
- 在类中:
- 静态属性 类 所有的对象都统一拥有的属性
- 类方法 类 如果这个方法涉及到操作静态属性、类方法、静态方法 cls 表示类
- 静态方法 类 普通方法,不使用类中的命名空间也不使用对象的命名空间 : 一个普通的函数 没有默认参数
- 方法 对象 self 表示对象
- property方法 对象