Python快速入门(九)面向对象2:继承、多态、静态方法、单例等


前言:主要介绍继承、多态、静态方法、new方法、单例等。


1.单继承

  • 继承:实现代码的重用,相同的代码不需要重复的编写
  • 子类拥有父类的所有方法和属性
  • 子类 继承自 父类,可以直接 享受 父类中已经封装好的方法,不需要再次开发
  • 子类 中应该根据 职责,封装 子类特有的 属性和方法
    代码:
class Animal:

    def eat(self):
        print("吃")

    def drink(self):
        print("喝")

    def run(self):
        print("跑")

    def sleep(self):
        print("睡")


class Dog(Animal):
    def bark(self):
        print("汪汪叫")

class Cat(Animal):
    def bark(self):
        print("喵喵喵")

# 创建一个对象 - 狗对象
wang = Dog()
wang.eat()
wang.drink()
wang.run()
wang.sleep()
wang.bark()
print("*"*100)

tom = Cat()
tom.eat()
tom.drink()
tom.run()
tom.sleep()
tom.bark()

输出:
在这里插入图片描述

2.继承的传递性

  • C 类从 B 类继承,B 类又从 A 类继承,那么 C 类就具有 B 类和 A 类的所有属性和方法。
  • 子类 拥有 父类 以及 父类的父类 中封装的所有 属性 和 方法。

代码:

class Animal:

    def eat(self):
        print("吃")

    def drink(self):
        print("喝")

    def run(self):
        print("跑")

    def sleep(self):
        print("睡")


class Dog(Animal):

    def bark(self):
        print("狗特有的属性:汪汪叫")


class XiaoTianQuan(Dog):

    def fly(self):
        print("哮天犬特有的属性:我会飞")


# 创建一个哮天犬的对象
xtq = XiaoTianQuan()
xtq.eat()
xtq.drink()
xtq.run()
xtq.sleep()
xtq.bark()
xtq.fly()

输出:
在这里插入图片描述

  • 注意:如果新建一个cat类继承animal类,添加cat的特有方法,则此时的xiaotianquan对象则不能调用cat里面的方法。

代码:

class Animal:

    def eat(self):
        print("吃---")

    def drink(self):
        print("喝---")

    def run(self):
        print("跑---")

    def sleep(self):
        print("睡---")

class Dog(Animal):

    def bark(self):
        print("汪汪叫")

class XiaoTianQuan(Dog):

    def fly(self):
        print("我会飞")

class Cat(Animal):

    def catch(self):
        print("抓老鼠")

# 创建一个哮天犬的对象
xtq = XiaoTianQuan()
xtq.fly()
xtq.bark()
xtq.eat()
xtq.catch() #出错

输出:
在这里插入图片描述

3.覆盖父类方法

  • 如果子类中,重写了父类的方法,在使用子类对象调用方法时,会调用子类中重写的方法。

代码:

class Animal:

    def eat(self):
        print("吃---")

    def drink(self):
        print("喝---")

    def run(self):
        print("跑---")

    def sleep(self):
        print("睡---")

class Dog(Animal):

    def bark(self):
        print("汪汪叫")

class XiaoTianQuan(Dog):

    def fly(self):
        print("我会飞")

    def bark(self):
        print("叫得跟神一样...")

xtq = XiaoTianQuan()
xtq.bark()

输出:
在这里插入图片描述

4.拓展父类方法

  • 可以重写父类的方法
  • 使用 super(). 调用原本在父类中封装的方法
  • 父类名.方法(self)

代码:

class Animal:

    def eat(self):
        print("吃---")

    def drink(self):
        print("喝---")

    def run(self):
        print("跑---")

    def sleep(self):
        print("睡---")

class Dog(Animal):

    def bark(self):
        print("汪汪叫")

class XiaoTianQuan(Dog):

    def fly(self):
        print("我会飞")

    def bark(self):

        # 针对子类特有的需求,编写代码
        print("啦啦啦...")
        
        # 使用 super(). 调用原本在父类中封装的方法
        # super().bark()
        # 父类名.方法(self)
        Dog.bark(self)
        
        # 增加其他子类的代码
        print("xxxx")


xtq = XiaoTianQuan()
xtq.bark()

5.父类的私有属性和私有方法

  • 子类不能继承父类的私有属性和私有方法。

代码:

class A:

    def __init__(self):
        self.num1 = 12
        self.__num2 = 15

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

class B(A):

    def demo(self):

        # 在子类的对象方法中,不能访问父类的私有属性
        # print("访问父类的私有属性 %d" % self.__num2)

        # 在子类的对象方法中,不能调用父类的私有方法
        # self.__test()
        pass

# 创建一个子类对象
b = B()
print(b)
b.demo()

6.父类的公有方法

如果需要访问父类的私有方法,可以通过父类的共有方法,访问这个父类的私有方法,我们可以在共有方法里面设置一些条件才能访问私有方法,这样会更加安全。
代码:

class A:

    def __init__(self):
        self.num1 = 100
        self.__num2 = 200

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

    def test(self):
        print("父类的公有方法 %d" % self.__num2)
        self.__test()

class B(A):

    def demo(self):
        # 访问父类的公有属性
        print("子类方法 %d" % self.num1)
        # 调用父类的公有方法
        self.test()
        pass

# 创建一个子类对象
b = B()
print(b)

b.demo()
# 在外界访问父类的公有属性/调用公有方法
print(b.num1)
b.test()

输出:
在这里插入图片描述

7.多继承&注意事项

  • 子类 可以拥有 多个父类,并且具有 所有父类 的 属性 和 方法
  • 例如:孩子 会继承自己 父亲 和 母亲 的 特性
  • 注意:Java是单继承

代码:

class A:

    def test(self):
        print("test 方法")

class B:

    def demo(self):
        print("demo 方法")

class C(A, B):
    """多继承可以让子类对象,同时具有多个父类的属性和方法"""
    pass

# 创建子类对象
c = C()
c.test()
c.demo()

输出:
在这里插入图片描述
注意事项代码:

class A:

    def test(self):
        print("A --- test 方法")

    def demo(self):
        print("A --- demo 方法")

class B:

    def test(self):
        print("B --- test 方法")

    def demo(self):
        print("B --- demo 方法")

class C(B, A):
    """多继承可以让子类对象,同时具有多个父类的属性和方法"""
    pass

# 创建子类对象
c = C()

c.test()
c.demo()

# 确定C类对象调用方法的顺序
print(C.__mro__)

输出:
在这里插入图片描述

8.多态

  • 多态 不同的 子类对象 调用相同的 父类方法,产生不同的执行结果。
  • 多态 可以 增加代码的灵活度
  • 以 继承 和 重写父类方法 为前提
  • 是调用方法的技巧,不会影响到类的内部设计

代码:

class Dog(object):

    def __init__(self, name):
        self.name = name

    def game(self):
        print("%s 蹦蹦跳跳的玩耍" % self.name)

class XiaoTianDog(Dog):

    def game(self):
        print("%s 飞到天上去玩耍" % self.name)

class Person(object):

    def __init__(self, name):
        self.name = name

    def game_with_dog(self, dog):
        print("%s 和 %s 快乐的玩耍" % (self.name, dog.name))
        # 让狗玩耍
        dog.game()


# 创建一个狗对象
wangcai = XiaoTianDog("飞天旺财")

# 创建一个小明对象
xiaoming = Person("小明")

# 让小明调用和狗玩的方法
xiaoming.game_with_dog(wangcai)

输出:
在这里插入图片描述

9.类属性和实例属性

  • 类属性 就是给 类对象 中定义的 属性
  • 通常用来记录 与这个类相关 的特征
  • 类属性 不会用于记录 具体对象的特征

代码:

class Tool(object):

    # 使用赋值语句定义类属性,记录所有工具对象的数量
    count = 0

    def __init__(self, name):
        self.name = name
        print(name)
        # 让类属性的值+1
        Tool.count += 1


# 1. 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")
tool3 = Tool("水桶")

# 2. 输出工具对象的总数
print(Tool.count)

输出:
在这里插入图片描述

10.类方法

  • 类属性 就是针对 类对象 定义的属性
  • 类方法 就是针对 类对象 定义的方法

代码:

class Tool(object):

    # 使用赋值语句定义类属性,记录所有工具对象的数量
    count = 0

    @classmethod
    def show_tool_count(cls):
        print("工具对象的数量 %d" % cls.count)

    def __init__(self, name):
        self.name = name
        # 让类属性的值+1
        Tool.count += 1

# 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")

# 调用类方法
Tool.show_tool_count()

输出:
在这里插入图片描述

11.静态方法

  • 通过类名.调用静态方法 - 不需要创建对象

代码:

class Dog(object):

    @staticmethod
    def run():
        # 不访问实例属性/类属性
        print("小狗要跑...")
        
Dog.run()

输出:
在这里插入图片描述

12.方法案列综合

代码:

class Game(object):

    # 历史最高分
    top_score = 0

    def __init__(self, player_name):
        self.player_name = player_name

    @staticmethod
    def show_help():
        print("帮助信息:让僵尸进入大门")

    @classmethod
    def show_top_score(cls):
        print("历史记录 %d" % cls.top_score)

    def start_game(self):
        print("%s 开始游戏啦..." % self.player_name)

# 查看游戏的帮助信息
Game.show_help()

# 查看历史最高分
Game.show_top_score()

# 创建游戏对象
game = Game("小明")
game.start_game()

输出:
在这里插入图片描述

13.new方法

代码:

class MusicPlayer(object):

    def __new__(cls, *args, **kwargs):

        # 创建对象时,new方法会被自动调用
        print("创建对象,分配空间")

        # 为对象分配空间
        instance = super().__new__(cls)

        # 返回对象的引用
        return instance

    def __init__(self):
        print("播放器初始化")

# 创建播放器对象
player = MusicPlayer()
print(player)

输出:
在这里插入图片描述

14.Python单例

  • 目的:让 类 创建的对象,在系统中 只有 唯一的一个实例
  • 每一次执行 类名() 返回的对象,内存地址是相同的

代码:

class MusicPlayer(object):

    # 记录第一个被创建对象的引用
    instance = None

    # 记录是否执行过初始化动作
    init_flag = False

    def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否是空对象
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance

    def __init__(self):

        # 1. 判断是否执行过初始化动作
        if MusicPlayer.init_flag:
            return

        # 2. 如果没有执行过,在执行初始化动作
        print("初始化播放器")

        # 3. 修改类属性的标记
        MusicPlayer.init_flag = True

# 创建多个对象
player1 = MusicPlayer()
print(player1)

player2 = MusicPlayer()
print(player2)

输出:
在这里插入图片描述


结束!!!

发布了129 篇原创文章 · 获赞 83 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/105079619