Python-初识面向对象

什么是面向对象?

面向对象指的是一门编程的思想,python中一切皆对象。

面向过程 VS 面向对象

  • 面向过程编程:

核心是 “过程” 二字,过程指的是做事情的步骤,即先做什么再做什么,

基于该编程思想写程序,就好比一个工厂流水线,一种机械式的思维方式

优点:逻辑清晰,复杂的问题简单化

缺点:可扩展性差

  • 面向对象编程:

核心是 “对象” 二字,对象指的是特征和技能的结合体

基于该编程思想写程序,就好比在创造世界,一种上帝式的思维方式

优点:可扩展性高

缺点:编写程序复杂程度高

那么我们在编程的时候优先使用 面向过程思想 呢?还是面向对象思想呢?

通常是两者结合在一起使用

类与对象定义

对象:特征和技能的结合体

类:一系列对象相同的特征和技能的结合体

在现实生活中 先有一个一个对象,然后再有人们对类的概念,
在程序中 必须定义好类,然后调用类来创造对象

定义类:

​ class 类名
​ 相同的特征
​ 相同的技能

class Stut:	# 类名,遵循驼峰体命名规范,首字母大写
    # 特征
    school = "oldboy"
    # 技能
    def learn(self):
        print("learning...")

定义类发生的两件事情

  1. 生成一个空的名称空间
  2. 把类内部所有名字,扔进类的名称空间中
  • 注意:类在定义阶段产生好了名称空间,执行py文件时候会执行类内部的代码

创建对象

语法:类名 + () 调用产生对象

-------类调用-------
# 在我们定义好类之后,我们可以调用类的属性和方法
print(Stut.__dict__.get("school"))		# 类名.__dict__获取类内部全部属性
Stut.learn(123)		# 使用Stut的learn方法,此时由类来调用类内部的函数,该函数只是一个普通的函数,类内部learn函数有一个形参,那么在调用的时候也必须传一个参数才能调用


-------对象调用-------
s1 = Stut()	# s1 -》 <__main__.Stut object at 0x0000000009FA9DD8>
#在我们实例化类 创建出来一个s1对象之后,我们可以使用对象.属性来调用
print(s1.school)
s1.learn()		# 由对象来调用类内部的方法,self即对象本身,作为第一个参数传入。

创建对象(即调用类) 发生的三件事情

  1. 生成一个空的对象空间,
  2. 会自动触发类内部的 __init__函数
  3. 会把创建的对象本身以及调用类传入的参数一并传入给 init 函数
class OldboyStudend:
    """学生类"""
    # 给不同对象添加不同特征的方式二:
    def __init__(self,name,age,sex):
        # self 就是创建出来的对象本身,对象.属性 可以获取不同对象的属性
        self.name = name
        self.age = age
        self.sex = sex
        print("调用类就运行__init__函数",name,age,sex)

    school = "oldboy"

    def learn(self):
        print("正在learn...")

    def chooice_course(self):
        print("正在chooice_course...")

# print(OldboyStudend.__dict__.get("school"))


s1 = OldboyStudend("qinyj",21,"男")    # 创建出一个 名 s1的对象
s2 = OldboyStudend("jack",22,"男")    # 创建出一个 名 s2的对象
print(s1.school)        # 调用类的特征
print(s2.school)        # 调用类的特征


'''
问题:不同的对象特征技能一样,如何能不一样
解决:两种方式:
    - 在类内部定义 __init__ 函数
    - 创建出对象后单独添加属性
'''

# 给不同对象添加不同特征的方式一:
s1.name = "qinyj"
s1.age = "21"
s1.sex = "female"

s2.name = "jack"
s2.age = "22"
s2.sex = "female"
print(s1.name,s1.age,s1.sex)
print(s2.name,s2.age,s2.sex)

对象与类的查找顺序

对象中属性的查找顺序:

  1. 对象.属性 若对象本身有,则优先查找对象自己的
  2. 若对象本身没有,则去类里面找
  3. 若类没有,则报错
class OldboyStend:
    SCHOOL = "oldboy"
    NAME = "DDDDDDDD"

    def __init__(self,name,age,sex,school):
        self.name = name
        self.age = age
        self.sex = sex
        self.SCHOOL = school

s1 = OldboyStend("qinyj",22,"男","oldgirl")
print(s1.SCHOOL)
# oldgirl

print(s1.NAME)
# DDDDDDDD

对象绑定方法

类内部的函数主要是给对象用的

  1. 类来调用类内部的函数,这时候这个函数就是一个普通的函数,这个函数有一个形参,调用的时候必须传入几个参数
  2. 对象来调用类内部的函数 称之为对象的绑定方法,不同的对象调用该绑定方法,则会将不同的对象传入该绑定方法中
  3. 对象的绑定方法 是由对象来调用的,特殊之处就是把对象当做第一个参数传入该方法中
class OldboyStend:
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def learn(self):
        print(f"{self.name} 正在learn...")

s1 = OldboyStend("qinyj",22,"男")
s1.learn()
# qinyj 正在learn...

print(s1.learn)     # bound method 称之为对象的绑定方法   不再是一个普通的函数了
# <bound method OldboyStend.learn of <__main__.OldboyStend object at 0x000000000296C400>>

实战-人狗大作战

'''
需求:
    人 对象
    狗 对象
    人狗互咬,如果一方生命值为0,则该程序就结束

定义两个类:
    人类
    狗类
'''

class People:
    def __init__(self,name,damage,life):
        # 对象特有的特征
        self.name = name
        self.damage = damage
        self.life = life
    # 人咬狗 技能
    def bite(self,dog):
        if dog.life <= 0:
            return True
        if self.life == 0:
            print(f"{self.name} 死了,{dog.name} 赢了")
            return
        dog.life -= self.damage
        print(f'''
        人:[{self.name}] 开始咬狗:[{dog.name}]
        狗掉血:[{self.damage}]
        狗剩余血量:[{dog.life}]
        ''')

class Dog:
    def __init__(self,name,damage,life):
        # 对象特有的特征
        self.name = name
        self.damage = damage
        self.life = life

    # 狗咬人 技能
    def bite(self, people):
        if people.life <= 0:
            return True
        if self.life == 0:
            print(f"{self.name} 死了,{people.name} 赢了")
            return
        people.life -= self.damage
        print(f'''
        狗:[{self.name}] 开始咬人:[{people.name}]
        人掉血:[{self.damage}]
        人剩余血量:[{people.life}]
        ''')

people = People("qinyj",200,1000)
dog = Dog("哈士奇",500,400)
while True:
    flg1 = people.bite(dog)
    if flg1:
        break
    flg2 = dog.bite(people)
    if flg2:
        break

终端打印结果:

        人:[qinyj] 开始咬狗:[哈士奇]
        狗掉血:[200]
        狗剩余血量:[200]
        

        狗:[哈士奇] 开始咬人:[qinyj]
        人掉血:[500]
        人剩余血量:[500]
        

        人:[qinyj] 开始咬狗:[哈士奇]
        狗掉血:[200]
        狗剩余血量:[0]
        
哈士奇 死了,qinyj 赢了

小结

面向过程编程:
        核心是“过程”二字,过程指的是做事情的步骤,即先做什么再做什么
        基于该编程思想编写程序,就好比一条工厂流水线,一种机械式的思维方式。
            优点:逻辑清晰,复杂的问题流程化,进而简单化。
            缺点:可扩展性差。
    面向对象编程:
        核心是“对象”二字,对象指的是特征与技能的结合体。
        基于该编程思想编写程序,就好比在创造世界,一种上帝式的思维方式。
            优点:可扩展性高。
            缺点:编写程序的复杂程度要远高于面向过程编程思想。

    在定义类发生的事情:
        1.类在定义时,会产生一个空的名称空间。
        2.会把类内部所有名字,扔进类的名称空间中。
        注意: 类在定义阶段就已经产生好了名称空间,执行python文件时会执行类内部的代码。


    调用类发生的事情(******):
        1.首先会产生一个空的对象,就是产生“对象的名称空间”。
        2.会自动触发__init__。
        3.会把对象本身以及括号内的参数一并传给__init__函数。
        总结: 调用类会产生一个对象,调用类的过程叫做类的实例化,产生的对象称之为类的一个实例.


    __init__: 会在调用类时,自动触发该函数。

	对象绑定方法特殊之处
        1.类调用类内部的函数,只是调用普通函数.
        2.对象的绑定方法特殊之处(*******):
            - 由对象来调用的,会把对象当作第一个参数传入该方法中
            - 由不同的对象来调用,就会把不同的对象传给不同的绑定方法.
posted @ 2019-10-09 15:13  GeminiMp  阅读(221)  评论(0编辑  收藏  举报