Python面向对象三大特征

Python面向对象三大特征

面向对象的三大特征:封装继承多态

一、封装

  • 广义的封装:函数的定义和类的定义
  • 狭义的封装:一个类中的某些属性,如果不希望被外界直接访问,则可以将该属性私有化,该属性只能在当前类中被直接访问;如果在类的外面需要访问(即获取或修改),则可以通过暴露给外界的函数间接访问
  • 封装的本质:将类中的属性进行私有化

1.1 私有属性

以实例属性为例,类属性一样,私有化只要在类属性前面添加两个下划线_

  • 公有属性

    正常使用self.变量 = 值定义,可以在类的外面直接用对象进行访问到

# 定义类
class Person1():
    def __init__(self, name, age):
        # 公开属性
        self.name = name
        self.age = age


# 创建对象
p1 = Person1("张三", 10)
# 通过对象可以直接访问
print(p1.name, p1.age)
  • 私有属性

    在定义属性的时候,在前面添加两个下划线_,如上诉的name修改为__name

    • 注意
      • 此时变量名为__name,而不是原来的name
      • 进行限制属性动态绑定的时候,也要书写__xxx形式
      • 当前类中的函数中,可以通过 self.__xxxx访问
      • 类的外面直接用对象无法访问
# b.私有属性/属性的私有化
class Person2():
    # 注意事项:哪怕是定义了私有属性,进行了限制属性动态绑定的时候,也要书写__xxx形式
    __slots__ = ("__name", "__age")

    def __init__(self, name, age):
        # 私有属性,只需要在属性名的前面添加两个下划线__
        self.__name = name
        self.__age = age

    # 注意3:在当前类中的函数中,可以self.__xxx访问的
    def show(self):
        print(f"姓名:{self.__name},年龄:{self.__age}")


# 创建对象,通过对象可以直接访问
p2 = Person2("张三", 10)
# 通过对象无法直接访问
# print(p2.__name, p2.__age)  # 报错:AttributeError: 'Person2' object has no attribute 'name'
p2.show()

1.2 私有函数

既然属性可以私有,那么函数也可以私有

函数私有化方式和属性私有化类似,只要在函数名前面添加两个下划线_

class Person3:
    # 创建公有函数
    def func1(self):
        print("func1函数~~~")

    # 创建私有函数
    def __func2(self):
        print("__func2私有函数~~~")


# 创建对象
p3 = Person3()
# 通过对象调用函数
p3.func1()
# p3.__func2()  # AttributeError: 'Person3' object has no attribute '__func2'

此时,私有函数无法再类外通过对象进行调用,如果访问,则会报错

如果要访问私有函数,可以在共有函数中调用私有函数

class Person3:
    # 创建公有函数
    def func1(self):
        print("func1函数~~~")

        # 调用私有函数
        self.__func2()

    # 创建私有函数
    def __func2(self):
        print("__func2私有函数~~~")


# 创建对象
p3 = Person3()
# 通过对象调用函数
p3.func1()

输出结果

func1函数~~~
__func2私有函数~~~

1.3 类比总计

解释下面不同形式的变量出现在类中的意义

a:普通属性,也被称为公开属性,在类的外面可以直接访问

_a:在类的外面可以直接访问,但是不建议使用,容易和私有属性混淆

__a:私有属性,只能在类的内部被直接访问。类的外面可以通过暴露给外界的函数访问

__a__:在类的外面可以直接访问,但是不建议使用,因为系统属性和魔术方法都是这种形式的命名

​ 如:__slots____init____new____del____name____add____sub____mul__

综上所述:公有属性使用a,私有属性使用__a,系统属性使用__a__

二、继承

  • 如果两个或者两个以上的类具有相同的属性和方法,我们可以抽取一个类出来,在抽取出来的类中声明各个类公共的部分。其中:

​ 被抽取出来的类——父类(father class)或着超类(super class)或者基类(base class)

​ 两个或两个以上的类——子类或者派生类

​ 他们之间的关系——子类继承自父类;或者父类派生了子类

  • 简单来说

​ 一个子类只有一个父类,被称为单继承

​ 一个子类有多个父类,被称为多继承

  • 语法:
# 单继承
class 子类类名(父类类名):
	类体
# 多继承
class 子类类名(父类类名1,父类类名2.......):
	类体

注意:object是Python中所有类的根类

  • 继承的好处

​ 简化代码

​ 复用性

​ 可读性

2.1 单继承

一个子类只有一个父类,被称为单继承

父类

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

    def eat(self):
        print("eating~~~~~~")

子类1:子类中没有定义__init__,创建子类对象,自动调用父类中的__init__

class Doctor(Person):
    pass


doc = Doctor("王大夫", 45)
print(doc.name, doc.age)
doc.eat()

子类2:如果子类中定义了__init__,且定义了特有的属性,则在子类的__init__中调用父类的__init__

有三种方式可以调用

  • 方式一
super(当前类,self).__init__(参数列表)
  • 方式二
super().__init__(参数列表)
  • 方式三
父类.__init__(self,参数列表)
# b.如果子类中定义了__init__,且定义了特有的属性,则在子类的__init__中调用父类的__init__
class Student(Person):
    def __init__(self, name, age, score):
        # 方式一:super(当前类,self).__init__(参数列表)
        # super(Student, self).__init__(name, age)

        # 方式二:super().__init__(参数列表)
        # super().__init__(name, age)
        # 方式三:父类.__init__(self,参数列表)
        Person.__init__(self, name, age)
        self.score = score

    def study(self):
        print("studying~~~~~~~")


stu = Student("小明", 10, 88)
print(stu.score)
print(stu.name, stu.age)
stu.eat()
stu.study()

2.2 多继承

一个子类有多个父类,被称为多继承

如果在子类的__init__中调用父类的__init__,方式如上,建议使用方式三,目标明确

# 多继承,一个子类有多个父类
# 父类1
class Flyable():
    def fly(self):
        print("飞行")


# 父类2
class Runable():
    def run(self):
        print("行走")


# 子类
class Bird(Flyable, Runable):
    pass


# 创建子类对象
bird = Bird()
# 调用父类1的方法
bird.fly()
# 调用父类2的方法
bird.run()

三、多态

继承是多态的前提

  • 体现形式:

    • 一种事物的多种体现形式,举例:动物有很多种
    class Animal:
        pass
    
    
    class Cat(Animal):
        pass
    
    
    class SmallCat(Cat):
        pass
    
    
    # isinstance(对象,类型) :判断对象是否是制定的类型
    sc = SmallCat()	# sc 是多态的体现形式
    print(isinstance(sc, SmallCat))  # True
    print(isinstance(sc, Cat))  # True
    print(isinstance(sc, Animal))  # True
    print(isinstance(sc, object))  # True
    
    • 定义时并不确定是什么类型,要调用的是哪个方法,只有运行的时候才能确定调用的是哪个
    class Animal:
        def style(self):
            print("walking~~~~~")
    
    
    class Cat(Animal):
        pass
    
    
    class Dog(Animal):
        pass
    
    
    class Fish(Animal):
        def style(self):
            print("swimming~~~~~")
    
    
    class Bird(Animal):
        def style(self):
            print("flying~~~~~")
    
    
    def show(ani):  # ani 就是多态的体现形式
        ani.style()
    
    
    d = Dog()
    c = Cat()
    f = Fish()
    b = Bird()
    
    show(d)
    show(c)
    show(f)
    show(b)
    

    输出结果

    walking~~~~~
    walking~~~~~
    swimming~~~~~
    flying~~~~~
    
  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巧克力配酸奶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值