面向对象 二

2021-03-01  本文已影响0人  吃可爱长大鸭

目录

1.继承的使用
2.继承的好处
3.派生
4.字类访问父类的方法
5.存在继承关系后的属性查找顺序
6.存在多个父类时的查找顺序
7.经典类与新式类
8.super获取父类内容时,按照mor列表
9.覆盖

1.继承的使用

#  在子类中 类名后面加上括号,些上父类的名称即可,
#  在python中一个子类可以有多个父类,多个父类在括号中用逗号隔开,
这一点在其他语言中是不支持的
class Parent:
    year = 2018

    def coding(self):
        print("正在编程........")

class Sub(Parent):
    pass

print(Parent.year)

print(Sub.year)

# Sub.coding()


s = Sub()
print(s.year) # 子类可以使用父类中的属性
s.coding() # 子类也可以父类中的函数

2.继承的好处

# 案例一
class Student:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def study(self):
        print("正在学习....")

    def eat(self):
        print("正在吃饭.....")


stu1 = Student("张三",20,"man")
stu1.eat()
stu1.study()


class Teacher(Student):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("正在吃饭....")

    def study(self):
        print("正在学习....")
    pass

# 案例二
class Person:
    def __init__(self ,name ,age ,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print("正在吃饭....")

    def study(self):
        print("正在学习....")

class Teacher(Person):

    def teaching(self):
        print("老师正在上课......")

t1 = Teacher("blex" ,30 ,"woman")
t1.eat()
t1.study()


class Student(Person):
    pass

stu1 = Student("张三" ,20 ,"man")
stu1.eat()
stu1.study()

# stu1.teaching()

# 学生继承了老师 减少了重复代码,但是继承到一些学生不应该有的内容
# 正确姿势:抽取公共的父类  抽象
# 抽象是 抽取多个类中相同的部分形成另一个类



# 通过继承 避免了重复代码的编写
# 通过抽象 避免了继承到一些不应该有的内容
# 应该先抽象再继承
# 再抽取过程中 可能会一些跟业务需求无关的类,这是正常的 这些称之为公共父类
# 公共父类的作用是存储多个子类相同属性和技能

3.派生

"""
    派生
    什么是派生
    派生指的是 子类继承某个父类 并且拥有自己独特的属性或技能   该子类称之为派生类
    # 只要子类中出现了任何新内容,它就是一个派生类

"""

class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))


# Test不能称为派生类 , 因为没与任何独特的内容与父类完全一致
class Test(Person):
    pass

# 派生类属于子类吗?   派生类一定是某个子类
# Student类就成为 Person类的派生类


class Student(Person):
    def __init__(self,name,age,sex,number):
        self.name = name
        self.age = age
        self.sex = sex
        self.number = number

    # 上课
    def up_class(self):
        print("%s 正在上课.....")

4. 字类访问父类的方法

# 案例一
class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
        print(self)

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))


class Student(Person):
    def __init__(self,name,age,sex,number):
        # self.name = name
        # self.age = age
        # self.sex = sex
        #上述代码与父类中完全相同
        Person.__init__(self,name,age,sex)
        self.number = number
    # 上课
    def up_class(self):
        print("%s 正在上课.....")

    def sayHI(self):
        # print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))
        # 访问父类中的方法来简化代码
        # 指名道姓
        # Person.sayHI(self)
        super().sayHI()
        print("学号:",self.number)

stu1 = Student("阿三",20,"woman","9527")
# print(stu1)
# print(stu1.name,stu1.age,stu1.sex)
stu1.sayHI()

# super一定用在 存在继承关系的子类中

# 案例二
class Person:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex
        print(self)

    def sayHI(self):
        print("hello 我是%s 今年%s岁 性别:%s" % (self.name,self.age,self.sex))

class Student(Person):
    def __init__(self,name,age,sex,number):
        # self.name = name
        # self.age = age
        # self.sex = sex
        # 子类中重用父类种方法的方式2
        # super() # 表示创建一个特殊的对象 用于调用父类的方法
        # super().__init__(name,age,sex)
        # 了解:在python2中 super的使用方式有所不同 需要传入当前类,当前对象
        super(Student,self).__init__(name,age,sex)
        self.number = number

    # 上课
    def up_class(self):
        print("%s 正在上课.....")

stu1 = Student("阿三",20,"woman","9527")
print(stu1)
print(stu1.name,stu1.age,stu1.sex)

5.存在继承关系后的属性查找顺序

class S:
    age = 17

    def f1(self):
        print("S f1")

class A(S):
    # age = 18
    # def f1(self):
    #     print("A f1")
    pass
class B(A):
    # age = 19
    # def f1(self):
    #     print("B f1")
    pass
b = B()
# b.age = 20

print(b.age)

print(b.__dict__)
print(B.__dict__)
print(A.__dict__)

# 对象 -> 类 ->父类 ->父类的父类.....
# 优先找对象 如歌对象没有 则找类,如果类没有,会沿着继承关系一直找到最顶层的父类
# 无论是属性还是方法 查找顺序是一样的
b2 = B()
b2.f1()

6.存在多个父类时的查找顺序

# 1.按照继承的顺序 先继承谁就先找谁


class S:
    a = 100

class A(S):
    # a = 1
    pass
class B(S):
    # a = 2
    pass
class C(S):
    # a = 3
    pass
class D(A):
    # a = 4
    pass
class E(B):
    # a = 5
    pass
class F(C):
    # a = 6
    pass
class G(D,E,F):
    pass


g1 = G()
print(g1.a)
print(G.mro())

"""
s
a,b,c
d,e,f
g
"""

7.经典类与新式类

"""
    所有直接继承或间接继承object的类 都是新式类
    object 称之为根类  意思是 所有类 都源自于object类
    为什么这么设计?
        例如:创建对象时,需要申请内存空间,创建新的名称空间,将对象的属性放入名称空间,这一些了复杂的基础操作,都有object来完成
        简单地说object提供了一些常用的基础操作
    即所有类都属于新式类(在python3中)

    在python3中默认所有类都是新式类

    而python2中默认是经典类(不会自动继承Object)


"""
class S:
    pass
class Student(S):
    pass

# __bases__用于查看父类
print(Student.__bases__)

# 显示属性的查找顺序列表,属性查找属性就是按照该列表来查找的
print(Student.mro())

8.super获取父类内容时,按照mor列表

"super访问父类内容时 按照mro列表属性查找"

class S:
    def f1(self):
        print("s f1")

class A(S):
    pass

class B(S):
    def f1(self):
        print("b f1")
    pass

class C(A,B):
    def f2(self):
        print("c f2")
        super().f1()


print(C.mro())
c1 = C()
c1.f2()

9.覆盖

class A:
    age = 18

    def f1(self):
        print(" A f1"
        )
    pass
class B(A):
    age1 = 19
    def f1(self):
        self.f1()
        print(" B f1")

    pass

b1 = B()
print(b1.age)

b1.f1()

# 子类出现了与父类重复的名字 称之为覆盖
# 子类出现了与父类不同的名字 称之为拍派生
上一篇 下一篇

猜你喜欢

热点阅读