python中类的总结三

继承和派生

继承是从已有的类中派生出新的类,新类具有原类的数据属性和行为,并能扩展新的行为;
派生类就是从一个已有的类中衍生出新的类,在新类的基本上添加新的属性和行为。
目的:
继承的目的是延续旧类的功能。
派生的目的是在旧类的基础上改变原有的功能。

单继承
语法:
class 类名(基类名):
       语句块

说明:单继承是指派生类由一个基类衍生出来新类。
示例代码如下:

# 此示例示意单继承的定义方法和用法
class Human:
    def say(self, what):
        print("说:", what)

    def walk(self, distance):
        print("走了", distance, '公里')


class Student(Human):
    def study(self, subject):
        print("正在学习", subject)


class Teacher(Student):
    def teach(self, subject):
        print("正在教", subject)


h1 = Human()
h1.say('今天天气真好')
h1.walk(5)


s1 = Student()
s1.walk(4)
s1.say('感觉有点累')
s1.study('Python')


t1 = Teacher()
t1.teach("面向对象")
t1.walk(6)
t1.say('太累了,今天晚吃啥')
t1.study('英雄联盟')

继承派生机制的作用:
1.可以将一些共有功能加在基类中。实现代码的共享。
2.在不改变基类的基础上改变原有的功能。

继承说明:
python3 任何类都直接或间接的继承自object类;
object类是一切类的超类。

类的 base 属性
__base__属性用来记录此类的基类。

覆盖
覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调用的是子类中的覆盖版本,这种现象叫覆盖。
示例代码如下:

# 此示例示意覆盖的含义及用法
class A:
    def work(self):
        print("A.work 被调用")


class B(A):
    '''B类继承自A类'''
    def work(self):
        print("B.work被调用!!!")


b = B()
b.work()  # B.work被调用!!!  B.work(b)
A.work(b)  # A.work 被调用

那么问题来了当覆盖发生时,子类对象如何调用父类中的被覆盖的方法?
python中有一个函数super函数可以解决这个问题。

super(cls, obj) 返回绑定超类的实例(要求obj必须为cls类型的实例)
super() 返回绑定超类的实例,等同于: super(class, 实例方法的第一个参数, 必须在方法内调用)
作用:借助super()返回的实例间接调用父类的覆盖方法.
示例代码如下:

# 此示例示意用super函数间接调用父类中覆盖版本的方法
class A:
    def work(self):
        print("A.work 被调用")

class B(A):
    '''B类继承自A类'''
    def work(self):
        print("B.work被调用!!!")

    def super_work(self):
        # 调用B类自己的work方法怎么调用
        self.work()
        # 调用父类的work怎么调用
        super(B, self).work()
        super().work()  # 此种调用方式只能在实例方式内调用


b = B()
# b.work()  # B.work被调用!!!
# super(B, b).work()  # A.work 被调用
b.super_work()
# super().work()  # 出错

显式调用基类的初始化方法
当子类中实现了__init__方法,基类的构造方法并不会被调用,此时需要显式调用

# 此示例示意显式调用初始化方法
class Human:
    def __init__(self, n, a):
        self.name = n  # 姓名
        self.age = a  # 年龄
        print("Human类的初始化方法被调用 ...")
    def infos(self):
        print("姓名:", self.name)
        print("年龄:", self.age)


class Student(Human):
    def __init__(self, n, a, s=0):
        # super(Student, self).__init__(n, a)
        super().__init__(n, a)
        self.score = s
        print("Stduent的初始化方法被调用...")

    def infos(self):
        super().infos()  # 显式调用父类的方法
        print('成绩:', self.score)

s1 = Student('张飞', 15, 80)
s1.infos()

以下为钻石继承继承顺序

class Plant():
    def __init__(self):
        print("Enter plant")
        print("Leave plant")

class Fruit(Plant):
    def __init__(self):
        print("Enter Fruit")
        super().__init__()
        print("Leave Fruit")

class Vegetable(Plant):
    def __init__(self):
        print("Enter vegetable")
        super().__init__()
        print("Leave vegetable")

class Tomato(Fruit, Vegetable):
    def __init__(self):
        print("Enter Tomato")
        super().__init__()
        print("Leave Tomato")

tomato = Tomato()
print(Tomato.__mro__)

注:__mro__属性
作用:  用来记录类的方法查找顺序。

# 输出
# Enter Tomato
# Enter Fruit
# Enter vegetable
# Enter plant
# Leave plant
# Leave vegetable
# Leave Fruit
# Leave Tomato
# (<class '__main__.Tomato'>, <class '__main__.Fruit'>, <class '__main__.Vegetable'>, <class '__main__.Plant'>, <class 'object'>)


    A
   / \
  B   C
   \ /
    D
D --> B --> C --> A
遵循就近原则

封装

讲到封装,我们围绕三点展开,是什么,为什么,怎么样。
是什么
封装就是将类中的属性及方法隐藏起来,仅对外提供公共的访问方式,
可以想象为一个电视机,用户不需要知道里面具体有哪些零件,只提供给用户操作电视的按钮即可,这样将电视内部零件封装了起来,并且给外部提供了接口。
为什么
封装的目的是让使用者通过尽可能少的方法(或属性)操作对象,同时隔离复杂度。
示例代码如下:

#取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
#对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做隔离了复杂度,同时也提升了安全性

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用户认证')
    def __input(self):
        print('输入取款金额')
    def __print_bill(self):
        print('打印账单')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

a=ATM()
a.withdraw():
python 的封装是假的封装(模拟的封装)

说明
私有属性和方法
python类中,以双下划线(’__’) 开头,不以双下划线结尾的标识符为私有成员,私有成员只能使用该类的方法来进行访问和修改。
1. 以__开头的属性为私有属性。
2. 以__开头的方法为私有方法。

封装特性property
@property装饰器就是负责把一个方法变成属性调用的。
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值。
目的: 将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则。

示例代码如下:

class people:
    def __init__(self,name,age,height,weight):
        self.name=name
        self.age=age
        self.height=height
        self.weight=weight

    @property
    def bodyindex(self):
        return self.weight/(self.height**2)

p1=people('alex',18,1.76,74)
print(p1.bodyindex)

property属性的定义和调用要注意一下几点:
1.定义时,在实例方法的基础上添加 @property 装饰器;并且仅有一个self参数。
2.调用时,无需括号。
3.经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法。
4.新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法。
5.Python中的类有经典类和新式类,新式类的属性比经典类的属性丰富。( 如果类继object,那么该类是新式类 ),python3中的类都是新式类。

多态

多态是指在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态。

示例代码如下:

class Shape:
    def draw(self):
        print("Shape的draw()被调用")


class Point(Shape):
    def draw(self):
        print('正在画一个点!')


class Circle(Point):
    def draw(self):
        print('正在画一个圆!!!')


def my_draw(s):
    s.draw()  # <<<--- 此处显示出多态中的"动态"


s1 = Circle()  # 创建一个圆对象
s2 = Point()  # 创建一个点对象
my_draw(s1)   #正在画一个圆!!!
my_draw(s2)   #正在画一个点!

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

    def whoAmI(self):
        return 'I am a Person, my name is %s' % self.name


class Student(Person):
    def __init__(self, name, gender, score):
        super(Student, self).__init__(name, gender)
        self.score = score

    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name


class Teacher(Person):
    def __init__(self, name, gender, course):
        super(Teacher, self).__init__(name, gender)
        self.course = course

    def whoAmI(self):
        return 'I am a Teacher, my name is %s' % self.name


def who_am_i(x):
    print(x.whoAmI())


p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')


who_am_i(p) #I am a Person, my name is Tim
who_am_i(s) #I am a Student, my name is Bob
who_am_i(t) #I am a Teacher, my name is Alice

有志者事竟成!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值