初识类和对象
'''
面向对象:
对象--》具体的事物 xxx的手机
现实中的事物--》转成电脑中的程序
世界万物皆对象
把对象装进冰箱要几步?
--面向过程
1.打开冰箱
2.装大象
3.关冰箱
--面向对象
把冰箱看成对象
把大象看成对象
将冰箱和大象的关系通过代码结合起来
面向对象:
类
对象
属性
方法
对象:
小红的手机
小芳的手机
赵飞的手机
...
对象的集合---》提取共同特征---》封装到一个类中
特征: 动作:
类别: 手机类-- 品牌 大小 价格 颜色 打电话,发短信,上网,打游戏
学生类-- 姓名 年龄 性别 身高 血型 刷抖音,写作业,看书
'''
#定义一个类
#所有的类名要求首字母大写,多个单词则使用驼峰式命名
#python中所有类默认继承Object
'''
格式:
class 类名[(父类)]:
属性: 特征
方法: 动作
'''
class Phone(object):#类是一个模型,通过模型能印出一个个月饼
brand='huawei'
#属性
#brand=''
#方法
print(Phone)
#使用类来创建对象
hs=Phone()
print(hs)
print(hs.brand)
xiaohong=Phone()
print(xiaohong)
print(xiaohong.brand)
'''
<class '__main__.Phone'>
<__main__.Phone object at 0x000002370A2B3CC0>
huawei
<__main__.Phone object at 0x000002370A2B72B0>
huawei
'''
hs.brand='iphone'
print(hs.brand)#iphone
print(xiaohong.brand)#huawei
定义类和属性(类属性&对象属性)
#定义类和属性
class Student:
#类属性(类变量)----存在模型里
name='小伟'
age=2
#使用类来创建对象
xiaowei = Student()
#类属性(存于类的内存里)
print(xiaowei.name)#小伟
print(xiaowei.age)#2
#对象属性
xiaowei.age=18#动态创建在对象里(存于对象的内存),到这里对象才创建自己的属性,在这之前age属性是类的
print(xiaowei.age)#18
#python中调用属性的顺序是:先调用对象属性,如果没有再找类属性,如果都没有则保错
#先找对象属性(自己的空间里),找不到再去找类属性(类的空间里)
ff=Student()
print(ff.name)#小伟 此时它没有自己的名字,调用的是类的
ff.name='ff'#动态创建对象属性
print(ff.name)#ff
#调用类属性
Student.name='leilei'
print(Student.name)#leilei
#java中成员变量--静态(类变量)&非静态
# java中类变量可以直接通过类名调用也可以通过创建一个对象调用,但实际上它还是去调用类的
类中的方法
普通方法(self)
#类中的方法:动作
#种类:普通方法 类方法 静态方法 魔术方法
'''
普通方法格式:
def 方法名:(self[,参数,参数]):
pass
'''
class Phone:
brand='xiaomi'
price='4999'
type='mate 80'
#Phone类里面方法:call
def call(self):#self代表调用这个方法的对象(注意不是类)
print('self------->',self)
print('正在打电话...')
phone1=Phone()
print('------1----',phone1)
phone1.call()
'''
------1---- <__main__.Phone object at 0x000001443FF673C8>
self-------> <__main__.Phone object at 0x000001443FF673C8>
正在打电话...
'''
#可以发现这个self就是phone1对象
print('*'*30)
phone2=Phone()
print('----2',phone2)
phone2.call()
'''
******************************
----2 <__main__.Phone object at 0x00000232BA9274E0>
self-------> <__main__.Phone object at 0x00000232BA9274E0>
正在打电话...
'''
# class Phone:
# brand='xiaomi'
# price='4999'
# type='mate 80'
#
# #Phone类里面方法:call
# def call(self):#self代表调用这个方法的对象(注意不是类)
# print('当前对象-->self:',self)
# print('留言:',self.note)#调用对象的属性
#
# phone1=Phone()
# phone1.note='我是phone1的note'#动态创建phone1对象的属性
# phone1.call()
#
# #可以发现这个self就是phone1对象
#
# print('*'*30)
# phone2=Phone()
# phone2.note='我是phone2的note'
# phone2.call()
'''
当前对象-->self: <__main__.Phone object at 0x000002CAC44174A8>
留言: 我是phone1的note
******************************
当前对象-->self: <__main__.Phone object at 0x000002CAC4417518>
留言: 我是phone2的note
'''
#虽然我们在类中的call方法利用self调用了当前对象的属性note,,但是不是所有对象都有这个属性啊,比如下面
class TPhone:
brand='xiaomi'
price='4999'
type='mate 80'
# note='111'
#Phone类里面方法:call
def call(self):#self代表调用这个方法的对象(注意不是类)
print('当前对象-->self:',self)
print('留言:',self.note)#调用对象的属性
phone1=TPhone()
phone1.note='我是phone1的note'#动态创建phone1对象的属性
phone1.call()
#可以发现这个self就是phone1对象
print('*'*30)
phone2=TPhone()
# phone2.note='我是phone2的note'
phone2.call()
#phone2对象没有note属性,而且类也没有这个属性。因此报错了
#如果类有这个属性则先去找对象的没有再去找类的
魔术方法__init__
class Phone:
brand='huawei'
#魔术方法之一:__名字__()
#魔术方法前后有__,没有调用魔术方法它也会执行,只要我创建一个对象,系统就会默认执行魔术方法
def __init__(self):#可以给每个对象统一动态创建对象属性
print('----init----')
self.price=4999#对象属性初始化,所有对象都有这个属性,且初始值为4999
def call(self):
print('------->call')
print('价格(对象属性):',self.price)#不能保证每个self中都存在price
print('品牌(类属性):',self.brand)#先找对象自身,对象没有时,再找类
p=Phone()
p.price=1000#动态创建对象属性的方式1,也可以再魔术方法里面统一给所有对象创建
p.call()
p1=Phone()
p1.call()
# print(Phone.price)#报错,类里没有这个属性
print(Phone.brand)
'''
----init----
------->call
价格(对象属性): 1000
品牌(类属性): huawei
----init----
------->call
价格(对象属性): 4999
品牌(类属性): huawei
huawei
'''
'''
p=Phone()步骤:
1.找有没有一块空间x是Phone类的
2.利用Phone类向内存申请一块空间y
3.去Phone类找有没有__init__,如果没有则将内存y赋值给对象名p
4.如果有__init__则先进入这个方法再将内存地址赋值给p对象
'''
#例子
class Person:
# name='张三'
#该方法会在创建对象时调用
def __init__(self,name,age):#存放对象的共性----类似于构造器。用于初始化对象属性
self.name=name
self.age=age
def eat(self,food):
print('{}正在吃{}!'.format(self.name,food))
def run(self):
print('{}今年{}岁了,正在跑步'.format(self.name,self.age))
p=Person('李四',13)
p.eat('红烧肉')
p.run()
p1=Person('wangwu',22)
p1.name='王五'
p1.eat('老谭')
'''
李四正在吃红烧肉!
李四今年13岁了,正在跑步
王五正在吃老谭!
'''
类方法
#类方法
'''
特点:
1.定义需要依赖装饰器@classmethod
2.类方法中参数不是一个对象,而是类
3.类方法中只可以使用类属性,不能使用对象属性,他是对象没有出现时候就加载了.没有创建对象就可以Dog.age/Dog.test()
4.类方法不能使用普通方法
类方法作用:
因为只能访问类属性和类方法,所以可以实现在
对象还没出现的动作
'''
class Dog:
age=13
def __init__(self,nickname):
self.nickname=nickname#使得每个创建该类的对象都能动态创建这个动态属性,因此无论是哪个对象都有这个属性
#普通方法,需要通过对象来调用
def run(self):#需要依赖于对象
print('{}在院子里跑来跑去'.format(self.nickname))
print(self.age)#对象可以使用类的属性
def eat(self):
print("吃饭")
self.run()#类中普通方法的调用,需要通过self去调用
@classmethod#类方法
def test(cls):
print(cls)
# print(cls.nickname) 类不能使用对象属性,这个类并没有这个属性
print(cls.age)
#不能调用run等普通方法
print(Dog.age)
print(Dog.test())
print("----------")
'''
13
<class '__main__.Dog'>
13
None
----------
'''
d=Dog('大黄') #由于__init__这个方法,每个创建的对象都有nickname属性
d.run()
d.test()#先找对象方法,找不到再调用类方法。先找对象属性,找不到再找类属性
'''
大黄在院子里跑来跑去
13
<class '__main__.Dog'>
13
'''
#补充类方法
class Person:
__age=18 ##__代表私有属性,只能在类内进行访问,因此必须提供setget方法在类内进行修改访问
def show(self):
print('--->',Person.age)
def update_age(self):
Person.__age=20#如果改为self,他只会改当前对象,不改类属性
print('普通方法修改私有属性')
@classmethod
def update_age2(cls):
cls.__age=23
print('类方法修改私有属性')
@classmethod
def show_age(cls):
print('修改后的年龄是:',cls.__age)
@classmethod
def test(cls):
print('--->类方法')
# Person.age=Person.age+1 #不能在类外访问私有属性
# print(Person.age)
#类方法不需要对象就可以调用
Person.test()
Person.update_age2()
Person.show_age()
# Person.update_age()报错--普通方法必须由对象调用
p=Person()
p.update_age()
p.show_age()
#
# p.show()
'''
--->类方法
类方法修改私有属性
修改后的年龄是: 23
普通方法修改私有属性
修改后的年龄是: 20
'''
静态方法
'''
静态方法:与类方法相似
1.需要装饰器@staticmethod
2.不需要参数self/cls
3.与类方法一样只能访问类的属性和方法,无法访问对象的属性或方法
4.加载时机同类方法
总结:
区别:
静态方法装饰器@staticmethod,没有参数
类方法装饰器@classmethod,参数是cls
都只能访问类的属性和方法
都可以通过类名调用访问
都可以在创建对象之前使用
普通方法:
没有装饰器
参数是self
普通方法永远依赖对象,因此每个普通方法都有一个self
只有创建了对象才可以调用普通方法,否则无法调用
'''
class Person:
__age=18#私有类属性
def __init__(self,name):
self.name=name#动态给每个对象创建name的对象属性
@classmethod
def update_age(cls):
cls.__age=20
print('--->类方法')
@classmethod
def show_age(cls):
print('修改后的年龄是:',cls.__age)
@staticmethod
def test():#静态方法,由于没有参数,只能通过类名调用类属性和方法
print('--------->静态方法')
# print(self.name)语法错误
print(Person.__age)
Person.update_age()
Person.show_age()
Person.test()
'''
--------->静态方法
18
--->类方法
修改后的年龄是: 20
'''