继承:
面向对象的第二大特征:
继承:如果两个或者两个以上的类具有共同的属性以及方法,我们可以将共同的部分抽取
出来,在抽取的类中声明公共的部分。
被抽取出来的类–父类,超类,基类
其他类-- 子类,派生类
他们之间的关系–子类继承自父类
注意:如一个类没有继承其他任何类的情况下,默认继承object类,
object类是一切类的基类。
注意:当继承的类为object类的情况下,可以省略。
class 类名():
类名
():继承的父类,当父类object的时候,object可以省略,甚至()都可以一起省略。
class Person():
pass
class Person:
pass
class Person(object):
pass
单继承:
简单来说:就是一个子类只有一个父类,这时候我们可以称之为单继承。
继承的优点:
可以直接使用父类未私有化的属性以及方法。
当子类与父类存在相同的方法的时候,优先调用子类中方法。
class Animal:
def __init__(self,name,age,sex="公"):
self.name = name
self.age = age
self.__sex = sex
@property
def sex(self):
return self.__sex
@sex.setter
def sex(self,sex):
self.__sex = sex
def eat(self,food):
print("吃%s"%food)
def run(self):
print("run....")
class Dog(Animal):
pass
def run(self):
print(“dog run…”)
if name == ‘main’:
dog = Dog(“金毛”,2)
print(dog.name)
dog.eat(“狗粮”)
print(dog.sex)
dog.sex = “母”
dog.run()
需求:
父类:
人类:
定义学生类
特征:姓名 性别 年龄 学号 班级 分数
行为:吃饭 睡觉 学习
定义老师类
特征:姓名 性别 年龄 工号 学科
行为:吃饭 睡觉 授课
注意:当子类中含有特殊属性的时候,在子类我们需要将__init__进行重写,
同时,子类中所有的属性的我们都需要进行声明,并且在子类的__init__方法
中需要手动调用父类中__init__.
使用super()来进行调用。
当子类中没有特殊属性的时候,我们无需在子类中重写__init__方法,这时候
它会自动去调用父类中的__init__方法。
总结:
1.object类是一切类的基类
2.子类的对象可以直接使用父类中未私有化的属性以及方法
3.父类不能访问子类中特有的属性以及方法
4.子类中特有的方法直接在子类中进行声明,在子类声明特有的属性的时候,
我们还需要将父类中需要的参数也要进行声明,绑定的时候,子类特有的属性绑定给
self,父类中存在的属性通过super(),调用父类中__init__方法传递进去。
调用父类中的方法
super().init(name,age,sex)
优点:
1.简化代码,减少冗余
2.提高代码的维护性
3.提高代码的安全性
缺点:
增大代码的耦合度。
需求:
父类:
人类:
特征:姓名 性别 年龄
行为:吃饭 睡觉
定义学生类
特征:姓名 性别 年龄 学号 班级 分数
行为:吃饭 睡觉 学习
定义老师类
特征:姓名 性别 年龄 工号 学科
行为:吃饭 睡觉 授课
class Person:
def __init__(self,name,age,sex):
print("父类中的构造函数被调用啦")
self.name = name
self.age = age
self.sex = sex
def eat(self):
print("吃饭。。。")
def sleep(self):
print("睡觉。。。")
class Student(Person):
def __init__(self,name,age,sex,stuId,classId,score):
print("子类中的构造函数被调用啦")
self.stuId = stuId
self.classId = classId
self.score = score
# 调用父类中的方法
# super().__init__(name,age,sex)
# 调用父类中init方法
Person.__init__(self,name,age,sex)
def study(self):
print("敲代码。。。。")
if name == ‘main’:
stu = Student(“lili”,18,“girl”,“1903001”,“1903”,80)
print(stu.classId)
stu.eat()
print(stu.name)
# per = Person(“lilei”,20,“boy”)
# print(per.classId)
多继承:一个子类有多个父类的情况下,我们称之为多继承。
比如一个孩子有一个爸爸有一个妈妈
多继承:
class 类名(父类1,父类2,…):
类体
注意:一个子类可以继承多个父类,父类与父类直接使用逗号隔开。
当父类中出现相同的函数的时候,优先选择写在继承列表中前面的那个。
当初始化子类的时候,若父类中存在不同的属性,
这时候初始化的时候需要分开来进行初始化处理。
类名.init(self,参数列表)
总结:
1.一个子类可以继承多个父类中未私有化属性以及方法
2.一个子类可以有多个父类
3.一个父类可以有多个子类
在python中子类与父类是多对多的关系。
class Father:
def __init__(self,name,money):
self.name = name
self.money = money
def makemoney(self):
print("赚钱。。。。")
def sing(self):
print("娘子,啊哈。。。。")
class Mother:
def __init__(self,name,facevalue):
self.name = name
self.facevalue = facevalue
def spendmoney(self):
print("花钱。。。。")
def sing(self):
print("分手快乐。。。。")
class Child(Mother,Father):
def __init__(self,name,moeny,facevalue):
Father.__init__(self,name,moeny)
Mother.__init__(self,name,facevalue)
if name == ‘main’:
child = Child(“明明”,10000000000,98)
print(child.name)
print(child.money)
print(child.facevalue)
child.makemoney()
child.spendmoney()
child.sing()
鸭子模型:
面向对象三大特征:封装,继承,多态
其实在python中是不存在真正的多态的,原因是python动态数据类型的语言。
python的多态我们一般称它为鸭子模型。
鸭子模型定义:如果有一只鸟,走路像鸭子,叫声像鸭子,那么我们就可以称这只鸟
叫做鸭子。
鸭子模型的意思:不关心数据的类型,只关心的数据的使用。
多态:一类事物的多种表现形态,多态是依赖于继承而存在的。
1.序列有多种表现形态:字符串,列表,元组
2.动物有多种形态:猫,狗
在继承的关系中如果一个子类的实例的数据类型看做是当前子类,
那么它的数据类型也可以被认为是父类。
isinstance(o,t)
功能:对象是否隶属于某种类型
isinstance(o,tuple1)
功能:判断对象是否是某种数据类型中的一种
type(object)
功能:获取对象的类型
dir(object)
功能:查看当前对象身上所有的属性以及方法。
class Animal():
def __init__(self,name):
self.name = name
@staticmethod
def run(ani):
print("%s跑..."%ani.name)
class Dog(Animal):
pass
class Cat(Animal):
pass
class Person():
def init(self,name):
self.name = name
if name == ‘main’:
dog = Dog(“jerry”)
Animal.run(dog)
cat = Cat(“bob”)
print(isinstance(dog,Animal))
print(isinstance(dog,Dog))
per = Person("Tom")
# Animal.run(per)
print(isinstance(per,(Animal,Dog)))
print(dir(dog))
# print(dog)
重写__str__函数
str() 函数在使用print打印对象的时候会自动的被调用,
str()返回的结果就是我们打印对象的时候出现内容。
repr()函数是给python解释器准备的,当在终端敲变量名回车的时候
会自动调用此函数。
若在class中存在__repr__并且不存在__str__的时候我们可以使用
str = __repr__这种方式来赋值。
class Person:
def init(self,name,age):
self.name = name
self.age = age
# def __str__(self):
# return "%s-%d"%(self.name,self.age)
def __repr__(self):
return "%s-%d"%(self.name,self.age)
__str__ = __repr__
if name == ‘main’:
per = Person(“lili”,18)
print(per)
per2 = Person(“lilei”,20)
print(per2-per)
运算符重载:
class Person:
def init(self,name,age):
self.name = name
self.age = age
def __add__(self, other):
return Person(self.name,self.age + other.age)
def __str__(self):
return "%s-%d"%(self.name,self.age)
if name == ‘main’:
per1 = Person(“lili”,18)
per2 = Person(“lilei”,20)
per3 = Person(“lilei”,20)
print(per1+per2+per3)
list1 = [1,2,3]
list2 = [2,3,4]
print(list1+list2)
dict1 = {1:1,2:2}
dict2 = {2:2,3:3}
print(dict1+dict2)
需求:自定义一个dict类型,完成dict与dict相加。
完成相减的功能,相减要求返回相同的key并且value也相同。
class mydict(dict):
def __add__(self, other):
res = self.copy()
for k,v in other.items():
res[k] = v
return res
def __sub__(self, other):
res = {}
for k in self:
if k in other and self.get(k) == other.get(k):
res[k] = self.get(k)
return res
if name == ‘main’:
# dict1 = {}
# dict2 = dict()
md1 = mydict({1:1,2:2,3:3})
md2 = mydict({4:1,2:2,3:5})
print(md1+md2)
print(md1)
print(md1-md2)
单例模式:每次创建要求创建同一个对象。
观察者模式,工厂模式
class Person():
instance = None
def __new__(cls, *args, **kwargs):
# print("new函数被调用啦")
if cls.instance == None:
cls.instance = super(Person,cls).__new__(cls, *args, **kwargs)
return cls.instance
def __init__(self):
print("init函数被调用啦")
pass
if name == ‘main’:
per1 = Person()
per2 = Person()
per3 = Person()
per4 = Person()
print(id(per1))
print(id(per2))
print(id(per3))
print(id(per4))