####python之面向对象###

##面向对象和面向过程##

面向过程(Procedure Oriented):是一种以过程为中心的编程思想。以正在发生的为主要目标进行编程,就是分析出解决问题所需要的步骤然后用函数把这些步骤一步步实现,使用的时候一个个一次调用。
1.把完成某一个需求的 所有步骤 从头到尾 逐步实现
2.根据开发要求,将某些功能独立的代码封装成一个又一个函数
3.最后完成的代码,就是顺序的调用不同的函数
特点:
1.注重步骤和过程,不注重职责分工
2.如果需求复杂,代码变得非常复杂
3.开发复杂的项目的时候,没有固定的套路,开发难度很大
面向对象(Object Oriented Programming):简称oop,是一种程序设计思想,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数;

相比较函数,面向对象是更大的封装,根据职责在一个对象中封装多个方法
1.在完成某一个需求前,首先确定职责–要做的事(方法)
2.根据职责确定不同的对象,在对象内部封装不同的方法(多个)
3.最后完成代码,就是顺序的让不同的对象调用不同的方法
特点:
1.注重对象和职责,不同的对象承担不同的职责
2.更加适合对复杂的需求变化,是专门应对复杂项目的开发,提供固定的套路
3.需要在面向过程的基础上,再学习一些面向对象的语法

面向对象有两个核心的概念
类:是一类具有相同特征或行为的事物的一个统称
对象:由类创建出来的一个具体的存在
类和对象的关系:先有类再有对象
类是模板 对象是根据这个模板创建出来的
类只需要有一个 对象可以有多个

类:属性(这一类事务的共同信息) 和 方法(你能完成的动作)
1.类名:这类事物的名字(大驼峰命名法)
大驼峰命名法:
1.每个单词的首字母大写
2.单词与单词之间没有下划线
2.属性:这个类创建出来的对象有什么特征
3.方法:这个类创建出来的对象有什么行为
###面向对象的定义###
创建一个水果类
属性:名字
方法: 颜色 、味道

class frutes():
    def sweet(self):  ##一个
        print('%s味道很甜')
    def colour(self):
        print('颜色是红色')
print(frutes())  #调用函数,显示内存地址
#创建一个对象
apple = frutes()
print(apple) #调用函数,显示内存地址
frutes.name = 'Apple'
print(frutes.name)
apple.colour()
apple.sweet()

banana = frutes()
print(banana)
banana.sweet()
banana.colour()

在创建类定义方法的时候self参数

哪一个对象调用的方法,self就是哪一个函数对象的引用;在封装的方法内部,self就表示当前调用当法对象自己,在调用的时候就不必传递self参数(定义的时候,第一个参数必须是self)

class Cat:
    def __init__(self,name,color):
        self.name = name
        self.color = color
    def get_name(self):
        print('name is %s' %self.name)
    def get_color(self):
        print('color is %s' %self.color)

tom = Cat('Tom','blue')
erpang = Cat('pang','yellow')   # 实例化两个对象
#两个对象是使用同一个类创建出来的,但是其数据不一致,相互之间没有关系

tom.get_color()  # 当对象调用方法的时候,其中self参数就是调用方法的对象本身
tom.get_name()

erpang.get_color()# 当对象调用方法的时候,其中self参数就是调用方法的对象本身
erpang.get_name()

输出结果:
color is blue
name is Tom  
 #当调用方法的对象是tom的时候,self参数就是引用的该对象,输出都是实例化该对象的时候,设置的属性

color is yellow
name is pang
 #当调用方法的对象是erpang的时候,self参数就是引用的该对象,输出都是实例化该对象的时候,设置的属性

###初始化方法__init__###
这个初始化方法是内置方法,是专门用来定义一个类据有哪些属性和方法的
由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去
注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。

使用:类名() 就可以创建一个对象,在创建对象的时候,python解释器会自动执行以下操作:1.为对象在内存中分配空间–创建对象;2.调用初始化方法为对象的属性设置初始值。

在创建对象的时候就设置对象的属性。使用默认的初始化方法对属性进行设置。

1.把希望设置的属性值,定义成__init__方法的参数
2.在方法内部使用self.属性名 = 形参 接收外部传递的参数
3.在创建对象的时候,使用类名(属性)调用
class frutes():
    def __init__(self, new_name):   ##初始化方法
       self.name = new_name
    def sweet(self):
        print('%s味道很甜' %(self.name))
    def colour(self):
        print('%s颜色是红色' %(self.name))
       #print(frutes())  #调用函数,显示内存地址
#创建一个对象
apple = frutes('Apple')
print(apple) #调用函数,显示内存地址
apple.colour()
apple.sweet()

banana = frutes('Banana')
print(banana)
banana.sweet()
banana.colour()

####str方法###
希望使用print输出对象变量的时候,能够打印自定义内容就可以利用__str__这个内置的方法了。但是输出的内容只能是字符串类型。

使用print输出对象变量时候,默认情况会输出这个变量引用的对象是由哪一个类创建的对象以及在内存中的地址

默认输出:

class frutes():
    def __init__(self, new_name):
       self.name = new_name
    def __str__(self): #返回的必须是一个字符串
        return '我是%s' %(self.name)
    def sweet(self):
        print('%s味道很甜' %(self.name))
    def colour(self):
        print('%s颜色是红色' %(self.name))
       #print(frutes())  #调用函数,显示内存地址
#创建一个对象
apple = frutes('Apple')
print(apple) #调用函数,显示内存地址
apple.colour()
apple.sweet()

banana = frutes('Banana')
print(banana)
banana.sweet()
banana.colour()


##进制改变

class frutes():
    def __init__(self, new_name):
       self.name = new_name
    #def __str__(self): #返回的必须是一个字符串
    #    return '我是%s' %(self.name)
    def sweet(self):
        print('%s味道很甜' %(self.name))
    def colour(self):
        print('%s颜色是红色' %(self.name))
       #print(frutes())  #调用函数,显示内存地址
#创建一个对象
apple = frutes('Apple')
print(apple) #调用函数,显示内存地址
apple.colour()
apple.sweet()
addr = id(apple)

banana = frutes('Banana')
print(banana)
banana.sweet()
banana.colour()
addr = id(banana)  #输出内存地址
print('%x' %(addr))  #转化成十六进制
print('%d' %(addr))  #转换成10进制的方法

##del###
如果类中定义__del__方法,那么当使用这个类实例化出来的对象在被删除的时候(把这个对象从内存中删除掉),会自动调用该方法。

class frutes():
    def __init__(self, new_name):
       self.name = new_name
    def __del__(self): #返回的必须是一个字符串
        return '我是%s' %(self.name)
    def sweet(self):
        print('%s味道很甜' %(self.name))
    def colour(self):
        print('%s颜色是红色' %(self.name))
       #print(frutes())  #调用函数,显示内存地址
#创建一个对象
apple = frutes('Apple')
print(apple.name) #调用函数,显示内存地
del apple  ##删除

print("*" * 50)
print(apple.name)

练习:
取出栈的第一个数,栈(先进后出)第一个放入的值就有最后一个

class Stack:   #创建一个类
    def __init__(self):  #初始化一个列表
        self.stack = []
    def push(self,value):  #往栈里输入值
        self.stack.append(value)
        return True
    def pop(self):   ##判断栈里是否存在值 
        if self.stack:
            item = self.stack.pop()  #定义一个变量接受pop弹出的值
            return item
        else:
            return False 
    def top(self):
        if self.stack:
            return self.stack[-1]  #取出栈里的第一个值
        else:
            return False
    def length(self):   #栈的长度
        return len(self.stack)
    def view(self):   
        return ','.join(self.stack)  #用,连接栈内的值
s= Stack() 调用函数
s.push('1')
s.push('2')
s.push('3')
item = s.pop()  #弹出值
print(s.view())

取出队列的第一个数
class Stack:
    def __init__(self):
        self.stack = []
    def push(self,value):
        self.stack.append(value)
        return True
    def pop(self):
        if self.stack:
            item = self.stack.pop(0)
            return item
        else:
            return False
    def top(self):
        if self.stack:
            return self.stack[0]
        else:
            return False
    def length(self):
        return len(self.stack)
    def view(self):
        return ','.join(self.stack)
s= Stack()
s.push('1')
s.push('2')
s.push('3')
item = s.pop()
print(s.view())

练习

class Person:
    def __init__(self,name,weight):
         self.name = name
         self.weight = weight
    def __str__(self):
        return '%s的体重是%.2f' %(self.name,self.weight)
    #在对象的方法内部,可以直接访问对象的属性
    def run(self):
        print('%s跑步' %(self.name))
        self.weight -= 0.5
    def eat(self):
        print('%s吃饭' %(self.name))
        self.weight += 1
xiaoming = Person('小明',75)
xiaoming.run()
xiaoming.eat()
print(xiaoming)
xiaomei = Person('小美',45)
xiaomei.eat()
xiaomei.run()
print(xiaomei)

1、新式类和旧式(经典)类
新式类:以object为基类的类
经典类:不以object为基类的类

在python3.X中定义的类时,如果没有指定父类,会默认使用object作为基类–python3.x中定义的类都是新式类

在python2.x中定义类时,如果没有指定父类,则不会以object作为基类

为保证编写的代码能够同时在python2.x和python3.x运行,今后在定义类时,如果没有父类,建议统一继承自object
2、类属性和类方法

类属性:针对类本身定义的属性, 使用赋值语句在class关键字下可以定义类属性,这类属性归类本身所有。使用类名.属性调用类属性

当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到,当实例并没有该属性,所以会继续查找class的该属性

3、私有属性和私有方法

私有属性:前面带两个下划线表示对变量进行私有化,私有化之后的属性属于类内部的属性,可以在内部进行访问,为不无法随便进行访问或者修改。

私有方法:方法名称前面带两个下划线表示方法私有化,可以在内部进行调用,不能使用实例在外部调用私有化方法。

定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法
4、静态方法

如果需要在类中定义一个方法,这个方法,既不需要访问实例属性也不需要调用实例方法;既不需要访问类属性也不需要调用类方法,这个时候就可以把这个方法封装成静态方法。使用@staticmethod关键字进行设置

5、设计模式——单例
设计模式:

设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一特定问题的成熟解决方案,使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性
单例设计模式:

目的:让类创建对象,在系统中只有唯一的一个实例,每一次执行类名()返回的对象,内存地址是相同的

使用__new__(cls)方法实现单例设计模式:

我们用 类名. 的方式创建对象的时候,python解释器会帮我们做两件事情,
1.为对象分配空间

__new__是一个由object基类提供的内置的静态方法,主要有两个作用: 在内存中为对象分配空间 返回对象的引用
new:负责给对象分配空间,并返回对象的引用给初始化方法

2.对象初始化

__init__(初始化方法)负责给对象初始化.
解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法

猜你喜欢

转载自blog.csdn.net/weixin_44821839/article/details/91874379