Python-27_面向对象

# 三大编程范式:
# 1、面向过程编程
# 2、函数式编程
# 3、面向对象编程
# 特点:
# 面向过程---复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现)
#            面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式
# 面向对象---解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
# 对象是具体的存在,而类仅仅只是一个概念,并不真实存在!!
# 在程序中:务必保证先定义类,后产生对象!!
#
# 如果我们把数据和动作内嵌到一个结构(函数或类)中,那么我们就有了一个“对象系统”(对象就是数据与函数整合到一起的产物)
#
#
# ##### 面向对象设计:将一类具体事物的数据和动作整合到一起,即为面向对象设计。
# ##### 面向对象编程:用定义类+实例/对象的方法去实现面向设计。
#
# 类------把一类事物的相同特征和动作整合到一起就是类,类是一个抽象的概念;
# 对象------基于类而创建的一个具体的事物(一个具体的存在),也是特征和动作整合到一起;
# 实例化------由类生产对象的过程叫实例化;

# 例子:----初接触
# def people(name,age,gender):            # 这是一个类,统称为:人
#     def eat(x):
#         print("%s正在吃饭饭,请不要打扰"%x["name"])
#     def wushu(x):
#         print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(x["name"],x["name"],x["gender"],x["age"]))
#     def feature(name,age,gender):       # 对对象进行初始化
#         dic={"name":name,"age":age,"gender":gender,"eat":eat,"wushu":wushu}
#         return dic
#     return feature(name,age,gender)
# people01=people("newmet1",15,"男")     # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
# print(people01)
# people01["wushu"](people01)
# people01["eat"](people01)

# 例子:----面向对象编程:
class people:                           # 这是一个类,统称为:人

    def eat(self):
        print("%s正在吃饭饭,请不要打扰"%self.name)
    def wushu(self):
        print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
    def __init__(self,name,age,gender):       # 初始化函数
        self.name=name
        self.age=age
        self.gender=gender
people01=people("newmet1",15,"")     # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
print(people01.__dict__)        # {'name': 'newmet1', 'age': 15, 'gender': '男'}
people01.eat()                  # newmet1正在吃饭饭,请不要打扰
people01.wushu()                # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁


# 用面向对象语言写程序(是利用class等方法写),和一个程序的设计是面向对象的,完全是两回事!!
01-面向对象设计
#--------------  类  --------------#
# class School:
#     # 这个类具体是干什么用的 #
#     pass
# v=School()        # 类的实例化(类名+())
# print(v)          # <__main__.School object at 0x00000000020A6400>

# 一、经典类、新式类
# python2 中,类分:经典类、新式类;
# python3 中,类只有新式类(就是python2中的经典类)
# 经典类:
# class 类名:
#     pass

# 新式类:
# class 类名(父类):      # 这个类继承自--父类
#     pass


# 二、类:属性:
#           1、数据属性
#           2、函数属性
class friend:
    "这是一个朋友类"
    v=111
    def s():
        print("222")

print(dir(friend))          # 查出的是一个名字列表
print(friend.__dict__)      # 查看属性字典(内存地址)
print(friend.v)             # 111
friend.s()                  # 222
print(friend.__dict__["v"]) # 111
friend.__dict__["s"]()      # 222

print(friend.__name__)      # friend
print(friend.__doc__)       # 这是一个朋友类
print(friend.__base__)      # <class 'object'>
print(friend.__bases__)     # (<class 'object'>,)
print(friend.__module__)    #  __main__
print(friend.__class__)     # <class 'type'>

"""
#python为类内置的特殊属性

类名.__name__     # 类的名字(字符串)
类名.__doc__      # 类的文档字符串
类名.__base__     # 类的第一个父类(在讲继承时会讲)
类名.__bases__    # 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__     # 类的属性字典
类名.__module__   # 类定义所在的模块
类名.__class__    # 实例对应的类(仅新式类中)

"""
02-类
class people:                           # 这是一个类,统称为:人

    def eat(self):
        print("%s正在吃饭饭,请不要打扰"%self.name)
    def wushu(self):
        print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
    def __init__(self,name,age,gender):       # 初始化函数
        self.name=name
        self.age=age
        self.gender=gender
v1=people("newmet1",15,"")     # 实例化的过程          self --- v1  其就是实例化的结果
print(v1.__dict__)        # {'name': 'newmet1', 'age': 15, 'gender': '男'}
v1.eat()      # 自动给eat传了一个self参数     # newmet1正在吃饭饭,请不要打扰
v1.wushu()    # 自动给wushu传了一个self参数   # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁

print(v1.__dict__["name"])      # newmet1
print(v1.name)                  # newmet1
03-对象
class friend:
    def __init__(self,name):
        print("名字:%s"%name)
    name="newmet"
    def play_ball(self):
        print("正在打球")

# 增加
# friend.age=18
#
# def eat():
#     print("函数属性增加")
# friend.eat=eat
# print(friend.__dict__)
# friend.eat()

# 删除
# del friend.name
# print(friend.__dict__)

# 修改
friend.name="2222"

def eat():
    print("函数属性修改")
friend.play_ball=eat
print(friend.name)
print(friend.play_ball())
04-类属性增删修查
class friend:
    def __init__(self,name):
        self.name=name
    age=18
    def play_ball(self):
        print("正在打球")
v=friend("newmet")
print(v.__dict__)

# 查看
# print(v.age)
# print(v.play_ball)

# 增加  (实例属性只能增加数据属性)
v.gender=""
print(v.__dict__)
print(v.gender)

# 修改
v.name="121"
print(v.__dict__)
print(v.name)
05-实例属性增删修查
country="中国-----------"
class Chinese:
    country="中国"
    def __init__(self,name):
        self.name=name
        print(">>>",country)                        #  没.(没实例化)  不在类中找,与实例无关
    def play_ball(self,ball):
        print("%s 正在玩 %s" %(self.name,ball))

print(Chinese.__dict__)
print(Chinese.country)          # 中国
p=Chinese("new")               # >>> 中国-----------  没.(没实例化)  不在类中找,与实例无关
print("实例化",p.country)      # 实例化 中国
06-对象与实例属性
#--------------------------------- 静态属性 --------------------------------#
# class Room:
#     def __init__(self,name,owner,length,width,height):
#         self.name=name
#         self.owner=owner
#         self.length=length
#         self.width=width
#         self.heigth=height
#     @property               # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
#     def cal_area(self):
#         # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
#         return self.length*self.width
#
# v1=Room("1号房间","new1",50,50,4)
# v2=Room("2号房间","new2",30,30,4)
# # v1.cal_area()       # new1住在叫1号房间的2500平米的房子中
# # v2.cal_area()       # new2住在叫2号房间的900平米的房子中
# # v1.cal_area           # new1住在叫1号房间的2500平米的房子中(类中增加 @property 后,不需要加括号)
# # v2.cal_area           # new2住在叫2号房间的900平米的房子中 (类中增加 @property 后,不需要加括号)
#
# print(v1.cal_area)      # 2500     @property隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
# print(v2.cal_area)      # 900
# print(v1.name)          # 1号房间      调用数据属性
# print(v2.name)          # 2号房间



#--------------------------------- 类方法 --------------------------------#
# class Room:
#     food=1
#     def __init__(self,name,owner,length,width,height):
#         self.name=name
#         self.owner=owner
#         self.length=length
#         self.width=width
#         self.heigth=height
#     @classmethod               # 将下列方法变成可以被类调用的方法
#     def cal_area(cls):
#         print(cls)                          # <class '__main__.Room'>
#         print("%s newmet"%cls.food)       # 1 newmet
#
# # v1=Room("1号房间","new1",50,50,4)
# # v2=Room("2号房间","new2",30,30,4)
# Room.cal_area()
# # 类调用自己的属性方法的时候 ,与实例没有关系


#--------------------------------- 静态方法 --------------------------------#

class Room:
    food=1
    def __init__(self,name,owner,length,width,height):
        self.name=name
        self.owner=owner
        self.length=length
        self.width=width
        self.heigth=height
    @property               # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
    def cal_area(self):
        # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
        return self.length*self.width

    @classmethod               # 将下列方法变成可以被类调用的方法
    def cal_area1(cls):
        print(cls)                          # <class '__main__.Room'>
        print("%s newmet"%cls.food)       # 1 newmet

    @staticmethod
    def bath(x):
        print("%s 正在沐浴" %x)

Room.cal_area1()

Room.bath("new")
v1=Room("1号房间","new1",50,50,4)
v1.bath("met")

# @property      ----  和实例绑定,与类无关
# @classmethod   ----  和类绑定,与实例无关
# @staticmethod  ----  和类和实例均不绑定(类的工具包)
# @staticmethod -- 静态方法只是名义上的归属类管理,不能使用类变量和实例变量,只是类的工具包

#--------------------------------- 总结 --------------------------------#

# @property      ----  能访问类的数据、函数属性以及实例的属性
# @classmethod   ----  只能访问类的属性
# @staticmethod  ----  不能访问类、实例属性
07-静态属性_方法
#--------------------- 定义锐雯类:---------------------
class Raven:
    camp='Noxus'
    def __init__(self,nickname,
                 aggressivity=54,
                 life_value=414,
                 money=1001,
                 armor=3):
        self.nickname=nickname
        self.aggressivity=aggressivity
        self.life_value=life_value
        self.money=money
        self.armor=armor
    def attack(self,enemy):
        damage_value=self.aggressivity-enemy.armor
        enemy.life_value-=damage_value

#--------------------- 定义盖伦类:---------------------
class Galen:
    camp='Demacia'
    def __init__(self,nickname,
                 aggressivity=58,
                 life_value=455,
                 money=100,
                 armor=10):
        self.nickname=nickname
        self.aggressivity=aggressivity
        self.life_value=life_value
        self.money=money
        self.armor=armor
    def attack(self,enemy):
        damage_value=self.aggressivity-enemy.armor
        enemy.life_value-=damage_value

#--------------------- 定义装备:---------------------
class BlackCleaver:
    def __init__(self,price=475,aggrev=9,life_value=100):
        self.price=price
        self.aggrev=aggrev
        self.life_value=life_value
    def update(self,obj):
        obj.money-=self.price #减钱
        obj.aggressivity+=self.aggrev #加攻击
        obj.life_value+=self.life_value #加生命值
    def fire(self,obj): #这是该装备的主动技能,喷火,烧死对方
        obj.life_value-=1000 #假设火烧的攻击力是1000

#--------------------- 测试交互:---------------------
r1=Raven('草丛伦')
g1=Galen('盖伦')
b1=BlackCleaver()

print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲

if r1.money > b1.price:
    r1.b1=b1
    b1.update(r1)


print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲

print(g1.life_value)
r1.attack(g1) #普通攻击
print(g1.life_value)
r1.b1.fire(g1) #用装备攻击
print(g1.life_value) #g1的生命值小于0就死了
08-基于面向对象设计的一个对战游戏 
# 获取指定位置上的·某个方向·指定数量的元素。
# 变化特征              "20"    右侧  0  1     (索引列r、行c、累加)
# 变化特征              "31"    上方 -1  0     (索引列r、行c、累加)
# 变化特征              "24"    左侧 0  -1     (索引列r、行c、累加)
# 变化特征              "03"    下方 1   0     (索引列r、行c、累加)

#
# def get_elements(list_target,r_index,c_index,r_dir,c_dir,count):
#     """
#     获取指定位置上的·某个方向·指定数量的元素。
#     :param list_target: list
#     :param r_index:列索引
#     :param c_index:行索引
#     :param r_dir:方向
#     :param c_dir:方向
#     :param count:次数--数量
#     :return:
#     """
#     result = []
#     for item in range(count):
#         r_index += r_dir
#         c_index += c_dir
#         result.append(list_target[r_index][c_index])
#     return result
#
#
# list01=[
#     ["00","01","02","03","04"],
#     ["10","11","12","13","14"],
#     ["20","21","22","23","24"],
#     ["30","31","32","33","34"],
#     ["40","41","42","43","44"]
# ]
#
#
# print(get_elements(list01,2,4,0,-1,3))


"""
该方式是:面向过程

缺点:
    1.代码可读性差
    2.每次调用方法,都需要思考方向(索引变化)的特征
    

    
"""


# 解决方法:
#       1.使用一个类,包装两个数据(行/列)
#       2.利用静态方法
class Vector2:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # def right(self):
    #     return Vector2(0,1)

    # 静态方法:不依赖于对象、类
    @staticmethod
    def right():
        return Vector2(0, 1)

    @staticmethod
    def up():
        return Vector2(-1, 0)

    @staticmethod
    def down():
        return Vector2(1, 0)

    @staticmethod
    def left():
        return Vector2(0, -1)


def get_elements(list_target, vect_pos, vect_dir, count):
    """
    获取指定位置上的·某个方向·指定数量的元素。
    :param list_target: list
    :param r_index:列索引
    :param c_index:行索引
    :param r_dir:方向
    :param c_dir:方向
    :param count:次数--数量
    :return:
    """
    result = []
    for item in range(count):
        vect_pos.x += vect_dir.x
        vect_pos.y += vect_dir.y
        result.append(list_target[vect_pos.x][vect_pos.y])
    return result


list01 = [
    ["00", "01", "02", "03", "04"],
    ["10", "11", "12", "13", "14"],
    ["20", "21", "22", "23", "24"],
    ["30", "31", "32", "33", "34"],
    ["40", "41", "42", "43", "44"]
]

print(get_elements(list01, Vector2(2, 0), Vector2.right(), 3))
09-静态方法_精华案例

 

posted on 2019-03-11 16:16  NewMet  阅读(118)  评论(0编辑  收藏  举报

导航