python学习之路-基础篇-面向对象-day05

来源:互联网 发布:js中push 编辑:程序博客网 时间:2024/06/01 18:52

大纲
1.什么是面向对象
2.类和对象的概念
3.面向对象3大特性
4.程序分析讲解3大特性
1)类的创建
2)类变量和实例变量
3)构造函数
4)析构函数
5)私有方法和私有属性
6)继承实例讲解
7)多态实例讲解
5.静态方法,类方法和属性方法

一.什么是面向对象?
在说面向对象之前我们先来说一说编程范式,指的是计算机编程的基本风格或典范模式,两种最重要的编程范式就是面向对象和面向过程。那么什么是面向过程呢?什么又是面向对象呢?他们之间又有什么区别呢?
面向过程(procedural programming):就是程序从上到下一步一步按照顺序向下执行。这样对于程序的修改就会很困难,一般适合写一些固定不变的程序
面向对象(object oriented programming—–oop):就是利用类和对象创建出各种模型,所以面向对象是以功能来划分问题,而不是按照步骤。它是的程序的可扩展性和可维护性变强
二.类和对象
由面向对象的概念我们抓住两个比较关键的字眼,那就是类和对象。
类(class):对一类拥有相同属性的抽象就是类
对象(object):把类进行实例化后的实例就是对象。一个类必须实例化(初始化)后才可以被程序调用
记住几句话:
世界万物皆是对象,世界万物皆可分类
只要是对象就属于某个类,只要是对象就肯定有属性
三.面向对象的三个特性
1.封装(encapsulation):在类中对数据进行赋值,只能内部使用,外部用户透明
2.继承(inheritance):一个类可以派出多个子类,在父类里面的属性和方法自动被之类继承
3.多态(polymorphisn):一个接口多种实现,一个基类衍生出不同的子类,并且每个子类继承相同的方法名,同时对父类方法做不同的实现,这就是一个事物实现多种形态
四.程序分析
下面我们就来看一个具体的面向对象的程序来对面向对象进行分析

class Animal(object):    # 1.定义一个类使用class关键字;2.类名大写,此处类名是Animal;3.object是基类(新式类的写法)    n="abc"    #n是类变量    def __init__(self,name,age):    #def __init__(self,name,age)是构造函数,作用是在实例化时做类的初始化,这里self的作用是为了接收变量名,例如下面的d    #原理:先将d存入内存,再向内存里面存入相应的变量,这里是d.name,d.age,(所以这里并不是先开辟一片内存然后将变量存入内存    #返回内存地址给d这个实例)而是直接通过d取值       self.name=name       self.age=age    #self.name=name实例化变量(类的静态属性)作用域是实例本身    def bulk(self):    #定义了类的方法,就是功能(类的动态属性)        print("hello,my name is %s,i am so cute age is %s"%(self.name,self.age))d=Animal("dog",5)    #此处d就是Animal这个类的实例化(实例化就是把一个类变成一个对象的过程)结果为hello,my name is dog,i am so cute age is 5d.bulk()

此处我们再强化一下这段程序中的几个概念
1.类的创建class
class 类名(object)
这里object是新式类的标志
class 类名()
这就是经典类
经典类和新式类的最大的区别就是再多继承上的顺序问题
这里举个例子,可以在linux环境下的python进行实验以下代码,得出的结论是:
python2经典类的继承是深度优先,新式类的继承是广度优先(D->B->C->A)
python3无论是哪种都是广度优先,所以无论怎样建议必须加上object

class A(object):    def __init__(self):        print("i am A")class B(A):    def __init__(self):        print("i am B")class C(A):    def __init__(self):        print("i am C")class D(B,C):    def __init__(self):        print("i am D")

2.类变量和实例变量
在上面的程序中已经标注

#接着上面的代码d2=Animal("cat",3)print(Animal.n)#类变量不需要实例化就可以直接调用  abcd.n="def"print(d.n)  #defprint(d2.n)  #abc#只是在d中开辟了一块新的内存存放n的值,并没有改变本身的类变量Animal.n="123"print(Animal.n)  #123print(d.n)  #def  因为实例变量里面有新的赋值d.n="def"print(d2.n) #123#如果实例变量里面没有关于n的变量,则类变量改变del d.age#删除d的age属性

3.构造函数(初始化)

__init__()

4.这里补充一个析构函数,在实例释放或者销毁的时候自动执行,通常用于做一些收尾工作,比如关闭数据库连接,关闭打开的临时文件

def __del__(self):

5.私有方法,私有属性(即外部不能直接调用)

class Animal(object):    def __init__(self,name,age):        self.name=name        self.__age=age#两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。#在类内部的方法中使用时  self.s=Animal("dog",3)print(s.name) #dogprint(s.__age)#执行结果AttributeError: 'Animal' object has no attribute '__age

要想访问私有属性,必须在类内部写相应的方法来实现

class Animal(object):    def __init__(self,name,age):        self.name=name        self.__age=age        #两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。        #在类内部的方法中使用时  self.    def show_age(self):        print("%s age is %s"%(self.name,self.__age))s=Animal("dog",3)print(s.name) #dog#print(s.__age)#执行结果AttributeError: 'Animal' object has no attribute '__ages.show_age()#结果:dog age is 3

私有方法同私有属性类似

    def __eat(self,food):        print("%s is eating %s"%(self.name,food))        #私有方法

6.继承实例讲解

class Animal(object):    def __init__(self,name,age):        self.name=name        self.age=age    def eat(self):        print("%s like eating"%self.name)class Cat(Animal):    def __init__(self,name,age,song):        Animal.__init__(self.name,age)#不推荐        super(Cat,self).__init__(name,age)        #推荐,优点1.不需要考虑父类名称的改变2.多继承的时候不需要考虑先后问题        #多继承的时候,所继承的父类的静态属性要一致        self.song = []

7.多态实例讲解

class Animal(object):    def __init__(self,name):        self.name=name    def talk(self):        print("bulk...")class Cat(Animal):    def talk(self):        print("miaomiao...")class Dog(Animal):    def talk(self):        print("wowo...")a=Cat("jiafeimao")a.talk()b=Dog("coco")b.talk()#这样带来一个问题当我有一百种甚至更多的动物有不同的叫声的时候,每种动物都需要.talk()来叫#利用多态我们可以将talk写成一个公共的接口,给多个对象去调用def animal_talk(obj):     obj.talk()animal_talk(a)animal_talk(b)#谁叫传谁进去即可

五.python静态方法,类方法和属性方法
下面我们还是通过具体的代码来分析这三种方法的实现
1.静态方法(用@staticmethod包装实现)

#代码一:class Cat(object):    def __init__(self,name):        self.name=name    def eat(self):        print("%s is eating %s"%(self.name,"fish"))c=Cat("coco")c.eat()#执行结果  coco is eating fish#代码二:class Cat(object):    def __init__(self,name):        self.name=name    @staticmethod    def eat(self):        print("%s is eating %s"%(self.name,"fish"))c=Cat("coco")c.eat()#执行结果  TypeError: eat() takes exactly 1 positional argument (0 given)#第二段程序除了给eat加了一个静态方法@staticmethod,其余并未改变,但是结果却错了?怎样修改才能不报错呢#代码三:class Cat(object):    def __init__(self,name):        self.name=name    @staticmethod    def eat():        print("%s is eating %s"%("jiafeimao","fish"))c=Cat("coco")c.eat()#执行结果为   jiafeimao is eating fish 这是为什么呢??#静态方法只是名义上归类管理,实际上在静态里面是访问不了类或者实例里面的任何属性的,也就是说eat()和类没有任何关系了#那么怎样给name传参数呢#代码四:class Cat(object):    def __init__(self,name):        self.name=name    @staticmethod    def eat(self):        print("%s is eating %s"%(self.name,"fish"))c=Cat("coco")c.eat(c)#执行结果coco is eating fish

2.类方法(用@classmethod包装实现)

class Cat(object):    n="doudou" #类变量    def __init__(self,name):        self.name=name    @classmethod    def eat(self):        print("%s is eating %s"%(self.name,"fish"))c=Cat("coco")c.eat()#执行结果   AttributeError: type object 'Cat' has no attribute 'name'class Cat(object):    n="doudou" #类变量    def __init__(self,name):        self.name=name    @classmethod    def eat(self):        print("%s is eating %s"%(self.n,"fish"))c=Cat("coco")c.eat()#执行结果  doudou is eating fish#类方法只能访问类变量不能访问实例变量

3.属性方法(用@property包装实现)

#代码1class Cat(object):    def __init__(self,name):        self.name=name    @property    def eat(self):        print("%s is eating %s"%(self.name,"fish"))c=Cat("coco")c.eat#执行结果 coco is eating fish#属性方法就是把一个变成属性,那么属性方法怎么传入参数给eat呢#代码2class Cat(object):    def __init__(self,name):        self.name=name    @property    def eat(self):        print("%s is eating"%self.name)    @eat.setter    def eat(self,food):         print("food is:",food)c=Cat("coco")c.eat="fish"c.eat#执行结果   food is: fish#           coco is eating#那么接着讨论,普通的属性可以随意的删除,那么我能删除属性方法吗?#代码3class Cat(object):    def __init__(self,name):        self.name=name    @property    def eat(self):        print("%s is eating"%self.name)c=Cat("coco")del   c.eat#显然属性方法是默认是无法删除的,执行结果为AttributeError: can't delete attribute#代码4  私有属性class Cat(object):    def __init__(self,name):        self.name=name        self.__food=None   #私有属性    @property    def eat(self):        print("%s is eating %s"%(self.name,self.__food))    @eat.setter    def eat(self,food):         print("food is:",food)         self.__food=food    @eat.deleter    def eat(self):        del self.__food        print("over")c=Cat("coco")c.eat="baozi"del c.eatc.eat#AttributeError: 'Cat' object has no attribute '_Cat__food'
原创粉丝点击