面向对象基础

目录:

  基本概念

  定义类

  对象使用

  __init__函数

  绑定方法

概要:

类和对象本质是名称空间
    1. 什么是面向对象编程
        核心是对象二字,对象是特征与技能的结合体,基于该思想编写程序就好比在
        创造一个世界,世界是由一个个具体存在的对象组成的,你就是这个世界的上帝
        这一种上帝式的思维方式
        优点: 扩展性强
        缺点: 编程的复杂度要高于面向过程

    2. 类
        对象是特征与技能的结合体,类则是一系列对象相同的特征与技能的结合体

        在现实世界中,先有一个个具体存在的对象,然后随着人类文明的发展总结出的类
        在程序中一定先定义类,后调用类来产生对象

    3. 老男孩选课系统:
        在现实世界中具体存在的对象
            对象1:
                特征
                    学校='Oldboy'
                    姓名='周铁蛋'
                    年龄=36
                    性别=''
                技能
                    选课

            对象2:
                特征
                    学校='Oldboy'
                    姓名='张铜蛋'
                    年龄=38
                    性别=''
                技能
                    选课

            对象3:
                特征
                    学校='Oldboy'
                    姓名='Egon'
                    年龄=18
                    性别=''
                    等级=10
                技能
                    打分

        在现实世界中老男孩学生类
            相似的特征
                学校='Oldboy'
            相似的技能
                选课
  4.类的用途:
    类的用途一: 类本质就是一个名称空间,可以对该名称空间进行增删改查
    print(OldboyStudent.__dict__)
    print(OldboyStudent.__dict__['school'])#查看school属性
    OldboyStudent.school #OldboyStudent.__dict__['school']
    OldboyStudent.xxx=111 #OldboyStudent.__dict__['xxx']=111,添加属性
    print(OldboyStudent.__dict__)

    类的用途二: 调用类来产生对象
      1. 会产生一个空对象obj
      2. 会触发类中__init__方法,OldboyStudent.__init__(obj,)
   5.一切皆为对象,在python3中统一了类与类型的概念(类型即为类)
    class Foo:
    pass
    obj=Foo()
    print(type(obj))#<class '__main__.Foo'>
    
    l = [1,2,3]
    print(type(list))#<class 'list'>

  6.当拿到一个对象的时候,不仅拿到了对象的特有属性,还有类的属性以及类的功能函数

基本概念:

面向过程:

是一种编程思想,就是前辈程序员发现的一种比较号的编程方法
过程指的是 先干什么  再干什么,完成一个事情所有的具体步骤
优点:把复杂的问题流程化,简单化,降低开发难度
缺点:扩展差, 再当前这种情况下 用户需求千变万化  对扩展性要求非常高
使用场景:不需要扩展,或是对扩展性要求不高,例如linux内核,shell 脚本
案例: 把大象装进冰箱 需要几步
    1.打开冰箱
    2.装进大象
    3.关闭冰箱
面向过程中我们关注的点是,完成这个任务,具体的步骤 一步一步去完成

 面向对象:

一种编程思想
核心是对象
什么是对象:在现实生活中实实在在存在的,具备自己的特征和行为的事物
    反过来说 对象就是 特征和行为(技能)的结合体
如何来区分:如果能够准确的找到一个事物,它就是一个对象
例如:某人的女朋友

面向对象编程:我们关注的点是.使用什么样的对象可以完成我的任务
    例如:把大象装进冰箱,什么样的对象可以帮我完成这个任务,只要找到这个对象,命令它来做事情即可
    你从一个操作者 变成了指挥者, 例如:西游记中的如来,他要完成一个传经,要把经书传到东土大唐取,
    本来要自己去,但是太麻烦,所以找了唐僧师徒五个对象,来帮他完成这个任务

优势: 1.对于指挥者(程序员)来说,不需要再关心具体步骤
      2.扩展性,一个单独的个体的特征或行为发生变化时 不会影响到别人

缺点: 1.程序的复杂度变高,你得需要设计这个些对象,注意要避免过度设计得问题
      2.程序得执行结果可控性低

类与对象:

类就是分类 类型的意思
定义:一堆具备相同特征和行为的事物的抽象概念,不实际存在
先有类还是先有对象:
    生活中:
    生活中类怎么来的,是通过对象的特征和行为抽取而来,
    所以是先有对象才有了类

    编程中:
    必须是先有类 才能有对象,因为你必须先告诉程序,你这个对象有什么样的特征和行为

类的作用:用于描述该类的对象具备什么样的特征和行为

定义类

  语法:class关键字 类名

  类名规范:大写开头,驼峰命名法

class SHOldboyStudent:
    # 描述该类对象的特征
    school = "上海Oldboy"
    name = "矮根"
    age = 68
    gender = "unknown"

    # 在定义阶段
    # 只要包含该类的py被执行 就会做两件事情
    #   1.就会创建类的名称空间
    #   2.执行代码 将产生的名称放入名称空间
    print("========================")#可以执行

    # 描述该类对象的行为 通过函数
    def say_hi(abc):
        print(abc)
        print("hello oldBoy")

使用类中的属性:

print(SHOldboyStudent.__dict__)#查看名称空间
print(SHOldboyStudent.__dict__["name"])#矮根
print(SHOldboyStudent.name)#矮根

使用类中的函数:

print(SHOldboyStudent.__dict__["say_hi"])  #<function SHOldboyStudent.say_hi at 0x00000000021989D8>
print(SHOldboyStudent.say_hi)  #<function SHOldboyStudent.say_hi at 0x00000000021989D8>
# 使用类直接调用类中函数时 与普通函数没有任何区别  位self仅仅是一个置参数
SHOldboyStudent.say_hi(10)# 10、hello oldboy 

面向对象的使用:

定义类:

class OldboyStudent:
# 如果每个对象的这个属性都相同 才应该定义到类中 比如所有人的学校都是上海Oldboy
    school = "上海Oldboy"

创建对象:

#语法: 在类名后加括号 与调用函数写法相同
stu = OldboyStudent()
# 访问对象的属性
print(stu.school)#上海Oldboy
print(OldboyStudent.school)#上海Oldboy

修改属性的值:

stu.school = "北京Oldboy"
print(stu.school)#北京Oldboy

增加属性:

stu.room_num = "1008"
print(stu.room_num)#1008

删除属性:

print(stu.__dict__)#{'school': '北京Oldboy', 'room_num': '1008'}
del stu.room_num
print(stu.__dict__)#{'school': '北京Oldboy'}
# print(stu.room_num)报错,这个是对象的属性,删除之后就不能打印了

对象与类的名称空间是独立的:

stu.school = "深圳oldboy"    # 为对象的属性赋予新的值
print(OldboyStudent.school) # 类中的属性不会变化
stu.room_num = "1008"   # 为对象增加属性
# print(OldboyStudent.room_num) #报错,类中也不会出现新的属性
print(stu.__dict__)
print(OldboyStudent.__dict__)

对象的属性查找顺序:

# 对象自己的名称空间 -> 类的名称空间
stu1 = OldboyStudent()
stu1.school = "newSchool"
print(stu1.school)#newSchool
print(stu1)#<__main__.OldboyStudent object at 0x00000000021E7C50>

__init__函数:

__init__称之为初始化函数,它会在创建对象的时候自动执行

1.使用场景 需要为每个对象定制不同的属性值
2.__init__在创建对象后自动执行
3.第一个self参数 指的是这个对象本身 不需要手动传值

 创建对象时
   1.创建一个空对象
   2.执行__init__函数 并且自动传入了这个对象

__init__函数演变过程:

 1 # 原始代码
 2 stu1.name='周铁蛋'
 3 stu1.age=36
 4 stu1.gender='male'
 5 print(stu1.__dict__)
 6 
 7 stu2.name='美男子'
 8 stu2.age=18
 9 stu2.gender='male'
10 print(stu2.__dict__)
11 
12 stu3.name='张铜蛋'
13 stu3.age=18
14 stu3.gender='female'
15 print(stu3.__dict__)
16 
17 # 简化代码
18 def init(obj,name,age,gender):
19     obj.name=name
20     obj.age=age
21     obj.gender=gender
22 
23 init(stu1,'周铁蛋',36,'male')
24 init(stu2,'美男子',18,'male')
25 init(stu3,'张铜蛋',18,'female')
26 print(stu1.__dict__)
27 print(stu2.__dict__)
28 print(stu3.__dict__)

__init__函数作用:减少代码冗余

class Dog:
    # 作为一只狗 应该有 昵称  age color gender
    # 但是不能写到类中因为每个狗不一样
    # name = "二哈"

    # 该函数的作用,就是为对象的属性赋初始值,不用在每次创建新对象时复杂传值,减少代码冗余
    def __init__(self,name,color,age,gender):
        print("狗__init__执行了")
        print(self)
        self.name = name#将传入的name赋值给对象
        self.age = age
        self.color = color
        self.gender = gender

#dog1
= Dog() #print(dog1) #dog1.name = "二黄" #dog1.age = "2" #dog1.color = "黄色" #dog1.gender = "female" 简化为:dog1 = Dog('大黄','黄色',2,'female')
#dog2
= Dog() #print(dog1) #dog2.name = "二哈" #dog2.age = "1" #dog2.color = "白色" #dog2.gender = "female"
简化为:dog2 = Dog('二哈','白色',3,'male')

绑定方法:

好处:可以拿到对象及类中的属性和功能
绑定方法是什么?
是对象与类中的某个函数的绑定关系,就像生活中,我们都会吃饭,我吃饭你不会饱 那么吃饭就是我自己的绑定方法 为什么要把函数进行绑定? 因为对象的行为,通常都需要访问这个对象的数据或是修改这个对象的数据 如果没有对象,直接调用函数是没有意义的,在函数中访问不到对象的数据 所以将对象和函数进行绑定 特殊之处: 在使用绑定方法时,不需要关心self参数,会自动将这个对象本身传进来 对象调用绑定方法时,最后执行的还是类中的那个函数

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,

      就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)

注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。

class Person:
    country = "China"
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender
    def sleep(self):
        print("sleeping")
        print(self)#<__main__.Person object at 0x00000000027BC4A8>
    def eat(self):
        print("eating")
p1 = Person("矮根",68,"female")
p2 = Person("成伟",18,"female")
# 类调用类中函数 与 对象调用的区别
p1.sleep()
p2.sleep()
print(Person.sleep)#函数<function Person.sleep at 0x00000000027B8A60>  
print(p1.sleep)#绑定方法<bound method Person.sleep of <__main__.Person object at 0x00000000027BC4A8>>

类调用与对象调用的区别:

对于类而言 sleep就是一个普通函数
对对象而言 sleep是一个绑定方法

类调用
Person.sleep(10)#需要严格按照函数进行传值
对象调用
p1.sleep()

面向对象1:

 1 # 王者荣耀 对砍游戏
 2 # 两个英雄可以对砍 如果血量小于等于0 就GG
 3 # 所需的对象
 4 # 英雄对象
 5 """
 6    亚瑟
 7        属性
 8             类型
 9             血量
10             名称
11 
12        技能
13             Q 跳起来给你一刀 伤害50
14             W 给你一脚           30
15             E 大宝剑             100
16 
17     妲己
18        属性
19             类型
20             血量
21             名称
22 
23        技能
24             Q 给你一颗小心心  伤害10
25             W 给你一尾巴           30
26             E 色诱                100
27 
28 """
29 class Hero:
30     def __init__(self, hero_type, name, blood, q, w, e):
31         self.hero_type = hero_type
32         self.name = name
33         self.blood = blood
34         self.q = q
35         self.e = e
36         self.w = w
37         
38     def Q(self, enemy):
39         print("%s 对 %s 释放 Q技能 造成%s伤害 对方血量剩余%s" %
40               (self.name, enemy.name, self.q, enemy.blood - self.q))
41         # 敌方血减少
42         enemy.blood -= self.q
43         if enemy.blood <= 0:
44             print("hero %s GG" % enemy.name)
45 
46     def W(self, enemy):
47         print("%s 对 %s 释放 W技能 造成%s伤害 对方血量剩余%s" %
48               (self.name, enemy.name, self.w, enemy.blood - self.w))
49         # 敌方血减少
50         enemy.blood -= self.w
51         if enemy.blood <= 0:
52             print("hero %s GG" % enemy.name)
53 
54     def E(self, enemy):
55         print("%s 对 %s 释放 E技能 造成%s伤害 对方血量剩余%s" %
56               (self.name, enemy.name, self.e, enemy.blood - self.e))
57         # 敌方血减少
58         enemy.blood -= self.e
59         if enemy.blood <= 0:
60             print("hero %s GG" % enemy.name)
61 
62 
63 # 请选择你的英雄
64 yase = Hero("战士", "亚瑟", 200, 50, 30, 100)
65 
66 daji = Hero("法师", "妲己", 150, 10, 30, 180)
67 
68 # 妲己在草丛发现了路边亚瑟
69 # daji.Q(yase)
70 
71 daji.E(yase)
72 yase.W(daji)
73 yase.E(daji)
74 yase.Q(daji)
75 # daji.W(yase)
英雄联盟对战

 面向对象2:

   如下示例, 请用面向对象的形式优化以下代码在没有学习类这个概念时,数据与功能是分离的,如下
def exc1(host,port,db,charset):
    conn=connect(host,port,db,charset)
    conn.execute(sql)
    return xxx
def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    conn.call_proc(sql)
    return xxx
# 每次调用都需要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')

 面向对象:

 1 class Format:
 2     def __init__(self,host,port,db,charset):
 3         self.host = host
 4         self.port = port
 5         self.db = db
 6         self.charset = charset
 7     def exc1(self,sql):
 8         conn = connect(self.host,self.port,self.db,self.charset)#得到对象,便得到了对象的属性,类的属性,以及功能函数
 9         conn.execute(sql)
10         return XXX
11 
12     def exc2(self, proc_name,sql)
13         conn = connect(self.host,self.port,self.db,self.charset)#
14         conn.call_proc(sql)
15         return xxx
16 obj = Format('127.0.0.1',3306,'db1','utf8',)
17 obj.exc1('select * from tb1;')
18 obj.exc2('存储过程的名字')
优化代码

 

posted @ 2018-10-22 18:50  ChuckXue  阅读(178)  评论(0编辑  收藏  举报