面向对象的三大特征:封装、继承、多态
继承:子类继承父类,子类可以使用父类的属性和方法,简化代码.
当生成子类对象时,先初始化父类对象,所以如果父类有__init__()方法,并且有属性时,要通过子类的构造赋值
一个类可以有多个子类
在子类中,调用父类的属性时,在__init__()方法中使用
class Person: def __init__(self,name=None,age=None,sex=None): self.name=name self.age=age self.sex=sex def __str__(self): return "我的姓名:{0},我的年龄:{1},我的性别:{2}".format(self.name,self.age,self.sex) #继承父类 class Student(Person): def __init__(self,name=None,age=None,sex=None,score=None): # self.name = name # Person.name=name # self.age = age # self.sex = sex # Person.__init__(self,name,age,sex) super(Student, self).__init__(name,age,sex) self.score=score def __str__(self): return"我的姓名:{0},我的年龄:{1},我的性别:{2},成绩{3}".format(self.name,self.age,self.sex,self.score) stu=Student("Mary",21,'female',80) print(stu)
运行结果:
我的姓名:Mary,我的年龄:21,我的性别:female,成绩80
给父类传参的四种方式:
父类.属性,或self.属性或父类.__init__(self,参数)或super(父类,self).__init__(参数)四种方法
调用父类方法时:super().父类方法()
当子类继承父类时,子类的构造方法应该包含父类和子类共同的属性,在子类的初始化方法中,将父类的属性传递给父类,子类的属性赋值给子类
方法重写:子类和父类同名但参数列表不同,子类重写了父类的方法,当生成子类对象时,调用的是子类重写的方法
如果子类重写的方法想调用父类的方法时,在子类方法中:父类.方法(self)或super().父类方法()
三代继承:子类初始化方法需要祖父类、父类及自己的属性,可以调用父类的初始化方法传参,可重写父类的方法
构造的顺序:祖父类、父类,本类
class Person: def __init__(self,name=None,age=None,sex=None): print("------person") self.name=name self.age=age self.sex=sex def __str__(self): return "我的姓名:{0},我的年龄:{1},我的性别:{2}".format(self.name,self.age,self.sex) class Music: def __init__(self,piano=None): print("-------music") self.piano=piano class Student(Person,Music): def __init__(self,name=None,age=None,sex=None,score=None,piano=None): print("------student") #给父类传参四种方式————————方式一: # Person.name=name #方式二: # Person.__init__(self,name,age,sex,score) #方式三: #self.age=age #self.sex=sex #方式四: super(Student,self).__init__(name,age,sex) self.score=score self.piano=piano def __str__(self): return "我的姓名:{0},我的年龄:{1},我的性别:{2},我的成绩:{3},我喜欢:{4}".format(self.name,self.age,self.sex,self.score,self.piano) stu=Student("Mary",23,"女",88,"钢琴") print(stu)
类继承object
私有属性、私有方法:均不能在类外面被调用
两个下划线开头,声明该方法为私有方法,只能在类的内部调用,不能在类地外部调用。
单例模式:
要点:一是某个类只能有一个实例
二是它必须自行创建这个实例
三是它必须自行向整个系统提供这个实例
class SingleTone: __isinstance=None def __new__(cls): if cls.__isinstance==None: cls.__isinstance=object.__new__(cls) return cls.__isinstance else: return cls.__isinstance s=SingleTone() ss=SingleTone() print(id(s),id(ss))
运行结果:
91371440 91371440
对象列表排序:重写lt或gt方法
class Car: def __init__(self,brand=None,price=None): self.brand=brand self.price=price def __gt__(self,other): #支持中文排序:用encode()进行编码 return self.brand.encode("gbk")<other.brand.encode("gbk") #return self.price<other.price def __str__(self): return self.brand+str(self.price) lists=[Car("英菲尼迪",300000),Car("奥迪",350000),Car("奔驰",400000)] lists.sort() for i in lists: print(i)
多态
多态(从定义角度触发):同一类事物的多种形态。一个抽象类有多个子类,因而多态的概念依赖于继承
多态性(从使用角度触发):同一种调用方式,不同的执行效果。
class Animal:
def run(self):
raise AttributeError('子类必须实现这个方法')
class People(Animal):
def run(self):
print('the people is running')
class Pig(Animal):
def run(self):
print('pig is walking')
class Dog(Animal):
def run(self):
print('dog is running')
peo1=People()
pig1=Pig()
d1=Dog()
#实例化调用方法得到的结果
#peo1.run()
#pig1.run()
#d1.run()
#多态性:一种调用方式,不同的执行效果(多态性)
# 多态性依赖于:继承
##多态性:定义统一的接口,
def func(obj): #obj这个参数没有类型限制,可以传入不同类型的值
obj.run() #调用的逻辑都一样,执行的结果却不一样
func(peo1)
func(pig1)
func(d1)