面向对象基础篇

shaomz shaomz     2022-10-10     272

关键词:

介绍

一、什么是面向对象的程序设计及为什么要有它

二、类与对象

三、属性查找

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

五、对象之间的交互

六、练习

一、什么是面向对象的程序设计及为什么要有它

  面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。

优点:复杂的过程流程化,进而简单化
缺点:扩展性差
    面向对象:核心是对象二字,对象是特征与技能的结合体   基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成,是一种“上帝式”的思维方式
    优点:可扩展性强
    缺点:编程复杂高,容易出现过度设计

面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

技术分享图片

二、类与对象

    类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看

在现实世界中:先有对象,再有类

世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念

也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在

在程序中:务必保证先定义类,后产生对象

这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类

不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

如此,通过上面我们来定义一个类:

技术分享图片
#在现实世界中,站在老男孩学校的角度:先有对象,再有类
对象1:李坦克
    特征:
        学校=oldboy
        姓名=李坦克
        性别=男
        年龄=18
    技能:
        学习
        吃饭
        睡觉

对象2:王大炮
    特征:
        学校=oldboy
        姓名=王大炮
        性别=女
        年龄=38
    技能:
        学习
        吃饭
        睡觉

对象3:牛榴弹
    特征:
        学校=oldboy
        姓名=牛榴弹
        性别=男
        年龄=78
    技能:
        学习
        吃饭
        睡觉


现实中的老男孩学生类
    相似的特征:
        学校=oldboy
    相似的技能:
        学习
        吃饭
        睡觉
在现实世界中:先有对象,再有类
技术分享图片
#在程序中,务必保证:先定义(类),后使用(产生对象)
PS:
  1. 在程序中特征用变量标识,技能用函数标识
  2. 因而类中最常见的无非是:变量和函数的定义

#程序中的类
class OldboyStudent:
    school=oldboy
    def learn(self):
        print(is learning)
        
    def eat(self):
        print(is eating)
    
    def sleep(self):
        print(is sleeping)
  


#注意:
  1.类中可以有任意python代码,这些代码在类定义阶段便会执行
  2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看
  3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法
  4.点是访问属性的语法,类中定义的名字,都是类的属性

#程序中类的用法
.:专门用来访问属性,本质操作的就是__dict__
OldboyStudent.school #等于经典类的操作OldboyStudent.__dict__[‘school‘]
OldboyStudent.school=Oldboy #等于经典类的操作OldboyStudent.__dict__[‘school‘]=‘Oldboy‘
OldboyStudent.x=1 #等于经典类的操作OldboyStudent.__dict__[‘x‘]=1
del OldboyStudent.x #等于经典类的操作OldboyStudent.__dict__.pop(‘x‘)


#程序中的对象
#调用类,或称为实例化,得到对象
s1=OldboyStudent()
s2=OldboyStudent()
s3=OldboyStudent()

#如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__
#注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
class OldboyStudent:
    ......
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    ......


s1=OldboyStudent(李坦克,,18) #先调用类产生空对象s1,然后调用OldboyStudent.__init__(s1,‘李坦克‘,‘男‘,18)
s2=OldboyStudent(王大炮,,38)
s3=OldboyStudent(牛榴弹,,78)


#程序中对象的用法
#执行__init__,s1.name=‘牛榴弹‘,很明显也会产生对象的名称空间
s2.__dict__
{name: 王大炮, age: , sex: 38}

s2.name #s2.__dict__[‘name‘]
s2.name=王三炮 #s2.__dict__[‘name‘]=‘王三炮‘
s2.course=python #s2.__dict__[‘course‘]=‘python‘
del s2.course #s2.__dict__.pop(‘course‘)
在程序中:先定义类,后产生对象
技术分享图片
#python为类内置的特殊属性
类名.__name__# 类的名字(字符串)
类名.__doc__# 类的文档字符串
类名.__base__# 类的第一个父类(在讲继承时会讲)
类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__# 类的字典属性
类名.__module__# 类定义所在的模块
类名.__class__# 实例对应的类(仅新式类中)
类内置的特殊属性
技术分享图片
#1、在没有学习类这个概念时,数据与功能是分离的
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,存储过程的名字)




#2、我们能想到的解决方法是,把这些变量都定义成全局变量
HOST=‘127.0.0.1’
PORT=3306
DB=‘db1’
CHARSET=‘utf8’

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(HOST,PORT,DB,CHARSET,select * from tb1;)
exc2(HOST,PORT,DB,CHARSET,存储过程的名字)


#3、但是2的解决方法也是有问题的,按照2的思路,我们将会定义一大堆全局变量,这些全局变量并没有做任何区分,即能够被所有功能使用,然而事实上只有HOST,PORT,DB,CHARSET是给exc1和exc2这两个功能用的。言外之意:我们必须找出一种能够将数据与操作数据的方法组合到一起的解决方法,这就是我们说的类了

class MySQLHandler:
    def __init__(self,host,port,db,charset=utf8):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
    def exc1(self,sql):
        conn=connect(self.host,self.port,self.db,self.charset)
        res=conn.execute(sql)
        return res


    def exc2(self,sql):
        conn=connect(self.host,self.port,self.db,self.charset)
        res=conn.call_proc(sql)
        return res


obj=MySQLHandler(127.0.0.1,3306,db1)
obj.exc1(select * from tb1;)
obj.exc2(存储过程的名字)


#改进
class MySQLHandler:
    def __init__(self,host,port,db,charset=utf8):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(self.host,self.port,self.db,self.charset)
    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,sql):
        return self.conn.call_proc(sql)


obj=MySQLHandler(127.0.0.1,3306,db1)
obj.exc1(select * from tb1;)
obj.exc2(存储过程的名字)
数据与专门操作该数据的功能组合到一起

三、属性查找

类有两种属性:数据属性和函数属性

1. 类的数据属性是所有对象共享的

2. 类的函数属性是绑定给对象用的
技术分享图片
#类的数据属性是所有对象共享的,id都一样
print(id(OldboyStudent.school))

print(id(s1.school))
print(id(s2.school))
print(id(s3.school))

‘‘‘
4377347328
4377347328
4377347328
4377347328
‘‘‘



#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
print(OldboyStudent.learn)
print(s1.learn)
print(s2.learn)
print(s3.learn)
‘‘‘
<function OldboyStudent.learn at 0x1021329d8>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
View Code

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

#例子
class OldboyStudent:
    school=oldboy
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex
    def learn(self):
        print(%s is learning %self.name) #新增self.name

    def eat(self):
        print(%s is eating %self.name)

    def sleep(self):
        print(%s is sleeping %self.name)


s1=OldboyStudent(李坦克,,18)
s2=OldboyStudent(王大炮,,38)
s3=OldboyStudent(牛榴弹,,78)
类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数

OldboyStudent.learn(s1) #李坦克 is learning
OldboyStudent.learn(s2) #王大炮 is learning
OldboyStudent.learn(s3) #牛榴弹 is learning
类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)

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

类即类型

  提示:python的class术语与c++有一定区别,与 Modula-3更像。

  python中一切皆为对象,且python3中类与类型是一个概念,类型就是类

#类型dict就是类dict
>>> list
<class list>

#实例化的到3个对象l1,l2,l3
>>> l1=list()
>>> l2=list()
>>> l3=list()

#三个对象都有绑定方法append,是相同的功能,但内存地址不同
>>> l1.append
<built-in method append of list object at 0x10b482b48>
>>> l2.append
<built-in method append of list object at 0x10b482b88>
>>> l3.append
<built-in method append of list object at 0x10b482bc8>

#操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3
>>> l1.append(3)
>>> l1
[3]
>>> l2
[]
>>> l3
[]
#调用类list.append(l3,111)等同于l3.append(111)
>>> list.append(l3,111) #l3.append(111)
>>> l3
[111] 

五、对象之间的交互

class Garen:        #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp=Demacia  #所有玩家的英雄(盖伦)的阵营都是Demacia;
    def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻击力58...;
        self.nickname=nickname  #为自己的盖伦起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。
class Riven:
    camp=Noxus  #所有玩家的英雄(锐雯)的阵营都是Noxus;
    def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻击力54;
        self.nickname=nickname  #为自己的锐雯起个别名;
        self.aggressivity=aggressivity #英雄都有自己的攻击力;
        self.life_value=life_value #英雄都有自己的生命值;
    def attack(self,enemy):   #普通攻击技能,enemy是敌人;
        enemy.life_value-=self.aggressivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值。 
实例出俩英雄

>>> g1=Garen(草丛伦)
>>> r1=Riven(锐雯雯)
交互:锐雯雯攻击草丛伦,反之一样

>>> g1.life_value
455
>>> r1.attack(g1)
>>> g1.life_value
401 
补充:

  garen_hero.Q()称为向garen_hero这个对象发送了一条消息,让他去执行Q这个功能,类似的有:

  garen_hero.W()

  garen_hero.E()

  garen_hero.R()

 

 


第五章面向对象(基础篇)

1、对象的创建  类名  对象名称=null;    //声明对象  对象名称=new类名();     //实例化对象  类名对象名称=new类名()   //一步完成2、匿名对象  匿名对象就是没有明确给出名称的对象。一般匿名对象... 查看详情

第四十一篇面向对象基础(代码片段)

面向对象一、面向过程和面向对象1、面向过程编程(思想)1.上一个函数的输出是下一个函数的输入,类似流水线,机械式、顺序化2.优点:逻辑清晰,将复杂的问题流程化,细化、步骤化,进而简单化3.缺点:可扩展性差2、面... 查看详情

第五章,面向对象基础篇

5.3封装性   ? 为了解决属性必须封装且又必须访问的矛盾,只要是被封装的属性,必须通过setter和getter方法设置和取得。   ? 为前面类的私有属性加上getter和setter方法PublicvoidsetAge(inta){  Age=a;}PublicintgetAge(... 查看详情

一脚踩进java之基础篇12——面向对象

一、面向过程和面向对象1.1面向过程与面向对象都是我们编程中,编写程序的一种思维方式。  1)面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程。  例如:公司打扫卫生(... 查看详情

java基础编程篇(4.面向对象上)(代码片段)

...言尚硅谷-Java课程-笔记(用于自己复习)终于把面向对象看完了🤣,总结一下,基础篇就结束啦~一、类与对象1.面向对象学习的三条主线Java类及类的成员:属性、方法、构造器;代码块、内部类面向... 查看详情

javase之基础篇——面向对象

...会贯通,各个知识点之间可以相互调用。本文给大家介绍面向对象的相关知 查看详情

dart语法篇之面向对象基础(代码片段)

...这篇文章开始,我们继续Dart语法篇的第五讲,dart中的面向对象基础。我们知道在Dart中一切都是对象,所以面向对象在Dart开发中是非常重要的。此外它还和其他有点不一样的地方,比如多继承mixin、构造器不能被重载... 查看详情

python基础篇_006_面向对象(代码片段)

面向对象1.初识类:#定义一个函数,我们使用关键字def"""def函数名(参数):‘‘‘函数说明‘‘‘函数体return返回值"""deffunc():print("funcexecute...")#定义一个类使用关键字class"""class类名:‘‘‘类说明‘‘‘类体"""classC:passclassPerson:role... 查看详情

python基础篇:面向对象怎样炼成的(代码片段)

前言大家好,我是辣条哥今天好好给大家分析一下面向对象编程,面向对象编程是一种非常流行的“编程范式”(programmingparadigm),所谓编程范式就是“程序设计的方法论”,简单的说就是程序员对程序... 查看详情

[python面向对象]--基础篇(代码片段)

1.#类#类就是一个模板,模板里可以包含多个函数,函数里实现一些功能#定义一个类classbar:deffoo(self,agr):print(self,agr)obj=bar()print(obj)print(obj.foo("调用类的方法"))2.#方法#把函数写在类里就是方法#构造方法#普通方法classperson:def__init__(s... 查看详情

java基础篇之面向对象(代码片段)

一、类和对象什么是类类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。现实中,描述一类事物:属性:就是该事物的状态信息。行为:就是该事物能够做什么。... 查看详情

rk3568平台开发系列讲解(驱动基础篇)linux内核面向对象思想之继承

查看详情

rk3568平台开发系列讲解(驱动基础篇)linux内核面向对象思想之封装

查看详情

py---------面向对象基础篇(代码片段)

一、引子你现在是一家游戏公司的开发人员,现在你需要开发一款叫做《人猫大战》的小游戏,你就思考呀,人猫大战,那至少需要两个角色,一个是人,一个是猫,且人和猫有不同的技能,比如人拿棍打狗,狗可以咬人,让我... 查看详情

java自用基础编程篇-4.面向对象(中)(代码片段)

...言尚硅谷-Java课程-笔记(用于自己复习)以下是面向对象(中)的内容🤣一、面向对象的特征二:继承性1.为什么要有类的继承性?(继承性的好处)①减少了代码的冗余,提高了代码的复用性... 查看详情

javascript基础篇

对象Javascript是一种面向对象的语言,因此可以使用面向对象的思想来进行javascript程序设计对象就是由一些彼此相关的属性和方法集合在一起而构成的一个数据实体。js内置对象作为一门编程语言,JavaScript提供了一些内置的对象... 查看详情

一脚踩进java之基础篇16——面向对象(构造方法)

一、什么是构造方法呢?从字面上理解即为构建创造时用的方法,即就是对象创建时要执行的方法。既然是对象创建时要执行的方法,那么只要在new对象时,知道其执行的构造方法是什么,就可以在执行这个方法的时候给对象进... 查看详情

java自用基础编程篇-4.面向对象(下)(代码片段)

一、关键字:staticstatic:静态的1.可以用来修饰的结构:主要用来修饰类的内部结构属性、方法、代码块、内部类2.static修饰属性:静态变量(或类变量)2.1属性,是否使用static修饰,又分为:静态属... 查看详情