Python基础(八)

Python基础(八)

1、继承

1.1、简介

  1. 继承是一种创建类的方式,新建的类可称为子类或派生类,父类可称为基类或超类
  2. 继承可以使得子类具有父类中公共的属性或者方法
  3. 继承具有传递性,即子类拥有父类以及父类的父类中封装的所有属性和方法。
  4. python支持多继承,一个类可以支持一个或多个父类
  5. 在python3中如果没有继承任何类,默认继承object类

1.2、继承

  • 优点
    • 解决了类与类之间代码冗余的问题
    • 子类可以同时遗传多个父类的属性,最大限度的重用代码
    • 可以重点关心子类独有的方法
  • 缺点
    • 多继承违反人的思维习惯,代码的可读性会变差,不建议使用多继承。

1.3、单继承

1. 介绍

子类只继承一个父类

2. 语法

class 类名(父类名):
    pass

3. 单继承的查找顺序

对象>子类>父类>父父类,找到方法或属性后不会继续向下查找。

4. 例子

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

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


class dog(Animal):
    def dog(self):
        print("dog")


class cat(Animal):
    def cat(self):
        print("cat")


class ragdoll(cat):
    def embrace(self):
        print("ragdoll")


c1 = cat()
c1.eat()  # 吃
c1.cat()  # cat

r1 = ragdoll()
r1.eat()  # 吃
r1.cat()  # cat
r1.embrace()  # ragdoll
# 查看调用顺序  类名.mro()
print(ragdoll.mro()) # [<class '__main__.ragdoll'>, <class '__main__.cat'>, <class '__main__.Animal'>, <class 'object'>]

1.4、多继承

1. 介绍

多继承,即子类有多个父类,并且具有它们的特征

2. 语法

class 类名(父类A名,父类B名):
    pass

3. 查找顺序

在python3中按照广度有限进行查找,找到方法或属性后不会继续向下查找。

class G:
    pass

class E:
    pass


class F(G):
    pass


class B(E):
    pass


class C(F):
    pass


class D(G):
    def test(self):
        print('from D')


class A(B, C, D):
    pass


print(A.mro()) #[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.G'>, <class '__main__.D'>, <class 'object'>]
# -A-B-E-C-F-D-G

4. 例子

class A():
    def out_text(self):
        print('from A')

class B(A):
    def out_text(self):
        print('from B')

class C(A):
    def out_text(self):
        print('from C')

class D(B,C):
    pass

obj = D()
obj.out_text() # 结果---->from B
''' 可以打印出mro列表查看顺序'''
print(D.mro())  # [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

1.5、重写方法

1. 介绍

重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。

2. 例子

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

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

    def bark(self):
        print("芜湖")


class cat(Animal):
    def cat(self):
        print("cat")

    def bark(self):
        print("喵喵")


c = cat()
c.run()  # 跑
c.bark()  # 喵喵

1.6、调用父类

1. 介绍

子类可以通过类名或者是super()调用父类的属性

2. 例子

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

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

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

    def bark(self):
        print("芜湖")


class cat(Animal):
    def __init__(self, name, age, wight):
        super().__init__(name, age)
        # Animal.__init__(self, name, age)  效果一致
        self.wight = wight

    def cat(self):
        print("cat")

    def bark(self):
        super().bark()
        print("喵喵")

    def __str__(self):
        return ("{},{},{}".format(self.name, self.age, self.wight))


c = cat("cat", 1, 5)
c.run()  # 跑
c.bark()  # 芜湖 喵喵
print(c)  # cat,1,5

2、多态

2.1、简介

以封装和继承为前提的基础上,不同的子类调用相同的方法,产生不同的结果。

前提:

  • 多态发生在父类和子类之间
  • 子类需要重写父类的方法

2.2、鸭子类型

在程序设计中,鸭子类型(英语:ducktyping)是动态类型的一种风格。

在这种风格中,一个对象有效的语义不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。“

鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。

2.3、示例

class Language:
    def say(self):
        print("调用的是 language 类的say方法")


class Python(Language):
    def say(self):
        print("调用的是 Python 类的say方法")


class Linux(Language):
    def say(self):
        print("调用的是 Linux 类的say方法")


a = Language()
a.say()  # 调用的是 language 类的say方法
a = Python()
a.say()  # 调用的是 Python 类的say方法
a = Linux()
a.say()  # 调用的是 Linux 类的say方法

或者高级一点的用法

class Language:
    def say(self):
        print("调用的是 language 类的say方法")


class Python(Language):
    def say(self):
        print("调用的是 Python 类的say方法")


class Linux(Language):
    def say(self):
        print("调用的是 Linux 类的say方法")


def say(who):
    who.say()


say(Language())  # 调用的是 language 类的say方法
say(Python())  # 调用的是 Python 类的say方法
say(Linux())  # 调用的是 Linux 类的say方法

3、封装

3.1、简介

封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式,使这些指隐藏的属性与方法无法在外部直接访问与调用,也无法被子类继承。

3.2、私有化属性

  • 为了更好的保存属性安全,可以将属性定义为私有属性。
  • 私有属性只能在类的内部被使用或修改。
  • 在类的添加一个修改和访问的方法去维护私有属性。

1. 语法

两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。

2.示例

class people:
    __age = 18  # 私有属性

    def __init__(self):
        self.__name = '张三'  # 私有属性
        self.height = 178

    def __str__(self):
        # 私有化的属性能在内部使用
        return '{}的身高是{}年龄是{}'.format(self.__name, self.height, self.__age)

    def __set_name__(self, name):
        self.__name = name


class student(people):
    def __str__(self):
        # 子类无法继承子类的私有属性
        return '学生的身高是{}'.format(self.height, )

    pass


zs = people()
print(zs)  # 张三的身高是178年龄是18
zs.__set_name__("王五")
print(zs)  # 王五的身高是178年龄是18

ls = student()
print(ls)  # 学生的身高是178

3.3、私有化方法

私有化方法跟私有化属性概念一样,有些重要的方法。不允许外部调用,防止子类意外重写,把普通的方法设置成私有化方法。

1. 语法

两个下划线开头,声明该方法为私有,不能在类的外部被使用或直接调用。

2.示例

class people:
   __age = 18  # 私有属性

   def __init__(self):
       self.__name = '张三'  # 私有属性
       self.height = 178

   def __str__(self):
       # 私有化的属性能在内部使用
       return '{}的身高是{}年龄是{}'.format(self.__name, self.height, self.__age)

   def __set_name__(self, name):
       self.__name = name

   def __hello(self):  # 私有化方法
       print("hello")

   def sayHello(self):
       self.__hello()


class student(people):
   def __str__(self):
       # 子类无法继承子类的私有属性
       return '学生的身高是{}'.format(self.height, )

   pass


ls = student()
ls.sayHello()  # hello

3.4、property属性

通过property可以使私有属性依旧使用“类对象.属性”的方式进行操作。

1. 第一种方式

property属性方法:

  • property(get方法,set方法,del方法(重置值))
  • 三个传值可以根据需要只传一个或两个(为只读,可读可写)
class people:
    __age = 18  # 私有属性

    def __init__(self):
        self.__name = '张三'  # 私有属性
        self.height = 178

    def set_name(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    def set_age(self, age):
        self.__age = age

    def get_age(self):
        return self.__age

    age = property(get_age, set_age)
    name = property(get_name, set_name)


p1 = people()
print(p1.age)
print(p1.name)

2. 方式二

使用注释方法:

  • property需要在前,属性名.setter需要在后
  • property是get,属性名.setter是set
  • 方法名都为属性名
class people:
    __age = 18  # 私有属性

    def __init__(self):
        self.__name = '张三'  # 私有属性
        self.height = 178

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        self.__age = age

p1 = people()
print(p1.name)  # 张三
p1.name = "李四"
print(p1.name)  # 李四

print(p1.age)  # 18
p1.age = 12
print(p1.age)  # 12

4、小结

  • 继承
  • 多态
  • 封装
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值