⾯向对象和⾯向过程,是两种编程思想
编程思想:是指对待同⼀个问题,解决问题的套路⽅式
⾯向过程: 注重的过程,实现的细节.亲⼒亲为
函数
⾯向对象: 关注的是结果, 偷懒.
封装, 继承 和多态(三⼤技术)
类和对象,是⾯向对象中⾮常重要的两个概念
类:
类是泛指的,指代多个, 是由对的抽象来的
在代码中, 是通过关键字 class 定义的
对象:
对象是特指的,指代⼀个,是具体存在的
在代码中, 对象是由类创建的
类的组成:
类名
属性: 特性, 变量
⽅法: ⾏为, 函数
类名的定义随后的代码,使⽤狗类进⾏演示说明
类名: Dog(狗类)
属性:
姓名 name
年龄 age
....
⽅法:
吃 eat()
玩 play()
.....
类名的定义 class 类名:
# 在python中,定义类使用关键字 class , 语法如下
"""
# object 是所有的类基类,即最初始的类
# 类名: 遵循大驼峰的命名规范
class 类名(object):
类中的代码
"""
# 定义方式一, 推荐
class Dog(object):#定义一个名为狗的类
pass
# 定义方式二
class Dog1(): # 括号中的内容可以不写
pass
# 定义方式三
class Dog2: # 括号也可以不写
pass
创建对象
创建对象 变量 = 类名()
定义类的方法 def 方法名(self):
对象调用类中的方法 对象.方法名()
class Dog(object):
def play(self): #定义play()方法
print('小狗快乐的拆家中......')
dog = Dog() # 创建一个对象 dog
print(id(dog))
dog1 = Dog() # 创建一个对象 dog1
print(id(dog1))
dog.play()#dog对象调用类中的play()方法
dog1.play()
类外部操作属性1985369080256
1985369081072
小狗快乐的拆家中......
小狗快乐的拆家中......
类外给对象添加属性 对象.属性名 = 属性值
类外获取对象的属性值 对象.属性名
类外修改属性值 和添加一样,存在就是修改,不存在,就是添加
class Dog(object):
def play(self):
print('小狗快乐的拆家中.....')
dog = Dog()
dog.name = '大黄' # 给dog对象添加name属性,属性值是 大黄
dog.age = 2 # 给dog对象添加age属性,属性值是 2
print(dog.name)#输出dog对象的name属性值
print(dog.age)
dog.age = 3 # age 属性已经存在,所以是修改属性值
print(dog.age)
dog1 = Dog() # 新创建一个对象 dog1
dog1.name = '小白'#每个对象,都会保存自己的属性值,不同对象的属性值之间没有关联
print(dog1.name)
类内部操作属性大黄
2
3
小白
类内部操作属性: self.属性名
self是什么?
self 作为类中方法的第一个形参,在通过对象调用方法的时候,不需要手动的传递实参
值,是python解释器,自动将调用该方法的对象传递给self, 所以self这个形参代表的是对象
class Dog(object):
def play(self):
print(f'self: {id(self)}')
print(f'小狗 {self.name} 在快乐的拆家中.....')
dog = Dog()
dog.name = '大黄' #前提外部一定要添加了属性和属性值
print(f"dog : {id(dog)}")
dog.play()
dog1 = Dog()
dog1.name = '小白'
print(f"dog1: {id(dog1)}")
dog1.play()
魔法方法__init__方法[掌握]大黄
2
3
小白
调用时机:在创建对象后,会立即调用
作用:给对象添加初始属性,给对象属性添加初始值(构造函数)
注意点:有了self之外的形参,在创建的对象时候,需要给额外的形参传递实参值
不带参数的init方法
class Dog(object):
def __init__(self): # self 是对象 #在创建对象后,会立即调用
print('我是__init__方法,我被调用了')
self.name = '小狗' #默认值,所有的对象的这个属性值都是相同的!
Dog() #不需要创建对象,也会被调用的!#创建第一次
dog = Dog() #创建第二次,没有传递参数
print(dog.name)
dog1 = Dog()
print(dog1.name) #创建第三次
我是__init__方法,我被调用了
我是__init__方法,我被调用了
小狗
我是__init__方法,我被调用了
小狗
带参数的init方法
class Dog(object):
def __init__(self, name):
self.name = name
def play(self):
print(f"小狗{self.name}快乐的拆家中...") #self.name=dog.name
# 创建对象 类名(实参值)
dog = Dog('大黄')#创建类名为Dog的对象传递实参值"大黄"给类的初始方法init
print(dog.name)
dog.play()
dog1 = Dog('小白')
print(dog1.name)
dog1.play()
魔法方法__str__方法 [掌握]大黄
小狗大黄快乐的拆家中...
小白
小狗小白快乐的拆家中...
调用时机:
1.打印(对象)会自动调用__str__方法,打印输出是返回值
注意点:
方法必须返回一个字符串,只有self一个参数
没有 __str__方法打印对象
class Dog(object):
def __init__(self, name, age):
self.name = name
self.age = age
# def __str__(self):
# print('我是__str__, 我被调用了...')
# return f"小狗的名字是{self.name}, 年龄是{self.age}"# 必须返回一个字符串,否则会报错
dog = Dog('大黄', 2)
print(dog) # 没有定义 __str__ 方法,print(对象) 默认输出对象的引用地址
<__main__.Dog object at 0x0000023B978A01C0>
有 __str__方法打印对象
class Dog(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
print('我是__str__, 我被调用了...')
return f"小狗的名字是{self.name}, 年龄是{self.age}"# 必须返回一个字符串,否则会报错
dog = Dog('大黄', 2)
print(dog) # 没有定义 __str__ 方法,print(对象) 默认输出对象的引用地址
魔法方法__del__方法[理解]我是__str__, 我被调用了...
小狗的名字是大黄, 年龄是2
析构函数
调⽤时机:
对象在内存中被销毁删除的时候(引⽤计数为 0)会⾃动调⽤ __del__ ⽅法
1. 程序代码运⾏结束,在程序运⾏过程中,创建的所有对象和变量都会被删除销毁
2. 使⽤ `del 变量` , 将这个对象的引⽤计数变为会⾃动调⽤ __del__ ⽅法
应⽤场景:
对象被删除销毁的时候,要书写的代码可以写在`__del__`中.⼀般很少使⽤
class Dog(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"小狗的名字是{self.name}, 年龄是{self.age}"
def __del__(self):
print(f'我是__del__ 方法,我被调用了, {self.name}被销毁了.......')
dog1 = Dog('小白', 1)#程序结束后会调用__del__方法
dog = Dog('大黄', 2)
print(dog.name)
del dog #删除对象的引用
print(dog.name)#打印不出来会报错
查看对象的引用计数[理解]大黄
我是__del__ 方法,我被调用了, 大黄被销毁了.......
我是__del__ 方法,我被调用了, 小白被销毁了.......
NameError: name 'dog' is not defined
引⽤计数: 是 python 内存管理的⼀种机制, 是指⼀块内存,有多少个变量在引⽤,
1. 当⼀个变量,引⽤⼀块内存的时候,引⽤计数加 1
2. 当删除⼀个变量,或者这个变量不再引⽤这块内存.引⽤计数减 1
3. 当内存的引⽤计数变为 0 的时候,这块内存被删除,内存中的数据被销毁
my_list = [1, 2] # 1
my_list1 = my_list # 2
del my_list # 1
del my_list1 # 0
import sys
class Dog(object):
pass
dog = Dog() # 1
print(sys.getrefcount(dog)) # 显示的时候,会比实际的多一个, sys.getrefcount(dog)还会引用一次
dog1 = dog # 2
print(sys.getrefcount(dog)) # 显示的时候,会比实际的多一个,
del dog # 1
print(sys.getrefcount(dog1)) # 显示的时候,会比实际的多一个,
魔法方法__repr__方法[理解]2
3
2
class Dog(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'{self.name}, {self.age}'
# def __repr__(self): #repr 方法和 str 方法,非常类似,也是必须返回一个字符串
# return f"{self.name}"
my_list1 = [Dog('大黄', 2), Dog('小白', 4), Dog('小花', 6)] # 将三个Dog类的对象添加到列表中
print(my_list1)
dog = Dog('大黄', 2)
print(dog) # __str_
[<__main__.Dog object at 0x000001C5AB461FD0>, <__main__.Dog object at 0x000001C5AB461F10>, <__main__.Dog object at 0x000001C5AB461B20>]
大黄, 2
class Dog(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'{self.name}, {self.age}'
def __repr__(self): #repr 方法和 str 方法,非常类似,也是必须返回一个字符串
return f"{self.name}"
my_list1 = [Dog('大黄', 2), Dog('小白', 4), Dog('小花', 6)] # 将三个Dog类的对象添加到列表中
print(my_list1)
dog = Dog('大黄', 2)
print(dog) # __str__
案例一[大黄, 小白, 小花]
大黄, 2
1.地瓜有自己的状态,默认是生的,可以进行烧烤
2.地瓜有自己的烧烤的总时间,有每次烧烤的时间累加的得出
3.地瓜烧烤时,需要提供本次烧烤时间
4.地瓜随着烧开时间变化而变化0~3生的,4~6半生不熟,6~8熟了
5输出地瓜信息,可以显示地瓜的状态和烧烤总时间
1.家具分不同类型,并占用不同的面积
2.输出家具信息是,显示家具的类型和家具的占用面积
3.房子有自己的地址和占用的面积
4.房子可以添加家具,如果房子剩余面积可以容纳家具,则提示家具添加成功,否则失败
5.输出房子信息是,可以显示房子的地址,占地面积,剩余面积
继承:描述的的类与类之间所属关系
称为:类B继承类A
特点:B类的对象可以使用A的属性和方法
优点:代码复用,相同的不用多写
名词:
类A:父类 基类
类B:子类 派生类继承分类:
单继承:如果一个类只有一个父类,成为单继承
多继承:一个类有多个父类
多层继承:A继承B,B继承C.A 和C就是多层继承关系
优点:子类可以使用所有继承链中的类中方法和属性
#继承基本语法
#class 类B(类A):
# pass
class Aniaml(object):#对于Animal类和object类来说.单继承
def play(self):
print("快乐的玩耍")
class Dog(Aniaml): #定义Dog继承animal类 Dog-->Animal-->boject这种继承关系成为多层继承
def bark(self):
print("旺旺")
class Taidi(Dog): #多层继承Taidi-->Dog-->Animal
pass
dog=Dog() #创建Dog类对象,调用父类的方法
dog.play() #B类的对象可以使⽤ A类的属性和⽅法
taidi=Taidi()
taidi.play() #继承了爷爷类Aniaml的方法
taidi.bark() #继承了父亲类Dog 的方法 子类可以使用所有继承链中的类中方法和属性
子类重写父类的同名方法快乐的玩耍
快乐的玩耍
旺旺
继承是可以调用父类的方法,如何继承后调用自己的方法?需要重写一个同名的方法,就会优先调用自己的方法
重写:子类定义父类名字相同的方法
为什么重写:父类的方法,不能满足子类对象的需求
重写后的特点:子类对象调用子类的方法,不用父类的方法,父类继续用父类大方法
#定义Dog类,书写bark方法,输出玩玩叫
#定义XTQ类,重写bark方法,输出嗷嗷叫
class Dog(object):
def bark(self):
print("汪汪")
class Taidi(Dog):
def bark(self):
print("嗷嗷叫")
dog=Dog()
dog.bark() #父类继续用父类大方法
taidi=Taidi()
taidi.bark()#子类对象调用子类的方法,不用父类的方法
子类调用父类的同名方法汪汪
嗷嗷叫
子类和父类有一样的方法,首先使用子类的方法,如何调用父类的方法?子类创建新方法,调用父类方法
在子类定义一个新方法,调用新方法
新方法下的内容:
#方法一:父类名.方法名(self)
#方法二 suoer(当前的类,self).方法名(参数),会调用当类的父类的方法 #只会调用一次
#方法三是方法二的简写,super().方法名(参数
#定义Dog类,书写bark方法,输出玩玩叫
#定义XTQ类,重写bark方法,输出嗷嗷叫
class Dog(object):
def bark(self):
print("汪汪")
class Taidi(Dog):
def bark(self):
print("嗷嗷叫")
def see_host(self):
print("看见主人了",end=" ")
#看见主人后要旺旺叫,不要嗷嗷叫
#self.bark()
#想要在子类中调用父类的同名方法
#方法一:父类名.方法名(self)
Dog.bark(self) #为什么有self,通过对象调用方法需要传递实参值,如果通过类名调用方法,py不会自动传传参,需要手动给self形参传递实参值
#方法二 suoer(当前的类,self).方法名(参数),会调用当类的父类的方法 #只会调用一次
super(Taidi,self).bark()
#方法三是方法二的简写,super().方法名(参数)
super().bark()
taidi=Taidi()
taidi.see_host()
继承中init方法看见主人了 汪汪
汪汪
汪汪
如何继承父类的init方法?在子类init方法中调用父类的init方法
如果子类重写了父类的init方法.在子类需要调用父类的init方法,给对象添加父类的继承属性
class Dog(object):
def __init__(self,name):
self.age=0
self.name=name
def __str__(self):
return (f"名字为{self.name}年龄为{self.age}")
class Taidi(Dog):
# def __init__(self,color): #子类重写的_init_方法,默认不在调用父类的方法,默认属性用不到了,需要手动的调用父类inii方法
# self.color=color
def __init__(self,name,color):#需要重写init方法 注意:子类init方法的形参,一般先写父类的形参
super().__init__(name) #需要手动的调用父类inii方法 表示会执行 self.age=0 self.name=name
self.color=color
def __str__(self):#需要重写color
return (f"名字为:{self.name}年龄为:{self.age},毛色为:{self.color}")
pass
taidi=Taidi("小黑","黑色") #继承中init方法
print(taidi)
名字为:小黑年龄为:0,毛色为:黑色
多继承
一个子类可以继承多个父类
# 1. 定义Dog类, 定义bark方法,和 eat方法
class Dog(object):
def bark(self):
print('汪汪汪叫.....')
def eat(self):
print('啃骨头.....')
# 2. 定义God类, 定义 play方法和eat方法
class God(object):
def play(self):
print('在云中飘一会....')
def eat(self):
print('吃蟠桃仙丹....')
# 3. 定义XTQ类, 继承Dog类和God类
# class XTQ(Dog, God): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
class XTQ(God, Dog): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
pass
# 4. 创建XTQ类对象
xtq = XTQ()
xtq.bark() # 调用 Dog父类中的方法
xtq.play() # 调用 God父类中的方法
xtq.eat() # 两个父类都存在eat方法,子类对象调用的是 第一个父类中的方法
多继承调用指定父类的方法汪汪汪叫.....
在云中飘一会....
吃蟠桃仙丹....
# 1. 定义Dog类, 定义bark方法,和 eat方法
class Dog(object):
def bark(self):
print('汪汪汪叫.....')
def eat(self):
print('啃骨头.....')
# 2. 定义God类, 定义 play方法和eat方法
class God(object):
def play(self):
print('在云中飘一会....')
def eat(self):
print('吃蟠桃仙丹....')
# 3. 定义XTQ类, 继承Dog类和God类
# class XTQ(Dog, God): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
class XTQ(God, Dog): # XTQ 类有两个父类,这个继承关系称为多继承,XTQ类对象,可以调用两个父类中的属性和方法
def eat(self):
print('子类重写eat方法,调用子类自己的方法')
# 调用指定父类中的方法
# 方法一 类名.方法名(self, 参数)
# Dog.eat(self)
# God.eat(self)
# 方法二 super(类A, self).方法名(参数) 类A的父类(继承顺序链的下一个类)中的方法
# super(XTQ, self).eat() # God 类中的方法
super(God, self).eat() # 调用的Dog类中的方法
# super(Dog, self).eat() # 调用的object类中的方法,注意: object类中没有eat方法,代码报错
# 4. 创建XTQ类对象
xtq = XTQ()
xtq.bark() # 调用 Dog父类中的方法
xtq.play() # 调用 God父类中的方法
xtq.eat() # 两个父类都存在eat方法,子类对象调用的是 第一个父类中的方法
# 类名.__mro__ 可以当前类的继承顺序链,也叫做方法的调用顺序
# print(XTQ.__mro__)
封装汪汪汪叫.....
在云中飘一会....
子类重写eat方法,调用子类自己的方法
啃骨头.....
私有权限封装的意义:
1.将属性和方法放在一起作为一个整体,通过实例化对象来处理
2.隐藏内部的实现细节,只需要和对象及其属性和方法交互就可以
3.对象的属性和方法增加访问权限
私有属性
1.类的私有属性和私有方法,都不能通过对象直接访问,但可以在本类内部使用
2.类的私有属性和私有方法都不能被子类继承,子类无法访问
3.私有属性私有方法,往往处理类内部的事情,不通过对象处理,起到安全作用
私有权限:
定义:在属性名和方法名前面加上两个下划线__.就变成私有
1.不能在类外部访问
2.不能被子类继承
"""
私有属性,只需要在原属性名前加上两个下划线,即可
目的: 保证数据的相对安全,
想要访问和使用私有属性: 定义一个公有的方法,通过这个方法使用
"""
# 案例需求:
# 定义people类,定义属性ICBC_money,钱不能随便修改,必须是合法的终端才可以操作
class Penpel(object):
def __init__(self):
# self.ICBC_money=0 #公有属性,外部可以直接修改
# python中的私有本事是创建属性的名字,在创建对象的时候,会自动修改属性名
# 在属性名的前边加上_类名前缀
self.__ICBC_money = 0 # 私有属性,外部不可以修改
# 定义公有的方法,提供接口,修改余额
def get_money(self):
return self.__ICBC_money
def set_money(self, money):
num = input('输入金额:')
self.__ICBC_money += int(num)
# self.__ICBC_money += money
xw = Penpel()
# xw.ICBC_money=1000 #外部可以直接该金额,肯定不合理
# print(xw.__ICBC_money) 外部不可以访问
print(xw._Penpel__ICBC_money) # 运用原理去访问
# 实例对象.__dict__ 可以查看对象具有的属性信息,类型是字典,字典的key是属性名, 字典的value是属性值
print('赋值之前:', xw.__dict__)
xw.__ICBC_money = 1000 # 不是修改私有属性,是重新添加一个公有属性
print('赋值之后:', xw.__dict__)
print(xw.__ICBC_money)
print('=' * 20)
print(xw.get_money()) # 0
print(xw.get_money()) # 1000
xw.set_money(-500)
print(xw.get_money()) # 500
私有方法0
赋值之前: {'_Penpel__ICBC_money': 0}
赋值之后: {'_Penpel__ICBC_money': 0, '__ICBC_money': 1000}
1000
====================
0
0
输入金额:20
20
"""
私有方法: 在方法的前边加上两个__ ,就为私有方法
私有方法,不能在类外部访问
作用: 一般作为类内部的方法使用,不让在外部直接调用, 保证业务逻辑不被破坏
"""
class Dog(object):
def born(self):
"""生小狗的方法, 生一个小狗,休息30天"""
print('生了一只小狗...')
self.__sleep() #用公有方法调用私有方法,私有方法加上__
def __sleep(self):
print('休息30天')
dog = Dog()
# dog.__sleep() #外部不可以调用
dog.born()
类属性生了一只小狗...
休息30天
"""
对象(实例对象): 通过class定义的类创建的, 即通过类实例化来的, 又称为实例, 实例对象
实例对象定义的属性称为是 实例属性. 通过实例对象(self) 定义的属性都是实例属性
实例属性: 每个实例对象中都存在一份,并且值可能是不一样的
类(类对象): 通过class定义的,又称为 类对象, 是python解释器在创建类的时候自动创建的
作用: 1. 通过类对象,去定义实例对象 2. 类对象可以保存一些属性信息,称为类属性
类属性的定义: 在类内部,方法外部定义的变量就是类属性
类属性,字内存中只有一份
如何确定一个属性是该定义为实例属性还是类属性?
先假设这个属性为实例属性,查看这个属性值对于不同的实例对象, 属性值是否都一样,并且需要同时变化.
如果是, 则可以定义为类属性
如果不是,则可以定义为实例属性
"""
class Dog(object):
class_name = '狗类' # 定义类属性, 类名
def __init__(self, name, age): # 定义的都是实例属性
self.name = name
self.age = age
dog = Dog('大黄', 2)
# print(dog.__dict__) # 打印dog对象具有的属性
# print(Dog.__dict__) # 类名.__dict__ 查看类对象具有的属性 类也是一个对象
print(Dog.class_name) # 访问类属性 类名.类属性
Dog.class_name = 'Dog类'# 修改类属性 类名.类属性 = 属性值
print(Dog.class_name)
# 补充, 注意: 如果不存在和实例属性名相同的类属性.则可以使用实例对象访问类属性的值
# 如果存在重名,则使用实例属性访问的一定是实例属性,不是类属性
print(dog.class_name)
类方法狗类
Dog类
Dog类
"""
实例方法: 类中默认定义的方法,就是实例方法, 第一个参数为self,表示实例对象
类方法: 使用 @classmethod 装饰的方法,称为类方法, 第一个参数是cls,代表的是类对象自己
什么情况定义为实例方法,什么情况定义为类方法?
1. 如果在方法中使用了实例属性, 那么该方法必须定义为实例方法
2. 前提:不需要使用实例属性. 需要使用类属性,可以将这个方法定义为类方法
"""
class Dog(object):
class_name = '狗类'
def __init__(self, name, age):
self.name = name
self.age = age
def play(self): # 实例方法
print(f"小狗{self.name} 在快乐的玩耍....")
# def get_class_name(self): # 是实例方法, 因为没有使用实例属性,所以可以定义为类方法
# return Dog.class_name
@classmethod
def get_class_name(cls): # cls 是类方法的默认形参,在调用的时候,不需要手动传递,python解释器会自动传递
return cls.class_name
dog = Dog('大黄', 2)
dog.play()
print(dog.get_class_name()) # 对象.类方法()
# 类名.类方法()
print(Dog.get_class_name())
静态方法小狗大黄 在快乐的玩耍....
狗类
狗类
"""
实例方法: 类中默认定义的方法,就是实例方法, 第一个参数为self,表示实例对象
类方法: 使用 @classmethod 装饰的方法,称为类方法, 第一个参数是cls,代表的是类对象自己
静态方法: 使用 @staticmethod 装饰的方法,称为静态方法, 对参数没有特殊要求,可以有,可以没有
什么情况定义为实例方法,什么情况定义为类方法, 什么情况下静态方法?
1. 如果在方法中使用了实例属性, 那么该方法必须定义为实例方法
2. 前提:不需要使用实例属性. 需要使用类属性,可以将这个方法定义为类方法
3. 前提:不需要使用实例属性,同时也不需要使用类属性, 此时可以将这个方法定义为静态方法
"""
class Dog(object):
class_name = '狗类'
def __init__(self, name, age):
self.name = name
self.age = age
def play(self): # 实例方法
print(f"小狗{self.name} 在快乐的玩耍....")
@staticmethod # 定义静态方法
def show_info():
print('这是一个Dog类')
dog = Dog('大黄', 2)
dog.play()
dog.show_info()# 对象.方法名() 对象可调用静态方法
Dog.show_info()# 类名.方法名() 类可以调用静态方法
多态小狗大黄 在快乐的玩耍....
这是一个Dog类
这是一个Dog类
"""
在需要使用父类对象的地方,也可以传入子类对象,得到不同的结果 ---- 多态
实现步骤:
1. 子类继承父类
2. 子类重写父类中的同名方法
3. 定义一个共同的方法, 参数为父类对象.在方法中调用子类和父类同名的方法
"""
# 1. 定义DOg类
class Dog(object):
def __init__(self, name):
self.name = name
def play(self):
print(f'小狗{self.name} 在玩耍.......')
# 2. 定义哮天犬类,继承Dog类
class XTQ(Dog):
# 3. 重写 play方法
def play(self):
print(f'{self.name} 在天上追云彩.....')
# 4. 定义一个共同的方法,
def play_with_dog(obj_dog):
obj_dog.play()
# 创建Dog类对象@
dog = Dog('大黄')
play_with_dog(dog)
# 创建一个XTQ类的对象
xtq = XTQ('小黑')
play_with_dog(xtq)
总结小狗大黄 在玩耍.......
小黑 在天上追云彩.....
类外部定义属性:每个实例对象都定义有自己的属性
类内部操作属性:定义一个模板,实例对象都用内部定义的属性,相同的属性
__init__方法:定义一个模板,实例对象都用内部定义的属性,可以自己传参数
__str__方法:打印对象,打印属性
__del__方法:输出对象在内存引用被删除的
查看引用技术
__repr__方法:打印对象
继承:子类可以使用父类的方法
子类重写父类的同名方法:继承子类会使用父类的方法,只想使用自己同名的方法,重写此方法,首先调用自己的方法
子类调用分类的同名方法:子类父类写了同名的方法,子类用子类的,但还是需要用父类的,子类定义方法调用父类同名方法
继承中init方法:子类的init方法调用父类init方法
多继承:一个子类继承多个父类,父类有相同的方法,首先调用第一个父类的方法
多继承调用父类的方法,子类定义
封装:可以有私有属性,外界不能查看
私有权限:可以定义公有方法查看私有属性
私有方法:可以定义共有方法查看私有方法
类属性:用不到实例属性
类方法:用了类属性使用类方法
静态方法:用不到类属性使用静态方法
多态:在需要使用父类对象的地方,也可以传入子类对象,得到不同的结果,定义一个共同的方法可以使用父类方法,可以使用子类方



