day019python之面向对象基础1

面向对象基础

1 面向对象基础

1.1 面向对象的由来

  • python中一切皆对象
  • 定义一个类,类有属性(变量、特征),有方法(函数、技能)

1.2 面向对象编程介绍

1.2.1 回顾面向过程设计

  • 核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么然后干什么

  • 优点:复杂问题流程化,进而简单化(一个复杂的问题分成一个个小的步骤去实现)

  • 缺点:一套流水线或流程解决一个问题,生产汽水的就无法生产汽车,即使可以也要大改,牵一发而动全身

  • 应用场景:一旦完成基本很少改变,如Linux内核,git等

1.2.2 面向对象设计

  • 核心是对象二字,python中一切皆对象(对象是特征与技能的结合体),面向对象只用来解决扩展性

  • 优点:解决了程序的扩展性,对某一个对象的单独修改会立即反映到整个体系中

  • 缺点:Ⅰ编程的复杂难度远高于面向过程,易出现过度设计

     Ⅱ无法像面向过程的程序精准预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,谁也无法准确的预测最终结果
    
  • 应用场景:需求经常变化的软件,一般集中于用户层,互联网应用,企业内部软件,游戏等

2 类与对象

2.1 基本使用

  • 造一个张三对象,他有体重、身高,还有睡觉技能(特征与技能的结合体:属性和方法)

  • 定义一个类

# 类 person
class Person:
    # 特征(属性)
    height = 180
    weight = 90
    # sleep函数,就是方法,技能
    def sleep(self):
        print("睡觉技能")
  • 定义一个对象
# 对象 zhangsan
zhangsan = Person()
  • 使用对象
print(zhangsan.height)  # 180
print(zhangsan.weight)  # 90
zhangsan.sleep()  # 睡觉技能

2.2 示例

  • 定义一个学生类(学习属性,选课技能),实例化得到一个学生对象
class Student:  # 类名尽量用驼峰
    school = 'oldboy'
    def choose_course(self):  # 方法,特殊函数,定义在类内部,有一个参数self
        print("选课技能")

student = Student()  # 类的实例化,取得对象
# __dict__是类的名称空间
print(Student.__dict__)  # 以__开头的是写在类中的属性和方法,都在Student中

# 通过Student取得school
print(Student.school)  # oldboy
print(Student.choose_course)  # <function Student.choose_course at 0x000001F299BC78B0>

print(student.school)  # oldboy
student1 = Student()
print(student1.school)  # oldboy

3 对象属性的查找顺序

  • 对象有自己属性时,优先使用自己的,没有才用类的

    先从自己的名称空间找,没有则去类中找,如果类中也没有就报错

  • 对象调用方法,使用的就是类中定义的方法

  • 类中定义的方法,是绑定给对象的,对象来使用

    哪个对象来调用方法,self就是哪个对象

  • 对象属性的查找顺序:对象自己-->类中-->报错

    对象方法的查找顺序:所有对象都用类的方法-->方法有self参数,通过self参数区分是哪个对象调用的

    类名._dict_ 类的名称空间

    对象.__dict__ 对象的名称空间

    类中的属性应该是对象的共有属性,如果是对象自己的,需要放到对象自己的名称空间

class Student:
    school = 'oldboy'
    def choose_course(self):
        print(self.school)
        print('选课技能')

# 定义两个不同的新对象
s1 = Student()
s2 = Student()

# 因为s1对象和s2对象的名称空间中,都没有school属性,因此共用类的名称空间中的school属性
print(s1.school)  # oldboy
print(s2.school)  # oldboy

# 此时s1转学去了北大
s1.school = '北大'

print(s1.school)  # 北大
print(s2.school)  # oldboy
print(Student.school)  # oldboy


# 对象有自己属性时,优先使用自己的,没有才用类的
# 先从自己的名称空间找,没有则去类中找,如果类中也没有就报错
# print(s1.xxx)  # 报错


# 对象调用方法,使用的就是类中定义的方法
# 类中定义的方法,是绑定给对象的,对象来使用
# 哪个对象来调用方法,self就是哪个对象
s1.school = '北大'
s2.school = '清华'

s1.choose_course()  # 北大 选课技能
s2.choose_course()  # 清华 选课技能


# 对象属性的查找顺序:对象自己-->类中-->报错
# 对象方法的查找顺序:所有对象都用类的方法-->方法有self参数,通过self参数区分是哪个对象调用的
# 类名.__dict__  类的名称空间
# 对象.__dict__  对象的名称空间
# 类中的属性应该是对象的共有属性,如果是对象自己的,需要放到对象自己的名称空间

print(s1.__dict__)  # {'school': '北大'}
s1.name = 'ccc'
s1.age = 18
print(s1.__dict__)  # {'school': '北大', 'name': 'ccc', 'age': 18}


# 对象不能改掉类的属性
class Student:
    school = 'oldboy'
    def choose_course(self):  # self必须写,哪个对象调,self就是哪个对象
        print(self.school)
        print("选课技能")

s1 = Student()
s1.school = "北大"  # 改的是对象自己的名称空间属性,改不到类的属性


# 更改类的属性(不用改源码的方式)
Student.school = '北大'
s1 = Student()
s2 = Student()
print(s1.school)  # 北大
print(s2.school)  # 北大

s1.school = "清华"
print(s1.school)  # 清华
print(s2.school)  # 北大


# 统计一个类被实例化多少次
class Student:
    count = 0

# 错误方法
s1 = Student()
s1.count += 1  # 实例化一次 数字+1
s2 = Student()
s2.count += 1  # 实例化一次 数字+1
print(Student.count)  # 打出来永远是0

# 方式二
s1 = Student()
Student.count += 1  # 实例化一次 数字+1
s2 = Student()
Student.count += 1  # 实例化一次 数字+1
print(Student.count)  # 2

print(Student.count)  # 2
print(s1.count)  # 2

s1 = Student()
Student.count += 1  # 实例化一次 数字+1
s2 = Student()
Student.count += 1  # 实例化一次 数字+1
s1.count += 1  # 加了这句话

print(Student.count)  # 2
print(s1.count)  # 3


Student.count += 10  # 修改类的count属性

print(s1.count)  # 打印s1的count属性,由于s1用自己的,就是3
print(s2.count)  # 打印s1的count属性,由于s1没有,用类的,类的是12,就是12

4 对象的绑定方法

函数:普通函数def定义的函数,有几个参数就要传几个参数
方法:绑定给某个对象的,绑定给谁,谁来调用,谁来调用就会自动把谁传过来,传给self

class Student:
    def choose_course(self):  # 定义在类内部的函数,就是绑定给对象的方法
        # print(self.name)  # 通过self来区分,到底是哪个对象调用了自己的绑定方法
        print('%s选了课' % self.name)


s1 = Student()
s1.name = 'ccc'  # 自己名称空间加了name属性
s1.choose_course()  # 绑定给对象的方法,对象来调用,自动把对象传进去

s2 = Student()
s2.name = 'yyy'  # 自己名称空间加了name属性
s2.choose_course()

# print(Student.name)  # 报错

类可以调用方法,类来调用,就是个普通函数
s1 = Student()
s1.name = 'zzz'
Student.choose_course(s1)
类可以调用对象的绑定方法,但是需要手动把对象传进来,现在choose_course就是个普通函数,有几个参数,就传几个参数

5 对象的初始化

对象在实例化的时候,赋初值(给对象一些属性)
class Student:
    def choose_course(self):
        print('选课')

# 之前的方案
student1 = Student()
student1.name = 'ccc'
student1.age = 18

# 新方案
class Student:
    def __init__(self):
        self.name = 'ccc'
        self.age = 18

    def choose_course(self):
        print('选课')

student1 = Student()  # 只要是类实例化得到对象,就会自动触发__init__的执行
print(student1.age)   # 18
print(student1.name)  # ccc

student2 = Student()
print(student2.name)  # ccc
# 定死了,不行

# __init__的终极使用
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def choose_course(self):
        print('选课')

student = Student(name='ccc', age=18)  # 这种初始化会触发类的__init__的执行,并把参数传入
print(student.name)
yyy = Student(name='yyy', age=20)
print(yyy.name)

# 按位置传
# cc=Student(20,'drrug')
ccc = Student('drrug', 20)
print(ccc.name)

6 阶段总结一

# 1 类与对象
class 类名:
    pass

对象 = 类名()

# 2 之前一直用的字典,列表,数字...其实都是一些类的对象
# 3 对象的属性查找
对象.属性-->先从对象自己的名称空间中找-->类的名称空间找-->报错
类中定义的属性,对象只能使用,不能修改
对象只能修改自己名称空间的
# 4 对象的绑定方法
定义在类内部的函数,就是对象的绑定方法,对象来调用,会自动把对象传入(self)
类也可以来调用,类来调用,就是普通函数,有几个参数就要传几个参数
函数就是def 定义的函数,有几个参数就要传几个参数
方法是绑定给对象的,由对象来调用,特殊之处是会把对象自身传入
class Student:
    def choose_course(self):
        print(self)  # <__main__.Student object at 0x000001FD4EA85B50>

s = Student()
s.choose_course()  # choose_course就叫方法
Student.choose_course(1)  # 就是普通函数 1

print(s.choose_course)  # <bound method Student.choose_course of <__main__.Student object at 0x0000025A0E90F1F0>>
print(Student.choose_course)  # <function Student.choose_course at 0x0000025A0E917430>

# 5 __init__的使用
初始化方法,类加括号实例化得到对象时,会触发它的执行
可以在初始化方法中,给对象赋初值
class Student:
    def __init__(self, name, age, school='北大'):  # 如果不写,它就不执行
        self.name = name
        self.age = age
        self.school = school

    def sleep(self):
        print('%s睡着了' % self.name)

s1 = Student('ccc', 19, school='清华')
s2 = Student('yyy', 18)
s3 = Student('zzz', 22)
# print(s.school)
s3.sleep()  # zzz睡着了
s2.sleep()  # yyy睡着了
原文地址:https://www.cnblogs.com/caojiaxin/p/14170489.html