Python面向对象

本文深入探讨了Python中的面向对象编程,包括类与对象的概念、属性和方法、类方法、静态方法、特殊方法如__init__、__str__、__repr__等。通过实例展示了如何创建和使用类,以及如何利用面向对象特性进行封装,例如银行账户类的实现。此外,还介绍了类的继承和多态等核心概念。
摘要由CSDN通过智能技术生成

面向对象

python是一个面向对象语言

python把面向过程(函数)和面向对象结合的非常好

类,对象

类:设计图

类是一系列具有相同特征或者行为的事物的一个抽象

对象:根据设计图造出来的具体存在

由类创建出来的一个具体存在

Python中所有都是对象

a = 10
print(type(a)) # <class 'int'>
b = True
print(type(b)) # <class 'bool'>
def fn():
    pass

print(type(fn)) # <class 'function'>

a2 = int(10)
print(type(a2)) # <class 'int'>
print(a == a2) # True

属性,方法

属性:对象特征(名词,形容词)的描述

方法:对象具备的行为(动词)

设计类的时候,使用名词分析法分析整个业务流程,抽取出名词作为类,剩余的归为属性和方法

sb.doSth的原则,将动词归到某个类中

DDD 领域建模

def ultraman(name,age,sex,perform):
    return {
        'name': name,
        'age': age,
        'sex': sex,
        'perform': perform
    }

def shoot(m):
    print('ultraman is shooting %s'%(m['name']))

dijia = ultraman('迪迦',3000,'男','光线炮')
print(dijia)

def monster(name,m_type):
    data = {
        'name': name,
        'type': m_type
    }
    return data

def bite(u):
    print('monster bite %s'%(u['name']))

jsl = monster('机丝拉','恐龙')
print(jsl)

shoot(jsl)
bite(dijia)

shoot(dijia)
bite(jsl)

语法:

class 类名:
    def 方法名(self,其他参数):
    	pass
    
class ultraman:
    name = '奥特曼'
    def shoot(m):   //m 不是怪兽,而是self
        print('ultraman is shooting %s'%(m['name']))

dj = ultraman()
dj.name = '迪迦奥特曼'
jack = ultraman()
jack.name = '杰克奥特曼'

dj.shoot(jsl)
jack.shoot(jsl)

self

类的方法和普通方法的区别,就在于,类的方法必须有一个额外的参数,而且必须放在第一个参数的位置,我们在调用的时候,不需要给这个参数赋值,由python自动给他赋值,赋的就是对象本身的引用,相当于this,这个名字一般约定俗成为self,但是写其他的名字也一样

class Ultraman:
    name = '奥特曼'
    def shoot(self,m):   # m 不是怪兽,而是self
        print('ultraman is shooting %s'%(m['name']))
        
dj = Ultraman()
dj.shoot(jsl)        

在java中,方法的执行必须是sb.doSth

class A{
   void f(){}
}
A a  = new A();
a.f();
A.getClass().getMethod('f').invoke(a)

python中也可以用类名方法名类似的方式去调用,不建议这样使用,因为看起来不太面向对象

Ultraman.shoot(dj,jsl) 

类属性

class Ultraman:
    name = '奥特曼'   # 并不是对象的属性,而是类属性
    def shoot(self,m):   # m 不是怪兽,而是self
    	# NameError: name 'name' is not defined
        print('%s is shooting %s'%(name ,m['name']))


dj = Ultraman()
dj.name = '迪迦'
dj.shoot(jsl)

类里面直接定义的变量,是类变量

类变量可以用类名.变量名来访问,也可以用对象.变量名来访问

class A{
	static int i;
}
A a = new A();
System.println(a.i);  //只不过这样写不好
System.println(A.i);

成员变量

外部创建
class Ultraman:
    name = '奥特曼'   # 并不是对象的属性,而是类属性
    def shoot(self,m):   # m 不是怪兽,而是self
        print('%s is shooting %s'%(self.name ,m['name']))
        
dj = Ultraman()
dj.shoot(jsl)
# 因为没有给dj这个对象去创建自由的属性name,所以self.name实际是类变量name
dj.name = '迪迦'  
# 其实是用外部创建的方式给Ultraman类创建了一个成员变量

在方法内部赋值

class Ultraman:
	def init(self,name):
		self.name = name
		
    def shoot(self,m):   # m 不是怪兽,而是self
        print('%s is shooting %s'%(self.name ,m['name']))
        
dj = Ultraman()
dj.init('迪迦')
dj.shoot(jsl)

因为成员变量是在方法中创建的,如果在init 方法调用之前访问,就会报错

希望有一个方法能够在对象创建的时候就把成员变量创建好,这个方法的作用很像构造函数

特殊方法

python为了解决一些特殊问题,定义了一些特殊方法(魔术方法)

这些方法都是以__开头,__结尾,开头结尾都是两个下划线中间没有空格

特殊方法不需要调用,也不应该去自己调用,这些特殊的方法会在特定的时间去自动调用

__init__

相当于构造函数,创建对象的时候执行,在造对象的时候要注意方法的参数

class Ultraman:
	def __init__(self,name):
		self.name = name
		
    def shoot(self,m):   # m 不是怪兽,而是self
        print('%s is shooting %s'%(self.name ,m['name']))

之前

d = Dog() 实际上是调用一个默认的 __init__(self)方法

写了以后,就没有默认的,所以必须匹配参数

class Ultraman:
    def __init__(self,name):
        self.name = name
        self.gender = '男'

dj = Ultraman('迪迦')

实例方法

默认情况下,写在类里面的方法都是实例方法,最少要有一个self参数,用于绑定此方法的执行对象,调用一般是sb.doSth(参数),也可以Class.dosth(sb,参数)

类方法

一般在python中很少用到类方法和静态方法,除了一些特殊的设计模式

class Ultraman:
    def __init__(self,name):
        self.name = name
    
    @classmethod
    def shoot(cls):
        print(cls)

当我们给方法加上@classmethod的时候,这个方法的第一个参数就是他的类,起名为cls

调用的时候,一般建议用类名.方法名调用,也可以用对象.方法名调用(不建议,容易有误解)

    @classmethod
    def shoot(cls):
        print(self.gender) # 类方法不可以调用实例对象

静态方法

静态方法,就是函数,区别就是命名空间在该类中,而不是在全局空间

静态方法中,没有self,也没有cls,所以静态方法中不可以去访问任何的类属性和类方法,成员属性和方法

class Ultraman:
    
    name = '奥特曼'
    def __init__(self,name):
        self.name = name
    
    @staticmethod
    def shoot(m):
        print(m)   # 这就是一个普通的函数方法,只不过命名空间在类中
#         print(self.name)
#        print(cls.name)

内置方法和属性

 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__init_subclass__',
 '__le__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
__str___()

返回对象的描述信息,相当于java对象中的toString()

class Ultraman:
    def __init__(self,name):
        self.name = name
        
    def __str__(self):
        return '%s奥特曼'%(self.name)
    
    def
      
dj = Ultraman('迪迦')    
print(dj)
__repr__

是在repr()方法后执行

str() 获得对象的字符串表现形式,一般得到一个好看的打印效果

__repr___是在调用repr() 方法后自动执行的,一般除了表现出数据内容,还会表现出数据类型

class Ultraman:
    def __init__(self,name):
        self.name = name
        
    def __str__(self):
        return '%s奥特曼'%(self.name)
    
    def __repr__(self):
    	return 'Ultraman:%s'%(str(self))
      
dj = Ultraman('迪迦')    
print(dj)
__del__

当对象被删除的时候,垃圾收集的时候执行的方法,类似于java中的finalize()方法或者c++中的析构函数

class Ultraman:
    def __init__(self,name):
        self.name = name
    def __del__(self):
        print(self.name,'del')
        
dj = Ultraman('迪迦')
del dj        
__gt__

会在对象做大于比较的时候调用,返回值将会作为比较的结果

class Ultraman:
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
    def __gt__(self, other):
        return self.weight > other.weight
    
dj = Ultraman('迪迦',10000)
jack = Ultraman('杰克',9000)
print(dj > jack)
__bool__

用于当bool() 方法转换对象时候执行

class Ultraman:
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
    
    def __bool__(self):
        return self.weight > 9500

dj = Ultraman('迪迦',10000)
jack = Ultraman('杰克',9000)
很多类似的运算符重载
class Ultraman:
    def __init__(self,name,weight):
        self.name = name
        self.weight = weight
    
    def __add__(self,other):
        return self.weight + other.weight

dj = Ultraman('迪迦',10000)
jack = Ultraman('杰克',9000)

print(dj + jack)

封装

面向对象三大特性:封装、继承和多态

面向对象的第一步,就是将属性和方法封装到一个抽象的类里面

外界使用类来创建对象,然后通过对象来访问属性和方法

对象的实现细节全部被封装在了类的内部

import datetime
import random
class Account:
    '''
    银行账户
    '''
    def __init__(self,account_id,password,name,personId,balance):
        self.account_id = account_id
        self.password = password
        self.name = name
        self.personId = personId
        self.balance = balance
        self.op_history = {}

#     def __init__(self):
#         self.account_id = 10001
#         self.password = '888888'
#         self.name = 'guest'
#         self.personId = ''
#         self.balance = 0
#         op_history = {}
    
    def deposit(self, amount):
        '''
        存钱
        :param amount
        :return:
        '''
        self.balance += amount
        rand = random.randint(1,1000)
        key = str(datetime.datetime.now())+'-'+str(rand)
        self.op_history[key] = '存钱%d'%(amount)
    
    def withdraw(self, amount):
        if amount > self.balance:
            print('存款余额不足')
        else:
            self.balance -= amount
            rand = random.randint(1,1000)
            key = str(datetime.datetime.now())+'-'+str(rand)
            self.op_history[key] = '取钱%d'%(amount)
    
    def __str__(self):
        return '%d   %s   %d'%(self.account_id,self.name,self.balance)
    
    def list_op_history(self):
        for k in self.op_history:
            print(k,self.op_history[k])
            
a1 = Account(10002,'123456','谷爱凌','US122321',100000)
a1.deposit(5000)
a1.withdraw(80000)

print(a1)
a1.list_op_history()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值