面向对象、类

python

一、面向对象

什么是面向对象

  面向对象是一门编程思想!

  

  面向过程编程思想与面向对象编程思想对比:

    - 面向过程编程思想:

      核心是 “过程”二字,过程是指解决问题的步骤,即先干什么再干什么!

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

      优点:

        将复杂的问题流程化,进而简单化

      缺点:

        牵一发而动全身,程序的可扩展性差

    - 面向对象编程思想:

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

      基于该编程思想编写程序,就好比把自己当做一个上帝在创造世界,一种“上帝式”的思维方式

      优点:

        可扩展性高

      缺点:

        面向对象编写程序的复杂程度比面向过程高

  注意:编程思想仅仅是一门思想,与任何技术无关

二、类

1、什么是类?

  类指的是类型、类别。

  在两种角度去看待类:

    - 现实世界中:

      - 先有一个个对象,经过社会的文明发展,随之总结出类,对象是实际存在的,而类是抽象产生的

    - python程序中:

      - 必须先由类,再通过调用类产生对象

 

  对象指的是“特征与技能”的结合体, 类指的是一系列“对象之间相同的特征与技能”的结合体

2、如何定义类?

  如何写类并产生对象:

    - 先从现实世界中通过一个个对象总结出类

    - 然后再定义类,后调用产生对象。

  比如 “选课系统”:

    选课系统 - 学生类:

      - 学生对象1:

        特征:

          - 姓名:tank

          - 性别:female

          - 年龄:95

          - 学校:家里蹲

        技能:

          - 技术:python

          - 学习:learn

          - 选课:course

      - 学生对象2

        特征:

          - 姓名:jason

          - 性别:female

          - 年龄:99

          - 学校:家里蹲

        技能:

          - 技术:python

          - 学习:learn

          - 选课:course

3、定义类的语法

  语法:

    class 关键字:帮你产生类

    class 类名:

      - 对象之间相同的特征

        - 学校

        school = "家里蹲"

      - 对象之间相同的技能

        - python

          def Python():

            pass

        - learn

          def Learn():

            pass

        - course

          def Course():

            pass

  类名的规范:

    - 驼峰命名法(推荐)

  定义一个学生类并对属性进行增删查改:

# 定义一个家里蹲学生类

class JldStudent: # 类名指向的是类的内存地址

# 学生相同的特征

# 在类中的特征(即变量)称之为“属性”

school = "OldBoy"

# 注意:在类内部定义函数,会默认产生一个参数self

# 学生相同的技能(即函数)称之为“方法”

def learn(self): # self此处当做一个形参

print("learning...")

# 查看类的名称空间

print(JldStudent.__dict__)

print(JldStudent.__dict__["school"]) # 可调用属性

print(JldStudent.__dict__["learn"]) # 获取learn方法对象

JldStudent.__dict__["learn"](123) # 方法对象+(),相当于执行learn函数(方法)

# 类提供了一种特殊获取名字的方式 “类名.名字”的方式

#

print(JldStudent.school)

JldStudent.learn(12)

#

JldStudent.school = "Cld"

print(JldStudent.school)

#

del JldStudent.school

# print(JldStudent.school) # AttributeError: type object "JldStudent" has no attribute "school"

#

JldStudent.age = 18

print(JldStudent.age)

  执行结果:

{"__module__": "__main__", "school": "OldBoy", "learn": <function JldStudent.learn at 0x0000026D35CD97B8>, "__dict__": <attribute "__dict__" of "JldStudent" objects>, "__weakref__": <attribute "__weakref__" of "JldStudent" objects>, "__doc__": None}

OldBoy

<function JldStudent.learn at 0x0000026D35CD97B8>

learning...

OldBoy

learning...

Cld

18

4、类的名称空间

  - 类的名称空间:

    在定义阶段时产生,会将类中所有的名字,扔进类的名称空间

  - 函数的名称空间:

    在调用函数时产生,函数调用结束后销毁

三、对象

1、对象的产生

  对象名=类名()   --->  调用类产生对象

  类的名称空间在定义时产生,对象的名称空间在调用类时产生

  调用类产生对象的过程称之为类的实例化,对象称之为一个类的实例

  定义一个类:

class Student:

# 学校 ---> 属性

school = "Jld"

# 技能 ---> 方法

def learn(self):

print(self) # 打印输出为 <__main__.Student object at 0x00000000021B6248>,是一个对象

print("learning...")

# 获取对象,产生对象

obj = Student()

print(obj) # 打印输出为 <__main__.Student object at 0x00000000021B6248>,也是一个对象

# 对象调用类内部的名字(属性)

print(obj.school)

# 对象调用类内部的函数(方法),无需传入参数:会将对象当做第一个参数传给该函数(方法)

obj.learn() # 对象的绑定方法,无需传参

  执行结果:

<__main__.Student object at 0x000001BE191C6908>

Jld

<__main__.Student object at 0x000001BE191C6908>

learning...

  由对象来调用类内部的函数,称之为对象的绑定方法。

  对象的绑定方法特殊之处:会将对象当做第一个参数自动传给该函数(方法),所以对象调用类内部的函数时无需传参

2、为对象添加独有的属性

  定义一个类:

class Student:

# 学校 --> 属性

school = "Jld"

def__init__(self, name, sex, age): # 参数:obj1, "张三", "female", 84

print(self.__dict__)

# 给对象添加新的属性

self.name = name # stu1.name = "张三"

self.sex = sex # stu1.sex = "female"

self.age = age # stu1.age = 84

print(self.__dict__)

# 技能 ---> 方法

def learn(self):

print("learning...")

# obj1 = Student() # Student(obj1) ---> __init__(self) ---> self==obj1

# obj2 = Student() # Student(obj2) ---> __init__(self) ---> self==obj2

# obj3 = Student() # Student(obj3) ---> __init__(self) ---> self==obj3



# 给对象添加独有的属性:

# 第一种方法(很麻烦):调用类后,为对象传入对象独有的特征(属性)

obj1.name = "张三"

obj1.sex = "female"

obj1.age = 84

# 第二种方法:调用类时,为对象传入对象独有的特征(属性)

# __init__(self, name, sex, age):obj1 --> self "张三" --> name "female" --> sex 84 --> age

# 调用类时:会将对象当做第一个参数,并与括号内所有的参数一并传给__init__()

obj1 = Student("张三", "female", 84)

  执行结果:

{}

{"name": "张三", "sex": "female", "age": 84}

注意:凡是在类内部定义的.__或者__结尾的方法都有特殊意义

  __init__():在类内部定义的方法,在调用类时触发,会自动将对象当做第一个参数自动传入并执行

3、对象名字的查找顺序

  对象名字的查找顺序:

    ① 对象.属性,会先找对象自己的

    ② 若对象没有,会去找类的

    ③ 对象没有,类也没有,就会报错

  定义一个类:

class people:

country = "China"

name = "李四"

def__init__(self, name, sex, age):

self.name = name

self.sex = sex

self.age = age

def run(self):

print("running...")

obj1 = people("张三", "female", 95)

print(obj1.name) # 张三 找对象自己的name属性

print(obj1.country) # China 对象没有,找类中的属性

# 报错:AttributeError: "people" object has no attribute "json"

print(obj1.json) # 对象没有,类也没有,就报错

4、一切皆对象

  在python中一切皆对象

  比如:python的八大数据类型都是类

    定义数据类型时,内部会自动调用相应的类,然后产生对象

"""

在python中一切皆对象

"""

class foo:

def__init__(self, x, y, z):

self.x = x

self.y = y

self.z = z

# 产生对象

# 调用类产生对象的过程称之为类的实例化,对象称之为一个类的实例

foo_obj = foo(10, 20, 30)

print(foo_obj)

# 查看 字符串 类型

print(type(str)) # <class "type">

# 查看 列表 类型

print(type(list)) # <class "type">

# 查看 字典 类型

print(type(dict)) # <class "type">

# 查看 元组 类型

print(type(tuple)) # <class "type">

# 查看 浮点型 类型

print(type(float)) # <class "type">

# 查看 整型 类型

print(type(int)) # <class "type">

# 查看 布尔值 类型

print(type(bool)) # <class "type">

# 除了这些还有很多都是类,既然是类,就可以是对象,所以在python中一切皆对象

  执行结果:

<__main__.foo object at 0x0000014471D71C88>

<class"type">

<class"type">

<class"type">

<class"type">

<class"type">

<class"type">

<class"type">

四、根据面向对象编程编写一个“人狗大作战”例子

"""

需求:有一个人对象,狗对象,狗咬人,人打狗

- 对象人1

- 特征

- 生命:1000

- 名字:name = "张三"

- 攻击力:arg

- 技能

- 打:hit

- 对象人2

- 特征

- 生命:950

- 名字:name = "李四"

- 攻击力:arg

- 技能

- 打:hit

- 抽象出类

- 人类:

- 相同特征

- 生命

- 相同特征

- 打

- 狗对象1

- 特征

- 生命值:150

- 名字:name = "二哈"

- 品种:dog_type = "哈士奇"

- 攻击力:arg

- 技能

- 咬:bite

- 狗对象2

- 特征

- 生命值:250

- 名字:name = "小短腿"

- 品种:dog_type = "柯基"

- 攻击力:arg

- 技能

- 咬:bite

- 抽象出类

- 狗类:

- 相同特征

- 生命

- 相同特征

- 咬

"""

import time

# 人类

class People:

def__init__(self, name, life, arg):

self.name = name

self.life = life

self.arg = arg

# 人对象调用hit时,传入狗对象

def hit(self, dog_obj):

print(f"[{self.name}]要开始打[{dog_obj.name}]了")

# 减掉狗对象的生命值 值为人对象的攻击力

dog_obj.life -= self.arg

print(f"[{dog_obj.name}]的生命值减掉:[{self.arg}],剩余血量为:[{dog_obj.life}]")

if dog_obj.life <= 0:

print(f"[{dog_obj.name}]已经没了")

return True

# 狗类

class Dogs:

def__init__(self, name, life, dog_type, arg):

self.name = name

self.life = life

self.dog_type = dog_type

self.arg = arg

# 狗对象调用bite时,传入人对象

def bite(self, p_obj):

print(f"[{self.name}]要开始咬[{p_obj.name}]了")

# 减掉人对象的生命值 值为狗对象的攻击力

p_obj.life -= self.arg

print(f"[{p_obj.name}]的生命值减掉:[{self.arg}],剩余血量为:[{p_obj.life}]")

if p_obj.life <= 0:

print(f"[{p_obj.name}]已经没了")

return True

p1 = People("张三", 1000, 50) # 人对象

d1 = Dogs("二哈", 150, "哈士奇", 200) # 狗对象

while True:

# 开始狗咬人,人打狗

res1 = d1.bite(p1)

if res1:

break

time.sleep(1) # 休眠1秒

res2 = p1.hit(d1)

if res2:

break

time.sleep(1) # 休眠1秒

  执行结果:

[二哈]要开始咬[张三]了

[张三]的生命值减掉:[200],剩余血量为:[800]

[张三]要开始打[二哈]了

[二哈]的生命值减掉:[50],剩余血量为:[100]

[二哈]要开始咬[张三]了

[张三]的生命值减掉:[200],剩余血量为:[600]

[张三]要开始打[二哈]了

[二哈]的生命值减掉:[50],剩余血量为:[50]

[二哈]要开始咬[张三]了

[张三]的生命值减掉:[200],剩余血量为:[400]

[张三]要开始打[二哈]了

[二哈]的生命值减掉:[50],剩余血量为:[0]

[二哈]已经没了

五、面向对象总结

  面向对象:

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

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

    优点:

      可扩展性强

    缺点:

      编写复杂难度较面向过程高

1、类的实例化:调用类的过程称之为类的实例化,产生的对象也可以称之为类的一个实例

  调用类产生对象发生的事情:

    ① 会产生一个空对象的名称空间

    ② 会自动触发__init__,并且会将对象当做第一个参数传入

    ③ 会将调用类括号内的参数一并传给__init__()

# 定义一个类
class
People:

national = "han"

def__init__(self, name, age, sex):

self.name = name

self.age = age

self.sex = sex

# 注意:看到self就应该知道是对象本身,在这里就是下面代码中的p_obj对象

def learn(self):

print("learning...")

p_obj = People("张三", 184, "female")

print(p_obj.name, p_obj.age, p_obj.sex)

  执行结果:

张三 184 female

2、查看类与对象的名称空间:类.__dict__      对象.__dict__

# 使用上面People类执行下列代码

print
(People.__dict__) # 查看类的名称空间

print(p_obj.__dict__) # 查看对象的名称空间

  执行结果:

{"__module__": "__main__", "national": "han", "__init__": <function People.__init__ at 0x000001B4D9BC96A8>, "learn": <function People.learn at 0x000001B4D9BC9620>, "__dict__": <attribute "__dict__" of "People" objects>, "__weakref__": <attribute "__weakref__" of "People" objects>, "__doc__": None}

{"name": "张三", "age": 184, "sex": "female"}

3、类或对象的属性操作:增、删、查、改

# 使用上面People类执行下列代码

# 类的属性操作

People.sal = 3000 #

People.number = 1 #

del People.number #

People.sal = 4500 #

print(People.sal) #

# 对象的属性操作

p_obj.county = "China"#

del p_obj.sex #

p_obj.name = "李四"#

print(p_obj.name) #

  执行结果:

4500

李四

4、类中数据属性(类中的变量):类中的属性是给对象使用的,对象引用类中的属性,指向的都是类中同一个内存地址

# 使用上面People类执行下列代码

p_obj1 = People("王五", 84, "female")

p_obj2 = People("赵六", 85, "male")

p_obj3 = People("孙七", 86, "female")

print(p_obj1.national, id(p_obj1))

print(p_obj2.national, id(p_obj2))

print(p_obj3.national, id(p_obj3))

  执行结果:

han 2612115777632

han 2612115777744

han 2612115777800

5、类中的方法(类中的函数):类中的方法是给对象使用的,由对象来调用就会将方法绑定给不同的对象,并且会将对象当做第一个对象传入

# 使用上面People类执行下列代码

p_obj1 = People("王五", 84, "female")

p_obj2 = People("赵六", 85, "male")

p_obj3 = People("孙七", 86, "female")

print(People.learn)

print(p_obj1.learn)

print(p_obj2.learn)

print(p_obj3.learn)

  执行结果:

<function People.learn at 0x0000022590CA9620>

<bound method People.learn of <__main__.People object at 0x0000022590CBA860>>

<bound method People.learn of <__main__.People object at 0x0000022590CBA8D0>>

<bound method People.learn of <__main__.People object at 0x0000022590CBA908>>

6、对象属性的查找顺序:先从对象自己的名称空间找 ---> 类的名称空间查找

# 使用上面People类执行下列代码

print(p_obj1.national) # 从类中查找

print(p_obj1.national2) # 类中也没有,报错

7、对象绑定方法的特殊之处

  ① 会将对象当做第一个参数传入

  ② 若对象的绑定发放中还有其他参数,会一并传入。

8、一切皆对象:在python3中,类即类型

# 使用上面People类执行下列代码

print(type(p_obj)) # <class "__main__.People">

str1 = "orange"

print(type(str1)) # <class "str">

list1 = [1, 2, 3]

print(type(list1)) # <class "list">

  执行结果:

<class"__main__.People">

<class"str">

<class"list">

以上是 面向对象、类 的全部内容, 来源链接: utcz.com/z/530953.html

回到顶部