6)面向对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6)面向对象相关的知识,希望对你有一定的参考价值。

                                     面向对象

 

游戏人狗大战:

# 函数 基础数据类型 循环 文件处理 模块
# 游戏公司
# 人狗大战
# 两个角色
# 人
    # 昵称
    # 性别
    # 生命值
    # 战斗力
    # 背包
# 狗
    # 昵称
    # 品种
    # 生命值
    # 战斗力

 

通过之前的函数来实现:

def Person(name,sex,hp,dps): #人模子
    dic = {'name':name,'sex':sex,'hp':hp,'dps':dps,'bag':[]}
    return dic
alex = Person('alex','N/A',250,5)

def Dog(name,kind,hp,dps): #狗模子
    dic = {'name':name,'kind':kind,'hp':hp,'dps':dps}
    return dic
ha2 =Dog('哈士奇','藏獒',15000,200)

def attack(person_name,dog_name,person_dps,dog_hp):
    print('%s打了%s,%s掉了%s点血,剩余%s点血' %(person_name,dog_name,dog_name,person_dps,dog_hp-person_dps))

attack(alex['name'],ha2['name'],alex['dps'],ha2['hp'])

 

 

但是患有个问题是狗血没掉:

print(ha2)

 

alex打了哈士奇,哈士奇掉了5点血,剩余14995点血

{'name': '哈士奇', 'hp': 15000, 'kind': '藏獒', 'dps': 200}

 

 

 

接下来进行修改:得到新内容:

 

 

def Person(name,sex,hp,dps): #人模子
    dic = {'name':name,'sex':sex,'hp':hp,'dps':dps,'bag':[]}
    return dic
alex = Person('alex','N/A',250,5)

def Dog(name,kind,hp,dps): #狗模子
    dic = {'name':name,'kind':kind,'hp':hp,'dps':dps}
    return dic
ha2 =Dog('哈士奇','藏獒',15000,200)
#人打狗
def attack(person,dog):
    dog['hp'] -= person['dps']
    print('%s打了%s,%s掉了%s点血,剩余%s点血' %(person['name'],dog['name'],dog['name'],person['hp'],dog['hp']))

attack(alex,ha2)
print(ha2)

alex打了哈士奇,哈士奇掉了250点血,剩余14995点血

{'name': '哈士奇', 'dps': 200, 'kind': '藏獒', 'hp': 14995}

 

 

 

#狗咬人

def bite(dog,person):
    person['hp'] -= dog['dps']
    print('%s咬了%s,%s掉了%s点血,剩余%s点血' % (dog['name'], person['name'], person['name'], dog['dps'],person['hp']))

bite(ha2,alex)
print(alex)

 

哈士奇咬了alex,alex掉了200点血,剩余50点血

{'name': 'alex', 'sex': 'N/A', 'dps': 5, 'hp': 50, 'bag': []}

 

 

 

 

这里患有一个问题

就是传参不固定会发生人咬狗事件,要想办法固定




def Person(name,sex,hp,dps): #人模子
    dic = {'name':name,'sex':sex,'hp':hp,'dps':dps,'bag':[]}

    def attack(dog):
        dog['hp'] -= dic['dps']
        print('%s打了%s,%s掉了%s点血,剩余%s点血' % (dic['name'], dog['name'], dog['name'], dic['hp'], dog['hp']))
    dic['attack'] = attack          #防止在外部去调用里面的信息调用不到
    return dic
alex = Person('alex','N/A',250,5)

def Dog(name,kind,hp,dps): #狗模子
    dic = {'name':name,'kind':kind,'hp':hp,'dps':dps}

    def bite(person):
        person['hp'] -= dic['dps']
        print('%s咬了%s,%s掉了%s点血,剩余%s点血' % (dic['name'], person['name'], person['name'], dic['dps'], person['hp']))
    dic['bite'] = bite    #防止在外部去调用里面的信息调用不到
    return dic
ha2 =Dog('哈士奇','藏獒',15000,200)
#人打狗
print(alex['attack'])
alex['attack'](ha2)

ha2['bite'](alex)




# 面向对象的编程思想
# 人狗大战
# 创建一个人
# 创建一个狗
# 人打狗 —— 函数
# 狗咬人 —— 函数

# 造模子 —— 面向对象
# 规范了一类角色的属性项目、属性的名字、技能、技能的名字
# 权限 有一些函数 只能是这个角色才能拥有 才能调用 

 

技术分享图片

面向对象规则:

 

 

类:

具有相同属性和相同动作的一类事物,组成一个类

是抽象的

就是一个模子

 

对象:

具体的某一个具有实际属性 和具体动作的一个实体

是具体的

 

类的语法:

Class   类名:

静态属性= 任何属性 None

def 动态属性(self):pass

 

 

只要写在类名中的名字,不管是变量名换是函数名,不能在类外直接调用

只能通过类名来使用它

 

Print(类名.静态属性)

 

1)类名的功能--------》查看静态属性

 

 


 

 

 

 

2)类的第二功能====实例化(创造对象)

 

 

 

 

Class Persion

Pass

 

Alex = persion()

Print(alex)   #对象= 类名()

Print(Persion)

 

 

 

 

写进来

 

 

 

 

 

 

类的实例化过程:————==++

 

 技术分享图片

技术分享图片

技术分享图片

总结:

# 类  : 具有相同属性和相同动作的一类事物 组成一个类
# 对象 : 具体的某一个具有实际属性 和具体动作的一个实体

# 类是抽象的
# 对象是具体的
# 类被创造出来 就是模子 是用来描述对象的

# class 类名:
#     静态属性 = 123
#     def 动态属性(self):
#         # 在类中的方法的一个默认的参数,但也只是一个形式参数,约定必须叫self
#         print('-->',self)
#
# # 只要是写在类名中的名字 不管是变量还是函数名 都不能在类的外部直接调用
# # 只能通过类名来使用它
# # 类名的第一个功能是 —— 查看静态属性
# print(类名.静态属性)   # 查看
# 类名.静态属性 = 456    # 修改
# print(类名.静态属性)
# 类名.静态属性2 = 'abc'# 增加
# print(类名.静态属性2)
# # del 类名.静态属性2  #删除
# # print(类名.静态属性2)
# print(类名.__dict__)   # 类中必要的默认值之外 还记录了程序员在类中定义的所有名字

# 类名可以查看某个方法,但是一般情况下 我们不直接使用类名来调用方法
# print(类名.动态属性)
# 类名.动态属性(1)


# 类的第二个功能是 —— 实例化(创造对象)  对象= = 类名()
# class Person:pass
#
# alex = Person()
# 对象 = 类名()
# print(alex)  # object
# print(Person)
# alex name hp dps bag sex
# print(alex.__dict__)
# # alex.__dict__['name'] = 'alex'
# # alex.__dict__['sex'] = '不详'
# # alex.__dict__['hp'] = 250
# # alex.__dict__['dps'] = 5
# # alex.__dict__['bag'] = []
# # print(alex.__dict__)
# alex.name = 'alex'   # 给alex对象添加属性
# alex.hp = 250
# alex.dps = 5
# alex.sex = '不详'
# alex.bag = []
# print(alex.__dict__)

class Person:
    def __init__(self,name,hp,dps,sex):
        self.name = name
        self.hp = hp
        self.dps = dps
        self.sex = sex
        self.bag = []

alex = Person('alex',250,5,'N/A')
print('alex : ',alex)
print(alex.__dict__)
print(alex.name)
# 为什么会执行init中的内容?
# self到底是什么?
# 实例化的过程
# 类名()就是实例化
# 在实例化的过程中 发生了很多事情是外部看不到的
# 1.创建了一个对象
# 2.自动调用__init__方法
# 这个被创造的对象会被当做实际参数传到__init__方法中,并且传给第一个参数self
# 3.执行init方法中的内容
# 4.自动的把self作为返回值 返回给实例化的地方

 

 

 

对象名。方法名 相当与调用一个函数,这个函数默认吧对象作为第一个参数传入函数

 

class Person:
    def __init__(self,name,hp,dps,sex):
        self.name = name
        self.hp = hp
        self.dps = dps
        self.sex = sex
        self.bag = []
    def attack(self,dog):
        dog.hp -= self.dps
        print('%s打了%s,%s掉了%s点血,剩余%s点血' % (self.name,dog.name,dog.name,self.dps,dog.hp))


class Dog:
    def __init__(self,name,kind,hp,dps):
        self.name = name
        self.kind = kind
        self.hp = hp
        self.dps = dps

    def bitte(self,person):
        person.hp -= self.dps
        print('%s咬了%s,%s掉了%s点血,剩余%s点血' % (self.name,person.name,person.name,self.dps,person.hp))


ha2 = Dog('哈士奇','藏獒',1500,200)
alex = Person('alex',250,5,'N/A')
alex.attack(ha2)# Person.attack(alex)
ha2.bitte(alex)

 

#对象名.方法名 相当于调用一个函数,默认吧对象作为第一个参数传入函数

 技术分享图片


from  math import pi


#类 园  属性 方法

class Circle:
    def __init__(self,r):
        self.r = r

    def area(self):  #面积
        return pi * self.r**2

    def perimeter(self): #周长
        return self.r*pi*2
c1 = Circle(2)

 

 

每一个角色都有属于自己的属性和方法

当一个类在创建一个实例的时候,就产生了一个这个实例和类之间的联系

可以通过实例  对象找到实例化他的类

  技术分享图片技术分享图片

在访问变量的时候,都先使用自己的命名空间中的,如果自己的空间中没有,再到类的空间中去找

在使用对象修改静态变量的过程中,相当于在自己的空间中创建了一个新的变量

 

在类的静态变量中操作,应该使用类名来直接进行操作,不会出现乌龙问题

 

 

 

 技术分享图片

class Foo:
    count = 0
    def __init__(self):
        Foo.count +=1

f1 = Foo()
print(Foo.count)
[Foo() for i in range(10)]
print(Foo.count)

 组合:

技术分享图片

 

继承:解决代码的冗余

可以多继承

 

单继承:

 

class Parent:
    pass

class Son(Parent):
    pass

#Son这个类继承了Parent类
#父类、基类、超类----Parent类
#子类、派生类-----Son类

 

 

多继承:

class Parent:
    pass

class Parent2:
    pass

class Son(Parent,Parent2):
    pass

 

 

举个例子:

class Animal:
    def __init__(self,name,hp,dps):
        self.name = name
        self.hp = hp
        self.dps = dps
class Person(Animal):pass
class Dog(Animal):pass

alex = Person('alex',250,5)
ha2 = Person('哈士奇',15000,200)
print(alex.__dict__)
print(ha2.__dict__)

 

子类的空间找不到就到父类的里面去找

 

class Animal:
    def __init__(self,name,hp,dps):
        self.name = name
        self.hp = hp
        self.dps = dps
class Person(Animal):
    def __init__(self, name, hp, dps):
        print('-----%')
class Dog(Animal):pass

alex = Person('alex',250,5)
# ha2 = Person('哈士奇',15000,200)
print(alex.__dict__)
# print(ha2.__dict__)


#先找对象的空间----创建对象的类的内存空间-----父类的内存空间

 

 

继承例子:

 

class Animal:
    def __init__(self,name,hp,dps):
        self.name = name
        self.hp = hp
        self.dps = dps
class Person(Animal):
    def __init__(self, name, hp, dps,sex):
        Animal.__init__(self,name,hp,dps)   #继承
        self.sex = sex

class Dog(Animal):pass

alex = Person('alex',250,5,'N/A')
# ha2 = Person('哈士奇',15000,200)
print(alex.__dict__)
# print(ha2.__dict__)


#先找对象的空间----创建对象的类的内存空间-----父类的内存空间

 

 

 

在优化一下:

class Animal:   #动物类
    def __init__(self,name,hp,dps):
        self.name = name
        self.hp = hp
        self.dps = dps
class Person(Animal):  #人类
    def __init__(self, name, hp, dps,sex):
        # Animal.__init__(self,name,hp,dps)   #继承
        super().__init__(name,hp,dps)
        self.sex = sex                      #派生属性

class Dog(Animal):#狗类
    def __init__(self,name,hp,dps,kind):
        # Animal.__init__(self, name, hp,dps) #继承
        super().__init__(name,hp,dps)
        self.kind = kind                            #派生属性


alex = Person('alex',250,5,'N/A')
ha2 = Person('哈士奇',15000,200,333)
print(alex.__dict__)
print(ha2.__dict__)

 

 

class Animal:   #动物类
    def __init__(self,name,hp,dps):
        self.name = name
        self.hp = hp
        self.dps = dps
    def eat(self):   #附加属性吃药回血
        print('%s吃药回血了'%(self.name))
class Person(Animal):  #人类
    def __init__(self, name, hp, dps,sex):
        # Animal.__init__(self,name,hp,dps)   #继承
        super().__init__(name,hp,dps)
        self.sex = sex                      #派生属性

class Dog(Animal):#狗类
    def __init__(self,name,hp,dps,kind):
        # Animal.__init__(self, name, hp,dps) #继承
        super().__init__(name,hp,dps)
        self.kind = kind                            #派生属性


alex = Person('alex',250,5,'N/A')
ha2 = Person('哈士奇',15000,200,'藏獒')
print(alex.__dict__)
print(ha2.__dict__)
ha2.eat()

 技术分享图片

对象的内存空间---创建的对象的类的内存空间------父类的内存空间

技术分享图片


class Foo:
    def __init__(self):
        self.func()
    def func(self):
        print('in Foo')

class Son(Foo):
    def func(self):
        print('in Son')

Son()

 技术分享图片

钻石继承:

class A:
    def f(self):
        print('in A')

class B(A):
    def f(self):
        print('in B')

class C(A):
    def f(self):
        print('in C')

class D(B,C):
    def f(self):
        print('in D')

d = D()
d.f()

print(D.mro())    #mro可以知道顺序

 

D----->-B----->C-------->A:查找的顺序

 

小乌龟模型:

 

 技术分享图片

技术分享图片

查找太麻烦了,这个不合理

 

技术分享图片 

这个合理每个点,出现一次

 

 


以上是关于6)面向对象的主要内容,如果未能解决你的问题,请参考以下文章

6-面向对象

[6]面向对象编程

面向对象的思考过程

第6篇-JAVA面向对象Ⅱ

python高阶6 面向对象重新梳理

python 6 面向对象