面向对象的特征

一、封装

二、继承

不使用继承的方法

class Animal:
    """
    创建一个动物类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")

class Dog:
    """
    创建一个狗类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")
    def shout(self):
        """
        增加喊叫的方法
        """
        print("汪汪汪···")

class Cat:
    """
    创建一个狗类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("在吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")
    def shout(self):
        """
        增加喊叫的方法
        """
        print("喵喵喵···")

# 创建对象
wangcai = Dog()
wangcai.eat()
wangcai.play()
wangcai.drink()
wangcai.shout()

lili = Cat()
lili.eat()
lili.play()
lili.drink()
lili.shout()

"""
输出结果:
吃
玩
喝
汪汪汪···
在吃
玩
喝
喵喵喵···
"""

在没有使用继承开发的程序在一定情况下,程序会变成非常的多余

使用继承方法

class Animal:
    """
    创建一个动物类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")

class Dog(Animal):
    """
    创建一个狗类
    """
    def shout(self):
        """
        增加喊叫的方法
        """
        print("汪汪汪···")

class Cat(Animal):
    """
    创建一个狗类
    """
    def shout(self):
        """
        增加喊叫的方法
        """
        print("喵喵喵···")

# 创建对象
wangcai = Dog()
wangcai.eat()
wangcai.play()
wangcai.drink()
wangcai.shout()

lili = Cat()
lili.eat()
lili.play()
lili.drink()
lili.shout()

"""
输出结果:
吃
玩
喝
汪汪汪···
在吃
玩
喝
喵喵喵···
"""
继承:
	想要继承一个类,可以使用:类名(要继承的类名)
	父类    
	子类

继承的传递性

class Animal:
    """
    创建一个动物类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")

class Dog(Animal):
    """
    创建一个狗类
    """
    def shout(self):
        """
        增加喊叫的方法
        """
        print("汪汪汪···")

class Hsq(Dog):
    """
    创建一个哈士奇狗类
    """
    def open(self):
        """
        增加拆家的方法
        """
        print("拆家中···")

# 创建对象
erha = Hsq()
erha.eat()
erha.play()
erha.shout()
erha.drink()
erha.open()

"""
输出结果:
吃
玩
汪汪汪···
喝
拆家中···
"""

继承具有传递性,可以使用父类,也可以使用父类的父类等等;

注意:object 是所有类的父类

继承的注意事项

同级之间不能互相借用属性、方法;

子类覆盖父类的方法

class Animal:
    """
    创建一个动物类
    """
    def eat(self):
        """
        增加吃的方法
        """
        print("吃")
    def drink(self):
        """
        增加喝的方法
        """
        print("喝")

    def play(self):
        """
        增加玩的方法
        """
        print("玩")

    def shout(self):
        """
        增加喊叫的方法
        """
        # 父类的父类调用父类的方法不行,会报错
        # Dog.shout(self)
        print("嗷呜~")

class Dog(Animal):
    """
    创建一个狗类
    """
    def shout(self):
        """
        增加喊叫的方法
        """
        print("汪汪汪···")

class DsDog(Dog):
    """
    创建一个单身狗类
    """
    # 这是子类重写父类的方法
    def shout(self):
        """
        增加喊叫的方法
        """
        # 子类特有的需求
        print("求对象!")
        # 调用父类的方法
        super().shout()
        # 调用父类的父类的方法
        Animal.shout(self)
        # 递归(死循环)
        # DsDog.shout(self)

# 创建对象
huahua = DsDog()
huahua.shout()

"""
输出结果:
求对象!
汪汪汪···
嗷呜~
"""

当父类的方法不能满足自己的需求的时候,可以对父类的方法进行重写

父类的私有方法和属性

class A(object):
    """
    创建一个类
    """
    def __init__(self):
        """
        初始化属性
        """
        # 公有属性
        self.name = "丽丽"
        # 私有属性
        self.__age = 18

    def __eat(self):
        """
        添加私有方法
        """
        # 访问共有属性及同类的私有属性
        print("私有方法eat:{}{}".format(self.name,self.__age))

    def eat(self):
        """
        添加公有方法
        """
        # 访问公有属性及同类的私有属性
        print("公有方法eat:{}{}".format(self.name, self.__age))

class B(A):
    def test(self):
        # 1、子类不能访问父类的私有属性
        # print(self.__age)
        # print(super().__age)
        # 2、子类不能访问父类的私有方法
        # self.__eat()
        # 3、子类可以访问父类的公有属性
        print(self.name)
        print("子类访问父类的公有属性:{}".format(self.name))
        # super(B, self).name
        # 4、子类可以调用父类的公有方法
        print(self.eat())
        super(B, self).eat()

# 创建对象
b = B()
b.test()
# 在外界可以直接访问父类的公有属性,或者调用父类的公有方法
print(b.name)
b.eat()

"""
输出结果:
丽丽
子类访问父类的公有属性:丽丽
公有方法eat:丽丽18
None
公有方法eat:丽丽18
丽丽
公有方法eat:丽丽18
"""

公有和私有的区别

class A:
    def __init__(self): # 这里的参数不一定要传参,可以直接赋值
        # 添加公有属性
        self.num = 100
        # 添加私有属性
        self.__num = 200

    def __test(self):
        """
        私有方法
        """
        print("私有方法:%d %d"%(self.num,self.__num))

    def test(self):
        """
        公有方法
        """
        print("公有方法:%d %d"%(self.num,self.__num))
        
class B(A):
    pass

# 创建对象a
a = A()
# 调用公有属性
print(a.num)
# 调用私有属性
print(a._A__num)
# 调用公有方法
a.test()
# 调用私有方法
a._A__test()

# 创建对象b
b = B()
# 通过子类访问父类的公有属性
print(b.num)
# 通过子类调用父类的公有方法
b.test()
# 结论:子类是不能访问父类的私有属性和私有方法

"""
输出结果:
100
200
公有方法:100 200
私有方法:100 200

100
公有方法:100 200
"""

多继承

多继承可以让子类继承多个父类的方法和属性

class A:
    def test(self):
        print("----A----")

class B:
    def test1(self):
        print("----B----")

class C(A,B):
    def test2(self):
        print("----C----")

c = C()
c.test()
c.test1()
c.test2()

"""
输出结果:
----A----
----B----
----C----
"""

子类重写了父类的方法,以子类优先

class A:
    def test(self):
        print("----A----")

class B:
    def test(self):
        print("----B----")

class C(A,B):
    def test(self):
        print("----C----")

c = C()
c.test()

"""
输出结果:
----C----
"""

多继承的顺序,按继承的先后顺序调用

class A:
    def test(self):
        print("----A----")

class B:
    def test(self):
        print("----B----")

class C(A,B):
    def test1(self):
        print("----C----")

c = C()
c.test()

# 使用方法查询C类对象的调用顺序
print(C.__mro__)

"""
输出结果:
----A----
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
"""

结论:多继承需要注意对象调用的顺序;可以用.__ __ mro_ _ _ ()方法查询属性调用顺序,也可以查询方法调用顺序

三、多肽

class Animal():

    def introduce(self):
        """
        自我介绍的方法
        """
        print("我是一只神奇的动物,感谢各位的关照!")

class Dog(Animal):

    def introduce(self):
        """
        自我介绍的方法
        """
        print("飞天旺财在此,感谢各位的关照!")

class Cat(Animal):

    def introduce(self):
        """
        自我介绍的方法
        """
        print("波斯猫在此,感谢各位的关照!")

def introduce(temp):
    """
    定义自我介绍的函数
    """
    # 调用函数
    temp.introduce()

# 创建对象
a = Animal()
b = Dog()
c = Cat()

# 传入对象调用函数
introduce(a)
introduce(b)
introduce(c)

"""
输出结果:
我是一只神奇的动物,感谢各位的关照!
飞天旺财在此,感谢各位的关照!
波斯猫在此,感谢各位的关照!
"""

基于弱数据类型语言的特性,多肽不是太明显;

定义的时候不确定调用哪个类里面的方法,而是执行的时候才确定,我们就可以使用多肽

posted @ 2022-04-14 10:49  猪腩飞了天  阅读(30)  评论(0)    收藏  举报