前言

  师门中每逢成人礼就要下山历练一番,小掌门今年成人礼,下山也有一段时日。可恰逢年底,今年百姓收成都不是很好,各大店铺也很少招人,再加上学艺不精,小掌门无事可做就只能饿肚子了。后来小掌门饿的实在不行,只好沿街乞讨。其时惨状如图:

 

 

初识面向对象

  就这样每天风吹日晒地乞讨,后来小掌门发现自己每天所获得的馒头都比其他同行的小乞丐少好多,他发现其他小乞丐都有自己的广告语,然后小掌门稍一改进,便成了如下模样

每次要饭前小掌门都在地上写上几个字

def beg():#定义一个要饭函数
    print('求各位给个馒头吃')


if __name__ == '__main__':
    beg()

就这样,小掌门的馒头比以往多了起来,时不时也分点馒头给其他乞丐。

  一天,过来一个老叫花对小掌门说:“孩子啊,你这样每天要饭前还得找个树枝在地上写一遍字,其实你可以自己做个招牌啊,就跟那人一样”,老叫花指了指对面走过来的另一个乞讨的年轻人。

小掌门一拍脑门,是啊,我做一个招牌就不用每次都写一遍了,小掌门找了一块破木板,在上面好好提了几笔

class Begger:
    def __init__(self,name,age,money):
        self.name=name
        self.age=age
        self.money=money
    def beg(self):  # 定义一个要饭函数
        print('求各位给个馒头吃')



if __name__ == '__main__':
    zm=Begger('古墓派掌门','18',-10)
    zm.beg()

老叫花见小掌门挺聪明,笑着说:“看来你已经理解面向对象了”。

“前辈,什么叫面向对象啊”,小掌门瞪着水汪汪的大眼睛问道。

“说起面向对象,还得从面向过程说起”

 

面向对象vs面向过程

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

 

面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。

面向对象的程序设计的

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。

在python 中面向对象的程序设计并不是全部。

面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

了解一些名词:类、对象、实例、实例化

类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程(这在生活中表现的不明显,我们在后面再慢慢解释)

 

类的声明

 1 #class 类名:
 2 #    '类的文档字符串'
 3 #    类体
 4 #如:
 5 class Begger:
 6     def __init__(self,name,age,money):
 7         self.name=name
 8         self.age=age
 9         self.money=money
10     def beg(self):  # 定义一个要饭函数
11         print('求各位给个馒头吃')

在对象实例化时,会自动调用__init__函数,完成对象初识化,相当于c++,java中的构造函数

上述代码定义了一个Begger类,在实例化对象时,会自动初始化name,age,money实例属性

上面提到两个名词‘实例化对象’,‘实例属性’,下面我一一道来

实例化对象

类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征

zm=Begger('古墓派掌门','18',-10)

实例属性与类属性及私有属性

  1:实例属性:

    最好在__init__(self,...)中初始化

    内部调用时都需要加上self.

    外部调用时用instancename.propertyname

  2:类属性:

    在__init__()外初始化

    在内部用classname.类属性名调用

    外部既可以用classname.类属性名又可以用instancename.类属性名来调用

  3:私有属性:

    1):单下划线_开头:只是告诉别人这是私有属性,外部依然可以访问更改

    2):双下划线__开头:外部不可通过instancename.propertyname来访问或者更改

      实际将其转化为了_classname__propertyname

如我们在乞丐类(Begger)中加一个count类属性,用来计算小乞丐的个数,每个小乞丐加一个婚姻状况(marriage)私有属性:

(内心戏:没钱还想结婚,做梦吧)

 1 class Begger:
 2     count=0  #这是一个类属性
 3     def __init__(self,name,age,money,single=True):
 4         self.name=name #实例属性
 5         self.age=age
 6         self.money=money
 7         self._single=True #私有属性
 8         Begger.count+=1
 9     def beg(self):  # 定义一个要饭函数
10         print('求各位给个馒头吃')
11 
12 
13 
14 if __name__ == '__main__':
15     zm=Begger('古墓派掌门','18',-10)
16     zm.beg()
17     print("小乞丐个数:%s"%Begger.count)

类方法与静态方法

  1:普通类方法:

    def fun_name(self,...):

      pass

    外部用实例调用

  2:静态方法:@staticmethod            

      不能访问实例属性!!!   参数不能传入self!!!

      与类相关但是不依赖类与实例的方法!!

  3:类方法:@classmethod

      不能访问实例属性!!!   参数必须传入cls!!!

      必须传入cls参数(即代表了此类对象-----区别------self代表实例对象),并且用此来调用类属性:cls.类属性名

  *静态方法与类方法都可以通过类或者实例来调用。其两个的特点都是不能够调用实例属性

示例如下:

 1 class Begger:
 2     count=0  #这是一个类属性
 3     def __init__(self,name,age,money,single=True):
 4         self.name=name #实例属性
 5         self.age=age
 6         self.money=money
 7         self._single=True #私有属性
 8         Begger.count+=1
 9     def beg(self):  # 定义一个要饭函数,普通类方法
10         print('求各位给个馒头吃')
11 
12     @staticmethod
13     def beg_skill():#定义一个乞讨技巧函数,静态方法
14         print("乞讨技巧")
15 
16 
17     @classmethod
18     def beg_counter(cls):
19         print("小乞丐个数:%s" % Begger.count)
20 
21 
22 if __name__ == '__main__':
23     zm=Begger('古墓派掌门','18',-10)
24     zm.beg()
25     zm.beg_skill()
26     Begger.beg_counter()

tip:类属性与类方法是类固有的方法与属性,不会因为实例不同而改变,写他们的目的是减少多实例时所创造出来的内存空间,加快运行速度

封装、继承、多态

“封装、继承、多态并称为类的三大特性,也是面向对象的一个主要特点”老叫花说道“下面我就一一跟你讲”

 

封装

封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏

封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。你用的那个乞讨类中的乞讨技巧就是很好的体现,别人只看到你表现出的乞讨的形式,并不知道你在背后所做的何种工作” 老叫花意味深长地说。

 

property特性

 

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则


ps:面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类公开
【private】
这种封装对谁都不公开

python并没有在语法上把它们三个内建到自己的class机制中,在C++或java里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现

用法如下

class Begger:
    count=0  #这是一个类属性
    def __init__(self,name,age,money,single=True):
        self._name=name
        self._age=age
        self._money=money
        self._single=True #私有属性
        Begger.count+=1
    def beg(self):  # 定义一个要饭函数,普通类方法
        print('求各位给个馒头吃')
    @property
    def age(self):
        return self._age

    @age.setter
    def age(self,value):
        self._age=value

    @age.deleter
    def age(self):
        del self._age
    @staticmethod
    def beg_skill():#定义一个乞讨技巧函数,静态方法
        print("乞讨技巧")
    @classmethod
    def beg_counter(cls):
        print("小乞丐个数:%s" % Begger.count)


if __name__ == '__main__':
    zm=Begger('古墓派掌门','18',-10)
    print(zm.age)#获取年龄属性
    zm.age=20#设置年龄属性
    print(zm.age)
    del zm.age#删除年龄属性

 

继承

 

继承,以通用的类为基础建立专门的类对象

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类


“说起继承,老叫花子我可就有话说了,什么叫继承,就是儿子继承老子的东西。‘龙生龙,凤生凤,老鼠的儿子会打洞’。虽然说古人有云,‘王侯将相宁有种乎’ ,但有钱真的可以为所欲为,地主的儿子生下来就会继承老子的东西成为富二代,跟咱们这些臭要饭的就不一样了。我来给你举几个例子 ”

 1 class Person: #定义一个人类
 2     def __init__(self,name,age,money,single=True):
 3         self.name=name #实例属性
 4         self.age=age
 5         self.money=money
 6         self._single=True #私有属性
 7 class Begger(Person):#定义一个乞丐类,继承Person
 8     # count=0  #这是一个类属性
 9 
10     def beg(self):  # 定义一个要饭函数,普通类方法
11         print('求各位给个馒头吃')
12 
13     @staticmethod
14     def beg_skill():#定义一个乞讨技巧函数,静态方法
15         print("乞讨技巧")
16     # @classmethod
17     # def beg_counter(cls):
18     #     print("小乞丐个数:%s" % Begger.count)
19 
20 
21 if __name__ == '__main__':
22     zm=Begger('古墓派掌门','18',-10)
23     zm.beg()
24     zm.beg_skill()
25     # Begger.beg_counter()

tip:用已经有的类建立一个新的类,这样就重用了已经有的软件中的一部分设置大部分,大大生了编程工作量,这就是常说的软件重用,不仅可以重用自己的类,也可以继承别人的,比如标准库,来定制新的数据类型,这样就是大大缩短了软件开发周期,对大型软件开发来说,意义重大.

 

在python3中,子类新建与父类重名的方法叫重写,子类执行父类的方法也可以直接用super方法(这些与c++,java类似),如我们重写一下子类init方法

 1 class Person:
 2     def __init__(self,name,age,money,single=True):
 3         self.name=name #实例属性
 4         self.age=age
 5         self.money=money
 6         self._single=True #私有属性
 7 class Begger(Person):
 8     count=0  #这是一个类属性
 9     
10     #重写父类__init__
11     def __init__(self,name,age,money,single=True):
12         super(Begger,self).__init__(name,age,money,single)
13         #或者
14         # Person.__init__(self,name,age,money,single)
15         Begger.count+=1
16         
17         
18         
19     def beg(self):  # 定义一个要饭函数,普通类方法
20         print('求各位给个馒头吃')
21     @property
22     def age(self):
23         return self._age
24 
25     @age.setter
26     def age(self,value):
27         self._age=value
28 
29     @age.deleter
30     def age(self):
31         del self._age
32     @staticmethod
33     def beg_skill():#定义一个乞讨技巧函数,静态方法
34         print("乞讨技巧")
35     @classmethod
36     def beg_counter(cls):
37         print("小乞丐个数:%s" % Begger.count)
38 
39 
40 if __name__ == '__main__':
41     zm=Begger('古墓派掌门','18',-10)
42     zm.beg_counter()
43     zm.beg_skill()

 

抽象类与接口类

继承有两种用途:

一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)  

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
class Alipay:
    '''
    支付宝支付
    '''
    def pay(self,money):
        print('支付宝支付了%s元'%money)

class Applepay:
    '''
    apple pay支付
    '''
    def pay(self,money):
        print('apple pay支付了%s元'%money)


def pay(payment,money):
    '''
    支付函数,总体负责支付
    对应支付的对象和要支付的金额
    '''
    payment.pay(money)


p = Alipay()
pay(p,200)

开发中容易出现的问题

class Alipay:
    '''
    支付宝支付
    '''
    def pay(self,money):
        print('支付宝支付了%s元'%money)

class Applepay:
    '''
    apple pay支付
    '''
    def pay(self,money):
        print('apple pay支付了%s元'%money)

class Wechatpay:
    def fuqian(self,money):
        '''
        实现了pay的功能,但是名字不一样
        '''
        print('微信支付了%s元'%money)

def pay(payment,money):
    '''
    支付函数,总体负责支付
    对应支付的对象和要支付的金额
    '''
    payment.pay(money)


p = Wechatpay()
pay(p,200)   #执行会报错

接口初成:手动报异常:NotImplementedError来解决开发中遇到的问题

class Payment:
    def pay(self):
        raise NotImplementedError

class Wechatpay(Payment):
    def fuqian(self,money):
        print('微信支付了%s元'%money)


p = Wechatpay()  #这里不报错
pay(p,200)      #这里报错了

借用abc模块来实现接口

from abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        pass


class Wechatpay(Payment):
    def fuqian(self,money):
        print('微信支付了%s元'%money)

p = Wechatpay() #不调就报错了

 

实践中,继承的第一种含义意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

继承的第二种含义非常重要。它又叫“接口继承”。
接口继承实质上是要求“做出一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理实现了特定接口的所有对象”——这在程序设计上,叫做归一化。

归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合——就好象linux的泛文件概念一样,所有东西都可以当文件处理,不必关心它是内存、磁盘、网络还是屏幕(当然,对底层设计者,当然也可以区分出“字符设备”和“块设备”,然后做出针对性的设计:细致到什么程度,视需求而定)。

在python中根本就没有一个叫做interface的关键字,上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,如果非要去模仿接口的概念,可以借助第三方模块

抽象类

与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

#一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

# class Txt(All_file):
#     pass
#
# t1=Txt() #报错,子类没有定义抽象方法

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

python中实现抽象类

 

 

 

多态

多态指的是一类事物有多种形态

如:

class Person:
    def __init__(self,name,age,money,single=True):
        self.name=name #实例属性
        self.age=age
        self.money=money
        self._single=True #私有属性
class landlord(Person):
    def __init__(self):
        print("这是一个地主")
class prince(Person):
    def __init__(self):
        print("这是一个王子")
class Begger(Person):#乞丐类
    count=0  #这是一个类属性

    #重写父类__init__
    def __init__(self,name,age,money,single=True):
        super(Begger,self).__init__(name,age,money,single)
        #或者
        # Person.__init__(self,name,age,money,single)
        Begger.count+=1
    def beg(self):  # 定义一个要饭函数,普通类方法
        print('求各位给个馒头吃')
    @property
    def age(self):
        return self._age

    @age.setter
    def age(self,value):
        self._age=value

    @age.deleter
    def age(self):
        del self._age
    @staticmethod
    def beg_skill():#定义一个乞讨技巧函数,静态方法
        print("乞讨技巧")
    @classmethod
    def beg_counter(cls):
        print("小乞丐个数:%s" % Begger.count)


if __name__ == '__main__':
    zm=Begger('古墓派掌门','18',-10)
    zm.beg_counter()
    zm.beg_skill()
    wz=prince()
    dz=landlord()

 

鸭子类型

  Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

 

 

 

结语

 

 

 

 

 

 

“以上就是面向对象的解释了,小家伙可还满意”老叫花拍了拍酒葫芦道

“前辈你懂这么多为什么还是一个要饭的啊”

“其实我以前跟他一样”说着,老叫花指了指对面的那个年轻人

“前辈,你再给我讲点其他的呗”

“好好,回头老叫花我慢慢给你讲点其他的,不过你得给我弄点酒。。。。。。。。。。。。”

 

 

 

 

阅读目录

楔子

你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢?
 
你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色
 人和狗的角色定制1

上面两个方法相当于造了两个模子,游戏里的每个人和每条狗都拥有相同里的属性。游戏开始,你根据一个人或一只狗传入的具体信息来塑造一个具体的人或者狗,怎么生成呢?

 生成具体的人和狗

两个角色对象生成了,狗和人还有不同的功能呀,狗会咬人,人会打狗,对不对? 怎么实现呢,。。想到了, 可以每个功能再写一个函数,想执行哪个功能,直接 调用 就可以了,对不?

 bark和walk
 调用walk和bark

上面的功能实现的简直是完美!

但是仔细玩耍一会,你就不小心干了下面这件事

 在玩耍中犯了一个小错误

事实 上,从你写的代码上来看,这并没出错。很显然,人是不能调用狗的功能的,但在你的程序例没有做限制,如何在代码级别实现这个限制呢?

 限制功能全新代码
 生成具体的人和狗
 无法调用了

你是如此的机智,这样就实现了限制人只能用人自己的功能啦。

刚刚你用的这种编程思想其实就是简单的面向对象编程,我们创造了两个模子表示游戏里所有的人和狗之后,剩下的狗叫或者人走对于这两个模子来说就不重要了。具体人he狗之间的交互就等着你去使用了。假如你和狗打起来了,这时候你是走路还是拿棍子打狗就由你自己决定了。那你的每一个决定可能都影响着你这场游戏的输赢。这也是不确定的。和我们之前写代码按部就班的走,最终都会实现我们要完成的事情不太一样了。

尽管如此,我们也只完成了这个游戏非常小的一部分。还有很多功能都没有实现。

刚才你只是阻止了两个完全 不同的角色 之前的功能混用, 但有没有可能 ,同一个种角色,但有些属性是不同的呢? 比如 ,大家都打过cs吧,cs里有警察和恐怖份子,但因为都 是人, 所以你写一个角色叫 person(), 警察和恐怖份子都 可以 互相射击,但警察不可以杀人质,恐怖分子可以,这怎么实现呢? 你想了说想,说,简单,只需要在杀人质的功能里加个判断,如果是警察,就不让杀不就ok了么。 没错, 这虽然 解决了杀人质的问题,但其实你会发现,警察和恐怖分子的区别还有很多,同时又有很多共性,如果 在每个区别处都 单独做判断,那得累死。 

你想了想说, 那就直接写2个角色吧, 反正 这么多区别, 我的哥, 不能写两个角色呀,因为他们还有很多共性 , 写两个不同的角色,就代表 相同的功能 也要重写了,是不是我的哥? 。。。

好了, 话题就给你点到这, 再多说你的智商也理解不了了!

面向过程 VS 面向对象 

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

 

面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。

面向对象的程序设计的

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。

在python 中面向对象的程序设计并不是全部。

面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

了解一些名词:类、对象、实例、实例化

类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程(这在生活中表现的不明显,我们在后面再慢慢解释)

初识类和对象

python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了

>>> dict #类型dict就是类dict
<class 'dict'>
>>> d=dict(name='eva') #实例化
>>> d.pop('name') #向d发一条消息,执行d的方法pop
'eva'

从上面的例子来看,字典就是一类数据结构,我一说字典你就知道是那个用{}表示,里面由k-v键值对的东西,它还具有一些增删改查的方法。但是我一说字典你能知道字典里具体存了哪些内容么?不能,所以我们说对于一个类来说,它具有相同的特征属性和方法。

而具体的{‘name’:’eva’}这个字典,它是一个字典,可以使用字典的所有方法,并且里面有了具体的值,它就是字典的一个对象。对象就是已经实实在在存在的某一个具体的个体。

 

再举一个其他的例子,通俗一点,比如你现在有一个动物园,你想描述这个动物园,那么动物园里的每一种动物就是一个类,老虎、天鹅、鳄鱼、熊。他们都有相同的属性,比如身高体重出生时间和品种,还有各种动作,比如鳄鱼会游泳,天鹅会飞,老虎会跑,熊会吃。

但是这些老虎熊啥的都不是具体的某一只,而是一类动物。虽然他们都有身高体重,但是你却没有办法确定这个值是多少。如果这个时候给你一只具体的老虎,而你还没死,那你就能给他量量身高称称体重,这些数值是不是就变成具体的了?那么具体的这一只老虎就是一个具体的实例,也是一个对象。不止这一只,其实每一只具体的老虎都有自己的身高体重,那么每一只老虎都是老虎类的一个对象。

在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。

 

 

类的相关知识

初识类

声明

def functionName(args):
     '函数文档字符串'
      函数体 

复制代码
'''
class 类名:
    '类的文档字符串'
    类体

阅读目录

楔子

你现在是一家游戏公司的开发人员,现在需要你开发一款叫做<人狗大战>的游戏,你就思考呀,人狗作战,那至少需要2个角色,一个是人, 一个是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎么描述这种不同的角色和他们的功能呢?
 
你搜罗了自己掌握的所有技能,写出了下面的代码来描述这两个角色
 人和狗的角色定制1

上面两个方法相当于造了两个模子,游戏里的每个人和每条狗都拥有相同里的属性。游戏开始,你根据一个人或一只狗传入的具体信息来塑造一个具体的人或者狗,怎么生成呢?

 生成具体的人和狗

两个角色对象生成了,狗和人还有不同的功能呀,狗会咬人,人会打狗,对不对? 怎么实现呢,。。想到了, 可以每个功能再写一个函数,想执行哪个功能,直接 调用 就可以了,对不?

 bark和walk
 调用walk和bark

上面的功能实现的简直是完美!

但是仔细玩耍一会,你就不小心干了下面这件事

 在玩耍中犯了一个小错误

事实 上,从你写的代码上来看,这并没出错。很显然,人是不能调用狗的功能的,但在你的程序例没有做限制,如何在代码级别实现这个限制呢?

 限制功能全新代码
 生成具体的人和狗
 无法调用了

你是如此的机智,这样就实现了限制人只能用人自己的功能啦。

刚刚你用的这种编程思想其实就是简单的面向对象编程,我们创造了两个模子表示游戏里所有的人和狗之后,剩下的狗叫或者人走对于这两个模子来说就不重要了。具体人he狗之间的交互就等着你去使用了。假如你和狗打起来了,这时候你是走路还是拿棍子打狗就由你自己决定了。那你的每一个决定可能都影响着你这场游戏的输赢。这也是不确定的。和我们之前写代码按部就班的走,最终都会实现我们要完成的事情不太一样了。

尽管如此,我们也只完成了这个游戏非常小的一部分。还有很多功能都没有实现。

刚才你只是阻止了两个完全 不同的角色 之前的功能混用, 但有没有可能 ,同一个种角色,但有些属性是不同的呢? 比如 ,大家都打过cs吧,cs里有警察和恐怖份子,但因为都 是人, 所以你写一个角色叫 person(), 警察和恐怖份子都 可以 互相射击,但警察不可以杀人质,恐怖分子可以,这怎么实现呢? 你想了说想,说,简单,只需要在杀人质的功能里加个判断,如果是警察,就不让杀不就ok了么。 没错, 这虽然 解决了杀人质的问题,但其实你会发现,警察和恐怖分子的区别还有很多,同时又有很多共性,如果 在每个区别处都 单独做判断,那得累死。 

你想了想说, 那就直接写2个角色吧, 反正 这么多区别, 我的哥, 不能写两个角色呀,因为他们还有很多共性 , 写两个不同的角色,就代表 相同的功能 也要重写了,是不是我的哥? 。。。

好了, 话题就给你点到这, 再多说你的智商也理解不了了!

面向过程 VS 面向对象 

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。

应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。

 

面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的属性和方法),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙互相缠斗着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取。

面向对象的程序设计的

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人某一参数的修改极有可能导致阴霸的技能出现,一刀砍死3个人,这个游戏就失去平衡。

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。

在python 中面向对象的程序设计并不是全部。

面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

了解一些名词:类、对象、实例、实例化

类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程(这在生活中表现的不明显,我们在后面再慢慢解释)

初识类和对象

python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了

>>> dict #类型dict就是类dict
<class 'dict'>
>>> d=dict(name='eva') #实例化
>>> d.pop('name') #向d发一条消息,执行d的方法pop
'eva'

从上面的例子来看,字典就是一类数据结构,我一说字典你就知道是那个用{}表示,里面由k-v键值对的东西,它还具有一些增删改查的方法。但是我一说字典你能知道字典里具体存了哪些内容么?不能,所以我们说对于一个类来说,它具有相同的特征属性和方法。

而具体的{‘name’:’eva’}这个字典,它是一个字典,可以使用字典的所有方法,并且里面有了具体的值,它就是字典的一个对象。对象就是已经实实在在存在的某一个具体的个体。

 

再举一个其他的例子,通俗一点,比如你现在有一个动物园,你想描述这个动物园,那么动物园里的每一种动物就是一个类,老虎、天鹅、鳄鱼、熊。他们都有相同的属性,比如身高体重出生时间和品种,还有各种动作,比如鳄鱼会游泳,天鹅会飞,老虎会跑,熊会吃。

但是这些老虎熊啥的都不是具体的某一只,而是一类动物。虽然他们都有身高体重,但是你却没有办法确定这个值是多少。如果这个时候给你一只具体的老虎,而你还没死,那你就能给他量量身高称称体重,这些数值是不是就变成具体的了?那么具体的这一只老虎就是一个具体的实例,也是一个对象。不止这一只,其实每一只具体的老虎都有自己的身高体重,那么每一只老虎都是老虎类的一个对象。

在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。

 

 

类的相关知识

初识类

声明

def functionName(args):
     '函数文档字符串'
      函数体 

复制代码
'''
class 类名:
    '类的文档字符串'
    类体
版权声明:本文为qflyue原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/qflyue/p/8298555.html