在子类中使用父类的方法,有两种方式:
1.指定类名
2.super()
继承或不继承都能使用,将对象作为参数传递给另一个类中,完成初始化.
class School:school &#61; &#39;xxx&#39;def __init__(self, name, age, gender):self.name &#61; nameself.age &#61; ageself.gender &#61; genderclass Student(School):def __init__(self, name, age, gender, courses):# 指定名称访问School.__init__(self, name, age, gender)# 课程self.courses &#61; courses# 学生信息def stu_info(self):print(&#39;<%s >&#39; % self.courses)# 教师类
class Teacher(School):school &#61; School.schooldef __init__(self, name, age, gender, title):# 指定名称访问School.__init__(self, name, age, gender)# 教什么self.title &#61; title# 老师的信息def Tea_info(self):print(&#39;<%s >&#39; % self.title)stu1 &#61; Student(&#39;kid&#39;, 18, &#39;male&#39;, &#39;python&#39;)
tea1 &#61; Teacher(&#39;xx&#39;, 30, &#39;male&#39;, &#39;python&#39;)
print(stu1.__dict__)
print(tea1.__dict__)
"""
{&#39;name&#39;: &#39;kid&#39;, &#39;age&#39;: 18, &#39;gender&#39;: &#39;male&#39;, &#39;courses&#39;: &#39;python&#39;}
{&#39;name&#39;: &#39;xx&#39;, &#39;age&#39;: 30, &#39;gender&#39;: &#39;male&#39;, &#39;title&#39;: &#39;python&#39;}
"""
调用super()放回一个特殊的对象,该对象专门用来应用父类的属性,依赖继承关系,严格按照mro的顺序查找.Python2中:
super(当前类名, self).__init__( 参数1, 参数2 ···) 完整写法。
Python3中:
super().__init__(参数1, 参数2 ···) 新增MRO,不需要写类名,并且会自动将self参数进行传递.
class School:school &#61; &#39;xxx&#39;def __init__(self, name, age, gender):self.name &#61; nameself.age &#61; ageself.gender &#61; genderclass Student(School):def __init__(self, name, age, gender, courses):# 指定名称访问super().__init__(name, age, gender)# 课程self.courses &#61; courses# 学生信息def stu_info(self):print(&#39;<%s >&#39; % self.courses)# 教师类
class Teacher(School):def __init__(self, name, age, gender, title):# 指定名称访问super().__init__(name, age, gender)# 教什么self.title &#61; title# 老师的信息def Tea_info(self):print(&#39;<%s >&#39; % self.title)stu1 &#61; Student(&#39;kid&#39;, 18, &#39;male&#39;, &#39;python&#39;)
tea1 &#61; Teacher(&#39;xx&#39;, 30, &#39;male&#39;, &#39;python&#39;)
print(stu1.__dict__)
print(tea1.__dict__)
"""
{&#39;name&#39;: &#39;kid&#39;, &#39;age&#39;: 18, &#39;gender&#39;: &#39;male&#39;, &#39;courses&#39;: &#39;python&#39;}
{&#39;name&#39;: &#39;xx&#39;, &#39;age&#39;: 30, &#39;gender&#39;: &#39;male&#39;, &#39;title&#39;: &#39;python&#39;}
"""
# 查找顺序练习
class A:def aaa(self):print(&#39;from - - A - - > aaa&#39;)def test(self):print(&#39;from - - A - - >test&#39;)super().aaa() # super 不会回头 往下 就直接到 B类中, 执行B.aaa() 打印 from - - B - - > aaa 又回到这里print(&#39;AAA&#39;)def aaa(self): # 上面的super() 目前是B 直接到B类去了 没造出来也没法调用,pycharm直接灰色显示print(&#39;from - - test - - > aaa&#39;)class B:def text(self):print(&#39;from - - B - - > test&#39;)def aaa(self):print(&#39;from - - B - - > aaa&#39;)class C(A, B):def aaa(self):print(&#39;from - - c - - > aaa&#39;)obj &#61; C()
print(C.mro())
obj.test()"""
[
from - - A - - >test
from - - B - - > aaa
AAA
"""
在一个类中引用另一个类最为对象的数据,称为类的组合.
解决类与类之间的代码冗余问题:
1.继承: 继承是一种什么是什么的关系,
2.组合: 组合是一组什么有什么的关系.
class A():def __init__(self, x):self.x &#61; xdef func1(self):return self.xclass B():def __init__(self, y):self.y &#61; yobj1 &#61; A(10)
obj2 &#61; B(obj1)print(obj2.y) # <__main__.A object at 0x000002520F3C9240>
print(obj2.y.x) # 10
在类与类存在什么是什么关系的时候使用继承
在类与类存在什么有什么关系的时候使用组合
老师类和学生类继承人类
老师和学生就是人类
# 人类
class People:def __init__(self, name, age, gender):self.name &#61; nameself.age &#61; ageself.gender &#61; genderpass # 其他属性# 学生类
class Student(People):def __init__(self, name, age, gender):super().__init__(name, age, gender)# 老师类
class Teacher(People):def __init__(self, name, age, gender):super().__init__(name, age, gender)pass # 其他属性
现在添加需求:
给老师类和学生类添加课程.
课程包含 课程名称, 课程学习时间
# 人类
class People:def __init__(self, name, age, gender, course_name, study_time):self.name &#61; nameself.age &#61; ageself.gender &#61; genderself.course_name &#61; course_nameself.study_time &#61; study_time# 学生类
class Student(People):def __init__(self, name, age, gender, course_name, study_time):super().__init__(name, age, gender, course_name, study_time)# 老师类
class Teacher(People):def __init__(self, name, age, gender, course_name, study_time):super().__init__(name, age, gender, course_name, study_time)
这个时候学校的来个门卫大爷,守护学校的安危.给他录信息.
# 人类
class People:def __init__(self, name, age, gender, course_name, study_time):self.name &#61; nameself.age &#61; ageself.gender &#61; genderself.course_name &#61; course_nameself.study_time &#61; study_time# 学生类
class Student(People):def __init__(self, name, age, gender, course_name, study_time):super().__init__(name, age, gender, course_name, study_time)# 老师类
class Teacher(People):def __init__(self, name, age, gender, course_name, study_time):super().__init__(name, age, gender, course_name, study_time)# 守门大爷类
class Janitor_uncle(People):def __init__(self, name, age, gender, course_name, study_time):super().__init__(name, age, gender, course_name, study_time)
守门大爷要这不需要这个课程.
而人类中含有课程的属性也不合理.
将课程提出来新建一个课程类.
老师和学生有课程.
# 人类
class People:def __init__(self, name, age, gender):self.name &#61; nameself.age &#61; ageself.gender &#61; gender# 课程类
class Course():def __init__(self, course_name, study_time):self.course_name &#61; course_nameself.study_time &#61; study_time# 学生类
class Student(People):def __init__(self, name, age, gender):super().__init__(name, age, gender)# 老师类
class Teacher(People):def __init__(self, name, age, gender):super().__init__(name, age, gender)# 守门大爷类
class Janitor_uncle(People):def __init__(self, name, age, gender):super().__init__(name, age, gender)# 造学生对象和老师对象
stu1 &#61; Student(&#39;kid&#39;, 18, &#39;male&#39;)
tea1 &#61; Teacher(&#39;qq&#39;, 30, &#39;male&#39;)
jan1 &#61; Janitor_uncle(&#39;xx&#39;, 60, &#39;male&#39;)# 造课程对象
subject &#61; Course(&#39;Python&#39;, &#39;48课时&#39;)# 学学老师绑定课程信息
stu1.course &#61; subject
tea1.course &#61; subject# 查看课程名称
print(stu1.course.course_name) # Python
# 查看课程课时
print(stu1.course.study_time) # 48课时
程序中的多态:指在子类中覆写父类的方法.类中使用多态的目的:
不是用来继承父类的属性和方法的,而是让父类来限制子类的行为.同样的名称的方法在不同的子类中会有不同的的行为,但是它们有相同的特征,可是使用相同的方法来调用它们.
多态的本质是在不同的类中定义相同的方法,
然后在父类中限制子类必须有某个方法,实现某个功能.抽象类就是从一堆类中抽取相似的功能创建一个类作为父类&#xff0c;子类继承父类&#xff0c;子类产生的对象在调用的时候&#xff0c;用法一样&#xff0c;方便使用。抽象类的定义的函数没有实现功能&#xff0c;只是规定了函数名&#xff0c;而且抽象类没法实例化。被抽象的类无法实例化
抽象化的方法在子类中必须要有重名的方法.Python不推崇这样类型.
import abc# metaclass&#61;abc.ABCMeta 抽象类
class Aniaml(metaclass&#61;abc.ABCMeta):&#64;abc.abstractmethod # s抽象化方法def talk(self):pass # 没有函数体直接pass# 继承动物类,
class Cat(Aniaml):passcat &#61; Cat()"""
TypeError: Can&#39;t instantiate abstract class Cat with abstract methods talk
TypeError: 无法用抽象方法实例化抽象类 Cat 谈话
"""
import abc# 抽象类
class Aniaml(metaclass&#61;abc.ABCMeta):&#64;abc.abstractmethod # 抽象化方法def talk(self):pass # 没有函数体直接pass# 动物
class Animal:def talk(self):print(&#39;啊喔&#39;)# 猫
class Cat(Animal):def talk(self):print(&#39;喵喵&#39;)# 狗
class Dog(Animal):def talk(self):print(&#39;汪汪&#39;)# 鸭子
class Duck(Animal):def talk(self):print(&#39;嘎嘎&#39;)# 实例化对象
cat &#61; Cat()
dog &#61; Dog()
duck &#61; Duck()# 调用talk
cat.talk()
dog.talk()
duck.talk()
Python崇尚鸭子类型,如果看书起来像,叫起来也像,走路也像,那它就是鸭子.
将对象的使用方法统一,做一个接口,
调用这个接口函数,传入不同的参数,可以达到不同的功能.
封装一个函数,只要有它内部执行的这个方法即可。它不依赖继承关系&#xff0c;只要这样对象看起来像鸭子&#xff0c;走起来像鸭子就可以把它当作鸭子。
# 动物
class Animal:def talk(self):print(&#39;啊喔&#39;)# 猫
class Cat(Animal):def talk(self):print(&#39;喵喵&#39;)# 狗
class Dog(Animal):def talk(self):print(&#39;汪汪&#39;)# 鸭子
class Duck(Animal):def talk(self):print(&#39;嘎嘎&#39;)# 实例化对象
cat &#61; Cat()
dog &#61; Dog()
duck &#61; Duck()# 定义函数
def talk(obj):obj.talk()# 调用
talk(cat)
talk(dog)
talk(duck)
不继承也没有约束 , 但是你自己要写
只要有相同的类型,那就是同一个类.
# 常用限制class Animal():def speak(self):raise Exception(&#39;必须实现speak方法) class People(Animal):pass
class Pig():pass
class Dog():passdef animal(animal):return animal.speak()obj1 &#61; People()
obj2 &#61; Pig()
obj3 &#61; Dog()animal(obj1)
animal(obj2)
animal(obj3)
Python中的一切皆对象,通过多态实现.
Python3中统一了类与类型的概念。
l &#61; [1, 2, 3] 等同 l &#61; list(1, 2 ,3)
print(type(l))
<clsaa &#39;list&#39;>
l1 .append(4) ---> 将l1传入append() 中
对象调用方法将自己作为第一个参数传递。
list是类,类调用方法&#xff0c;方法绑定给类
l &#61; [1, 2, 3]
list.append(l, 4)
print(l) [1, 2, 3, 4]
print(isinstance(l1, list)) # True 判断某个值是否由某个类创建class AAA():passaaa &#61; AAA()print(isinstance(aaa, AAA)) # True 判断某个值是否由某个类创建
Python中所有的数据都是通过调用类实例化得来,所以一切皆对象.