python的(封装.继承.多态)举个例子cs

python的(封装.继承.多态)举个例子cs

摘要:
1、首先介绍一下面向对象
2、然后分别讲一下封装、继承和多态
3、最后通过一段面向对象的案例来更好的理解一下面向对象

封装保证了程序的安全性,类的私有方法和属性是无法调用的。

继承保证了代码的重复用性,循环使用。

多态保证了程序的扩展性。

自定义数据类型就是面向对象中的类的概念。我们先介绍一下待会儿会用到的一些术语:

                # 我认为还是通过个例子更容易让人理解

# 首先我们定义一个类
class A(object):    # 这是一个类,class是创建一个类的标志
    # 类变量(类属性):类属性是指类的属性,属性就是我们刚学编程的时候听过的变量。
    x = 7
    y = "asdf"

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

    # 方法:方法就是在类外面我们写的函数,放在类里就叫做一个方法
    def func(self):
        c = 8    # 实例变量:定义在方法中的变量只作用于当前实例的类
        print("Hello World!")

a = A()    # 创建一个对象,实例化

上面的部分代码还需要再解释一下:

  • object:
    • 注意类名后面括号里有个参数object,他代表所有类的基类,也叫作超类。
    • 这就有了一个新式类和旧式类的概念:
    • 当用到多继承的时候,如果子类中没有想用的方法名或属性名,他会自动回到上面去找。那么按广度优先遍历的方法去寻找就是新式类(object);深度优先(括号里啥也没有)。
  • __init__():构造函数,实例化的时候若不显示的定义,那么默认调用一个无参的,是初始化的意思。

一、封装

  含义:对外面隐藏对象的属性和方法,仅提供接口。

  作用:安全性(通过私有变量改变对外的使用),复用性

#!/usr/bin/env python
# -*- coding:utf-8 -*-

class Student(object):
    def __init__(self, name, score):
        # 属性仅前面有两个下划线代表私有变量,外部无法访问,因此我们定义了两个新的方法,这样可以避免外部通过score乱改分数,仅当我们自己知道接口才可以修改
        self.__name = name
        self.__score = score

    def info(self):
        print('name: %s ; score: %d' % (self.__name,self.__score))

    def getScore(self):
        return self.__score

    def setScore(self, score):
        self.__score = score

stu = Student('Tom',99)
print('修改前分数:',stu.getScore())
stu.info()
stu.setScore(59)
print('修改后分数:',stu.getScore())
stu.info()

二、继承

  2.1.1、含义

  前面我们提到过,面向对象编程有个好处就是代码复用,而其中一种方法就是通过继承机制。继承就是说定义的一个新类,继承现有的类,获得现有类的非私有属性、方法。提到个私有,就是上面提到的那个前面加两个下划线的那个东西,他在外部无法调用,继承他的子类也不能。被继承的那个类称为基类、父类或超类,子类也可以叫做派生类。

  2.1.2、特点

    1、在继承中,基类的构造方法(__init__()方法)不会被自动调用,需要在子类的构造方法中专门调用。

    2、在调用基类的方法时需要加上基类的类名前缀,并带上self参数变量。区别于在类中调用普通函数时不需要带self参数。

    3、在python中,首先查找对应类型的方法,如果在子类中找不到对应的方法,才到基类中逐个查找。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

# 这是定义了一个基类
class Person(object):
    def __init__(self, name, age, money):
        self.name = name
        self.age = age
        self.__money = money # 私有属性
        # 被引入时,继承不了,但他们的set,get函数可以继承

    def setMoney(self,money):
        self.__money = money

    def getMoney(self):
        return self.__money

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

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

下面是定义的一个子类,继承自上方的类,来使用父类中的方法和属性:

# 由于我将每个类写在了不同的文件里,所以需要引入一下,这就和我们调用库一样
from 单继承的实现.person import Person

class Student(Person):
    def __init__(self,name,age,stuid,money):
        # 调用父类中的__init__(),supper括号中的内容,在python3以后可以不写,写上更安全些
        super(Student,self).__init__(name,age,money) # 让父类的self当做子类的对象
        # 子类可以由一些自己独有的属性或者方法
        self.stuid = stuid

创建对象,通过子类使用父类的属性和方法:

from 单继承的实现.student import Student

stu = Student('Tom',18,111,999) # 创建Student对象
# 下列方法和属性均是在父类Person中定义的,在Student继承之后,便可以直接使用
print(stu.name, stu.age)
stu.run()
print(stu.getMoney())

2.3、多继承

  上面的单继承要多理解一下,单继承理解了之后,多继承也就没什么了。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

class Father(object):
    def __init__(self,money):
        self.money = money
    def play(self):
        print("play")
    def func(self):
        print("func1")

class Mother(object):
    def __init__(self,facevalue):
        self.facevalue = facevalue
    def eat(self):
        print("eat")
    def func(self):
        print("func2")


class Children(Father,Mother):
    def __init__(self,money,facevalue):
        # 多继承时调用父类的属性
        Father.__init__(self,money)
        Mother.__init__(self,facevalue)

def main():
    c = Children(300,100)
    print(c.money,c.facevalue)
    c.play()
    c.eat()
    # 注意:如果多个父类中有相同的方法名,默认调用括号中前面的类
    c.func()
if __name__ == "__main__":
    main()

三、多态

  • 多态:是指一种事物的多种形态
  • 多态性:多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
  • eg:在python中的“+”号,它既可以表示数字的加法,也可以表示字符串的拼接,(__add__())
class Animal(object):
    def __init__(self, name):
        self.name = name

    def run(self):
        pass

    def animalRun(self):
        self.run()


class Cat(Animal):
    def run(self):
        print('cat is running')


class Dog(Animal):
    def run(self):
        print('dog is running')


d = Dog('dog')
c = Cat('cat')

Animal.animalRun(c)
Animal.animalRun(d)

四、面向对象案例

  下面给一个小程序,是模拟反恐精英,保卫者和敌人。主要是让大家看明白,只有简单的几个功能,希望大家可以从中理解面向对象的思想。python中,任何都是对象。

首先,这是我的几个类模块,分开来写比较清晰一点,写在一起也是没问题的。接下来我们一点一点的分析:

  。。。。。。。。。。

  得有人,好人和坏人

  。。。。。。。。。。

  人得有武器,先给他们两种:枪和手榴弹

  。。。。。。。。。。

  枪还有个弹夹也可以作为对象

  。。。。。。。。。。

  想想还有什么,差不多了吧,那么我们就开始写,想到什么再补充

坏蛋:代码如下:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from cs.person import Person
 5 
 6 class Gengster(Person):
 7 
 8     # 初始化,血量默认为100
 9     def __init__(self, gun, grenade, blood=100):
10         self.gun = gun
11         self.grenade = grenade
12         self.blood = blood
13 
14     # 人有开枪的功能
15     def fire(self,person):
16         person.blood.amount -= 5 # 对谁开枪,那个人就要减血
17         self.gun.shoot() # 这个人开枪,这又调用了枪的类,关于子弹的减少在枪的类里
18 
19     # 扔手榴弹,实际上是和枪一样的
20     def fire2(self,person):
21         person.blood -= 10
22         self.grenade.damage() # 同样通过另一个类来控制数量的减少,使代码看起来简洁点
23 
24     # 给弹夹里加子弹
25     def fillbullet(self):
26         self.gun.bulletbox.bulletcount += 10
27 
28     # 补血,并保证满血只能是100
29     def fillblood(self,num):
30         self.blood += num
31         if self.blood > 100:
32             self.blood = 100
33         print("补血后血量:" + str(self.blood))

坏蛋

好人:代码如下:

1 # 主要注释和上一个类似,这里不赘述
 2 
 3 #!/usr/bin/env python
 4 # -*- coding:utf-8 -*-
 5 
 6 from cs.person import Person
 7 
 8 class Profector(Person):
 9 
10     def __init__(self, gun, grenade, blood = 100):
11         self.gun = gun
12         self.grenade = grenade
13         self.blood = blood
14 
15     def fire(self, person):
16         person.blood -= 5
17         self.gun.shoot()
18         print(str(person) + "血量减少5,剩余" + str(person.blood) )
19 
20     def fire2(self,person):
21         person.blood -= 10
22         self.grenade.damage()
23 
24     def fillbullet(self):
25         self.gun.bulletbox.bulletcount += 10
26 
27     def fillblood(self,num):
28         self.blood += num
29         if self.blood > 100:
30             self.blood = 100
31         print("补血后血量:" + str(self.blood))

好人

枪:代码如下:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 class Gun(object):
 5 
 6     # 初始化,把弹夹放里面,通过人来控制枪,再来控制弹夹
 7     def __init__(self,bulletbox):
 8         self.bulletbox = bulletbox
 9 
10     def shoot(self):
11         if self.bulletbox.bulletcount == 0:
12             print('没子弹了')
13         else:
14             self.bulletbox.bulletcount -= 1
15             print(str(self) + '开一枪,还剩%d颗子弹' % (self.bulletbox.bulletcount))

枪

手榴弹:代码如下:

1 # 与枪类似
 2 
 3 #!/usr/bin/env python
 4 # -*- coding:utf-8 -*-
 5 
 6 class Grenade(object):
 7 
 8     def __init__(self,grenadecount):
 9         self.grenadecount = grenadecount
10 
11     def damage(self):
12         if self.grenadecount == 0:
13             print('手雷没有了')
14         else:
15             self.grenadecount -= 1
16             print(str(self) + "轰他一炮,手雷还剩%d颗" % (self.grenadecount))

手榴弹

弹夹:代码如下:

1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 
4 class Bulletbox(object):
5 
6     # 弹夹只需控制数量就好了
7     def __init__(self,bulletcount):
8         self.bulletcount = bulletcount

弹夹

这下差不多了,人也有了,武器也有了,可以开展了

main主程序:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from cs.grenade import Grenade
 5 from cs.gun import Gun
 6 from cs.bulletbox import Bulletbox
 7 from cs.gengster import Gengster
 8 from cs.profector import Profector
 9 # 参数:枪,手榴弹,血(默认100,且上限为100)
10 
11 # 创建弹夹,枪,手榴弹的对象,以备人使用
12 bulletbox = Bulletbox(10)
13 gun = Gun(bulletbox)
14 grenade = Grenade(20)
15 
16 # 创建人对象
17 good1 = Profector(gun,grenade)
18 good2 = Profector(gun,grenade)
19 bad1 = Gengster(gun,grenade)
20 bad2 = Gengster(gun,grenade)
21 
22 print("好人1开枪打坏人1和2")
23 good1.fire(bad1)
24 good1.fire(bad2)
25 print("好人2开枪打坏人1和2")
26 good2.fire(bad1)
27 good2.fire(bad2)
28 print("坏人1炸好人1和2")
29 bad1.fire2(good1)
30 bad1.fire2(good2)
31 print("坏人2炸好人1和2")
32 bad2.fire2(good1)
33 bad2.fire2(good2)
34 print("坏人1补血3个")
35 bad1.fillblood(3)

main

现在这一套流程就结束了,刚开始看也许看不太懂,要仔细看一下每个类之间的关系,先想清楚了,再来看代码是如何实现的

  有没有看出来点区别,面向过程编程是就事论事,而面向对象,先把对象找出来,通过对象之间的关系把他们联系起来。想想如果要用面向过程来实现这个,代码会写成什么样子呢。

  然而并没有结束,记不记得前面的类中有两对是比较类似的,好人和坏人,枪和手榴弹(这个里面的类还不太一样),那么想到了什么没有,前面提到的继承的优点是什么来着,----复用。我们可以可以用继承来写一下呢,如果你说这个也没少几行代码嘛,那么,如果在实际当中你要创建成百上千的对象呢,难道还要每个都复制粘贴改代码吗,还占空间对不对。

  那么我们写一个人类,毕竟好人和坏人都是人:

person代码:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 class Person(object):
 5 
 6     def __init__(self, gun, grenade, blood):
 7         self.gun = gun
 8         self.grenade = grenade
 9         self.blood = blood
10 
11     def fire(self, person):
12         person.blood -= 5
13         self.gun.shoot()
14         print(str(person) + "血量减少5,剩余" + str(person.blood) )
15 
16     def fire2(self, person):
17         person.blood -= 10
18         self.grenade.damage()
19         print(str(person) + "血量减少10,剩余" + str(person.blood) )
20 
21     def fillbullet(self):
22         self.gun.bulletbox.bulletcount += 10
23 
24     def fillblood(self,num):
25         self.blood += num
26         if self.blood > 100:
27             self.blood = 100
28         print(str(self) + "补血后血量:" + str(self.blood))

person

现在我们就不必把好人坏人都重写了,只需要继承一下人类就好了

好人和坏人代码:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 from cs.person import Person
 5 
 6 class Profector(Person):
 7 
 8     def __init__(self, gun, grenade, blood = 100):
 9         super(Profector,self).__init__(gun, grenade, blood)
10 
11 
12 class Gengster(Person):
13 
14     def __init__(self, gun, grenade, blood=100):
15         super(Gengster, self).__init__(gun, grenade, blood)
16 
17 # 这里面有个supper,他就是对父类的继承

好人和坏人

我知道大家看的有点迷了,我把他整在一起了,不过还是建议大家先根据每个小模块学习,顺便理解一下引入自定义模块。下面是完整代码,可以直接粘贴:

all代码:

1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 
 4 class Bulletbox(object):
 5     def __init__(self,bulletcount):
 6         self.bulletcount = bulletcount
 7 
 8 
 9 class Gun(object):
10     def __init__(self,bulletbox):
11         self.bulletbox = bulletbox
12 
13     def shoot(self):
14         if self.bulletbox.bulletcount == 0:
15             print('没子弹了')
16         else:
17             self.bulletbox.bulletcount -= 1
18             print(str(self) + '开一枪,还剩%d颗子弹' % (self.bulletbox.bulletcount))
19 
20 
21 class Grenade(object):
22     def __init__(self,grenadecount):
23         self.grenadecount = grenadecount
24 
25     def damage(self):
26         if self.grenadecount == 0:
27             print('手雷没有了')
28         else:
29             self.grenadecount -= 1
30             print(str(self) + "轰他一炮,手雷还剩%d颗" % (self.grenadecount))
31 
32 
33 class Person(object):
34     def __init__(self, gun, grenade, blood):
35         self.gun = gun
36         self.grenade = grenade
37         self.blood = blood
38 
39     def fire(self, person):
40         person.blood -= 5
41         self.gun.shoot()
42         print(str(person) + "血量减少5,剩余" + str(person.blood) )
43 
44     def fire2(self, person):
45         person.blood -= 10
46         self.grenade.damage()
47         print(str(person) + "血量减少10,剩余" + str(person.blood) )
48 
49     def fillbullet(self):
50         self.gun.bulletbox.bulletcount += 10
51 
52     def fillblood(self,num):
53         self.blood += num
54         if self.blood > 100:
55             self.blood = 100
56         print(str(self) + "补血后血量:" + str(self.blood))
57 
58 
59 class Profector(Person):
60     def __init__(self, gun, grenade, blood = 100):
61         super(Profector,self).__init__(gun, grenade, blood)
62 
63 
64 class Gengster(Person):
65     def __init__(self, gun, grenade, blood=100):
66         super(Gengster, self).__init__(gun, grenade, blood)
67 
68 
69 bulletbox = Bulletbox(10)
70 gun = Gun(bulletbox)
71 grenade = Grenade(20)
72 
73 good1 = Profector(gun,grenade)
74 good2 = Profector(gun,grenade)
75 bad1 = Gengster(gun,grenade)
76 bad2 = Gengster(gun,grenade)
77 
78 print("好人1开枪打坏人1和2")
79 good1.fire(bad1)
80 good1.fire(bad2)
81 print("好人2开枪打坏人1和2")
82 good2.fire(bad1)
83 good2.fire(bad2)
84 print("坏人1炸好人1和2")
85 bad1.fire2(good1)
86 bad1.fire2(good2)
87 print("坏人2炸好人1和2")
88 bad2.fire2(good1)
89 bad2.fire2(good2)
90 print("坏人1补血3个")
91 bad1.fillblood(3)

all

我在这里还想和大家一起看一下结果:

 

看一下有没有发现什么问题呢?

  血量减少的人的对象还是正常的,然而看一下开枪的人。有没有发现好人1和好人2的对象时同一个地址呢,他们的子弹也是累积的递减;坏人使用手榴弹也是。为什么开枪的人会是这样,而受伤的人却是正常的呢?

  提醒一下,我们前面创建的那些对象,有些是为了下一个对象调用而准备的,看看出错是在那个模块里错的,出错的和正确的他们之间有哪些不一样呢,而且出错的原理是什么呢?大家可以思考思考,评论区互相讨论一下。

  

  今天就到这里了,大家多多互动,互相学习。希望路过的大佬指点指点。

作者:渔单渠 微信搜索“小田学Python”

出处:https://www.cnblogs.com/yudanqu/

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是关于Python封装继承多态的面试题: 1. 什么是封装?如何实现? 封装是面向对象编程中的一种重要概念,它指的是将数据和方法包装在类中,对外部世界隐藏类的内部细节,从而提高了代码的安全性和可维护性。在Python中,可以通过将属性设置为私有属性,并提供公有的访问方法来实现封装。 2. 什么是继承?如何实现? 继承是面向对象编程中的一种重要机制,它指的是一个类可以通过继承另一个类的属性和方法来扩展自己。在Python中,可以通过在类定义中指定要继承的父类来实现继承。 3. 什么是多态?如何实现? 多态是面向对象编程中的一种重要特性,它指的是同一个方法可以被不同的对象调用,产生不同的结果。在Python中,可以通过方法重写和方法重载来实现多态方法重写指的是子类重写父类的方法,从而实现不同的功能;方法重载指的是在同一个类中定义多个同名方法,但参数类型和个数不同,调用时编译器会根据实际参数类型和个数选择调用哪个方法。 4. 在Python中如何实现接口? 在Python中,没有像Java和C#等语言中的接口概念。但是可以通过抽象基类(Abstract Base Class,简称ABC)来实现类似于接口的功能。ABC是Python中的一种特殊类,它不能被实例化,只能被继承,子类必须实现指定的抽象方法,从而保证了程序的正确性和可维护性。 以上就是关于Python封装继承多态的面试题,希望能对你有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值