python——类与对象

面向过程与面向对象

程序包括:

  • 数据:数据类型,数据结构
  • 处理过程:算法

两种程序设计思想

面向过程:

  • 面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度(C语言)
  • 以操作(函数)为主体,然后把对象作为参数传给主体。
#处理学生信息
# 1.用字典存储姓名和分数
student1 = {'name': '小贝', 'score': 98}
student2 = {'name': '闻闻', 'score': 93}

# 2.定义打印分数的函数
def print_score(student):
  print('姓名:%s,分数:%d' % (student['name'], student['score']))

# 3.调用打印分数的函数
print_score(student1)
print_score(student2)

面向对象:

  • 把计算机程序视为一组对象的集合,而每一个对象都可以接受其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递(python语言)
  • 以数据为主体,然后把特征或者动作分别作为对象的属性和方法。
# 1.定义学生类
class Student:
  def __init__(self, name, score):
    self.name = name
    self.score = score

  def print_score(self):
      print('姓名:%s,分数:%d' % (self.name, self.score))

# 2.实例化学生类
student1 = Student('小贝', 98)
student2 = Student('闻闻', 93)

# 3.调用实例的方法
student1.print_score()
student2.print_score()

区别:

在这里插入图片描述

  • 描述相似对象的共性,对象是类的实例。
    • 包括:数据(属性)、操作(方法)

类定义

语法:
calss<类名>:
	<方法定义>

类对象

  • 类对象支持两种操作:属性引用和实例化
  • 属性引用使用和python中所有的属性引用一样的标准语法:obj.name
  • 类对象创建以后,类命名空间中所有的命名都是有效属性名。
  • 在类中,定义的变量就是一个属性,定义的一个函数就是一个方法。
class Human:	#定义一个类,类名首字母要大写
  # 这是两个属性,相当于平时的变量
  arms = 2
  legs = 2
  hair = '各种颜色的头发'
  
  #这是类的方法,相当于我们定义的函数,但是函数第一个参数必须是self
  def walk(self):	
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

# 类的实例化
human = Human()

print(human.arms)
# 输出:2

print(human.legs)
# 输出:2

print(human.hair)
# 输出:各种颜色的头发

human.walk()
# 输出:直立行走

human.speak()
# 输出:说着各式各样的语言

类定义中self的含义

  • self 表示创建的实例本身
'''   错误示例  '''
class Human:
  arms = 2
  legs = 2
  hair = '各种颜色的头发'

  def walk(self):
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

  def intro(self):
    # 类的方法里访问类的属性
    print('人类有%d条胳膊%d条腿' % (arms, legs))

# 类的实例化
human = Human()

'''
 我们在类的方法里直接访问类的属性是不行的。
 访问类的属性要先实例化,然后通过 实例名.属性 进行访问,
 类的方法内访问类的属性时,类的实例还没被创建。这时候我们就用到了self
 '''
human.intro()
# 报错:NameError: name 'arms' is not defined on line 14
''' 修改后的代码 '''
class Human:
  arms = 2
  legs = 2
  hair = '各种颜色的头发'

  def walk(self):
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

  def intro(self):
    # 类的方法里访问类的变量
    print('人类有%d条胳膊%d条腿' % (self.arms, self.legs))	#这里加入了self 
	'''
	当执行 human.intro() 这行代码时,Python 会将 human 作为第一个参数偷偷传递给
	self,这样我们就不再需要传入第一个参数,并能通过 self 访问类的属性和方法了。
	'''
# 类的实例化
human = Human()

human.intro()
# 输出:人类有2条胳膊2条腿
总结:
  • 创建类方法时,第一个参数一定要设置为self,但是调用的时候要忽略他。
  • 在类内使用定义的方法(函数)或者是属性(变量)时,要用self.方法()或者是self.属性。

初始化方法def __init__(self):

PS:init左右是两个下划线!!!

  • 使用初始化方法后,当函数实例化之后,该方法会自动被执行。
  • 当实例化完成之后,初始化方法会自动执行,这样我们就完成了自定义的属性初始值设置。然后我们可以通过 实例名.属性名 在类外访问或 self.属性名 在类的方法中访问了。
class Human:
  # 除了进行固定的初始值设置,初始化方法 可以接收其他参数,进行自定义的属性初始值设置
  def __init__(self, name, arms, legs, hair):
    # self.不能丢
    self.name = name
    self.arms = arms
    self.legs = legs
    self.hair = hair

  def walk(self):
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

  def intro(self):
    print('我叫{},我有{}'.format(self.name, self.hair))

#类实例化,同时给类传入四个参数给__init__()函数
xiaobei = Human('小贝', 2, 2, '粉红色的头发')	
print(xiaobei.name)
# 输出:小贝

xiaobei.intro()
# 输出:我叫小贝,我有粉红色的头发

描述类 __str__(self):

PS:同样,str左右是两个下划线!!!
PS2:__str__(self):方法最后要用return返回,不可以用print。

class Human:
  arms = 2
  legs = 2
  hair = '各种颜色的头发'

  def __str__(self):
    return '人类有%d条胳膊%d条腿' % (self.arms, self.legs)

  def walk(self):
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

human = Human()
#实例化之后,我们直接print(实例名),结果为 __str__() 方法的返回值
print(human)
# 输出:人类有2条胳膊2条腿

类继承

class 子类(父类):

class Human:
  arms = 2
  legs = 2
  hair = '各种颜色的头发'

  def walk(self):
    print('直立行走')

  def speak(self):
    print('说着各式各样的语言')

#Chinese类中什么都没有,但是他继承了Human类,就可以直接调用Human类中的属性和方法
class Chinese(Human):
  pass

xiaobei = Chinese()

print(xiaobei.arms)
# 输出:2

xiaobei.walk()
# 输出:直立行走

多层继承

语法:
class B (A):	#B继承了A类,B就可以调用A类中的属性和方法
	pass
class C (B):	#C继承了B类,C就可以调用B的东西,也就可以调用A的东西
	pass
# 师傅
class Master:
  book = '九阴真经'

  def kungfu(self):
    print('九阴白骨爪')

# 徒弟
class Apprentice(Master):
  book2 = "九阳神功"		#徒弟可以新增一个属性
  
  def kungfu(self):		#徒弟对师傅类中的kungfu方法进行重写,调用徒弟之后结果就会改变
    print("九阴白骨爪改进版")
  
  def kungfu2(self):	#徒弟还可以新增一个方法
    print("金刚不坏之躯")

xiaobei = Apprentice()

print(xiaobei.book)
#输出:九阴真经
print(xiaobei.book2)
#输出:九阳神功
xiaobei.kungfu()
#输出:九阴白骨爪改进版
xiaobei.kungfu2()
#输出:金刚不坏之躯

多重继承

语法:
class D (A,B,C):
class Chinese:
  hair = '黑头发'
  skin = '黄皮肤'

  def speak_chinese(self):
    print('说汉语')

class American:
  hair = '金头发'
  skin = '白皮肤'

  def speak_english(self):
    print('说英语')

#横向继承,调用属性或者方法时,从左到右依次寻找,如果第一个没有,就从第二个寻找;
#如果都没有,就会报错
#新建和重写跟多层继承一样
class ABC(Chinese, American):
  pass

abc = ABC()

print(abc.hair)
# 输出:黑头发

print(abc.skin)
# 输出:黄皮肤

abc.speak_chinese()
# 输出:说汉语

abc.speak_english()
# 输出:说英语

小游戏(天下第一武道大会)

from random import randint, random


class Player:
    def __init__(self, name):
        self.name = name
        self.health = 100

    def attack(self, target):  # 攻击方法:攻击者 attack target

        print(self.name + '发起攻击')  # self.name 为攻击者
        damage = randint(10, 20)	#随机伤害
        baoji = randint(30,60)	#随机暴击
        target.defend(damage,baoji, self.name)

    def defend(self, damage,baoji, attack_name):  # 防御方法:以下的 self.health 和 self.name 均为被攻击者target
        # 补全 defend() 方法
        pi = randint(1, 100)
        if 20 < pi <= 80:	
            self.health = self.health - damage
            print("{0}受到来自{3}的{1}点伤害,血量剩余{2}".format(self.name, damage, self.health, attack_name))
            if self.health <= 0:
                print("{}被击败".format(self.name))

        elif pi > 80:	#20%几率产生暴击
            self.health = self.health - baoji
            print("{3}发动致命一击!{0}受到{1}点伤害,血量剩余{2}".format(self.name, baoji, self.health, attack_name))
            if self.health <= 0:
                print("{}被击败".format(self.name))

        else:	#20%几率产生防御
            print("{}防御成功".format(self.name))


kakarotto = Player('孙悟空')
piccolo = Player('比克大魔王')

# 使用循环轮番攻击,当有人被击败后停止循环
i = 1
while True:
    if kakarotto.health > 0:
        kakarotto.attack(piccolo)
        print("第{}回合结束".format(i).center(20, '-'))
        i += 1
    else:
        break
    if piccolo.health > 0:
        piccolo.attack(kakarotto)
        print("第{}回合结束".format(i).center(20, '-'))
        i += 1
    else:
        break

其中attck() 方法和 defend() 方法中的self.name不一样
在这里插入图片描述

孙悟空发起攻击
比克大魔王防御成功
-------1回合结束-------
比克大魔王发起攻击
孙悟空受到来自比克大魔王的12点伤害,血量剩余88
-------2回合结束-------
孙悟空发起攻击
比克大魔王受到来自孙悟空的12点伤害,血量剩余88
-------3回合结束-------
比克大魔王发起攻击
比克大魔王发动致命一击!孙悟空受到55点伤害,血量剩余33
-------4回合结束-------
孙悟空发起攻击
比克大魔王受到来自孙悟空的14点伤害,血量剩余74
-------5回合结束-------
比克大魔王发起攻击
孙悟空受到来自比克大魔王的16点伤害,血量剩余17
-------6回合结束-------
孙悟空发起攻击
孙悟空发动致命一击!比克大魔王受到59点伤害,血量剩余15
-------7回合结束-------
比克大魔王发起攻击
孙悟空受到来自比克大魔王的16点伤害,血量剩余1
-------8回合结束-------
孙悟空发起攻击
比克大魔王受到来自孙悟空的15点伤害,血量剩余0
比克大魔王被击败
-------9回合结束-------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值