一、类
1、对同一类事物抽象的描述,抽象的概念。归类所有,只有一份,所有对象共享这一份类属性。
2、定义类的语法:
class 关键字——命名规则:大驼峰StudentInfo; (小驼峰studentInfo)
class 类名:
pass
3、属性: 理解为用于描述类名词 (名字, 年龄, 颜色, 身高,...)
4、方法: 也叫做函数, 理解为类能够实现的行为功能(吃饭, 睡觉, 打豆豆,...)
二、对象: 真实存在的,类的具体的一个实例
1、对象 : 也叫做实例
2、创建对象的过程:叫做类的实例化
3、属性:归对象所有,每个对象都有一份,对象之间的实例属性互不影响
获取对象的属性值:对象.属性
给属性赋值:对象.属性 = 新值
4、方法:对象.方法()
5、动态的给对象的属性赋值
类中没有定义该属性,则在对象中给哪个对象的属性动态赋值,只有该对象能使用此属性
6、self 自己,本身
谁调用谁就是self,self指的是当前调用的对象
三、创建对象
1、创建对象的过程:p1 = Person()
(1)开辟内存,存储对象
(2)自动调用了init方法
2、实例变量
初始化实例变量, 初始化对象的属性
实例变量:对象的变量 ——> 对象属性
实例变量归对象所有, 每个对象都有一份, 对象之间互不影响
self.变量名 ——> 表示实例变量(实例属性)
3、init
一般情况下会在init方法中初始化实例变量(对象的属性)
1 # 2. 公路和汽车类, 计算车在公路上行走完的时间 2 # 分析: 时间 = 路程 / 速度 3 # 路程: 公路的长度 ---> 长度(名词) 4 # 速度: 汽车的速度 ---> 速度(名词) 5 # 功能: 计算车在公路上行走完的时间 6 class Road: 7 def __init__(self, length, name): 8 self.name = name 9 self.length = length 10 11 def get_time(self, car_obj): # 形参:本质变量 car_obj 小汽车对象 12 t = self.length / car_obj.v 13 print("%s小汽车在%s公路上行驶完全程的时间是%.2f" % (car_obj.brand, self.name, t)) 14 15 class Car: 16 def __init__(self, v, brand): # 属性v, 代表速度 17 self.v = v 18 self.brand = brand # 汽车品牌 19 20 def get_time(self, road_obj): # 形参: 公路对象 21 t = road_obj.length / self.v 22 print("%s小汽车在%s公路上行驶完全程的时间是%.2f" % (self.brand, road_obj.name, t)) 23 24 25 road1 = Road(100, "康庄大道") 26 car1 = Car(300, "奥拓") 27 28 road1.get_time(car1) # 奥拓小汽车在康庄大道公路上行驶完全程的时间是0.33 29 car1.get_time(road1) # 奥拓小汽车在康庄大道公路上行驶完全程的时间是0.33
四、实例方法&类方法&静态方法
1、实例方法:
第一个参数,都是self,self 指的是当前调用的对象;
可以访问:
self.实例属性
类名.类属性
2、类方法:
第一个参数,都是cls,cls 指的是当前的类
可以访问:
类名.类属性;cls.类属性
默认不能访问实例属性
1 #语法规则: 2 3 class 类名: 4 5 @classmethod 6 def 类方法名(cls, 参数,...): 7 pass
(1)类方法可以由类调用,也可以由实例调用
(2)类方法中可以通过传递实例作为参数,从而访问到实例方法和实例属性
3、静态方法:
如果类中一个方法既不操作类, 也不操作实例, 那么定义为静态方法
没有默认的参数
1 #语法规则: 2 3 class 类名: 4 5 @staticmethod 6 def 静态方法名(): 7 pass
综上:
1、如果需要定义一个方法,操作实例——> 实例方法
2、如果需要定义一个方法,操作类——> 类方法
3、如果需要定义一个方法,既不操作实例也不操作类 ——> 静态方法
1 class Person: 2 country = "中国" 3 def __init__(self, name, age): 4 self.name = name 5 self.age = age 6 7 # 定义一个实例方法, self, 访问实例属性, 访问类属性 8 def show_info(self): 9 print("实例方法:show_info, {}, {}, {}".format(self.name, self.age, self.country)) 10 11 # 定义一个类方法, cls当前类, 可以访问类属性, 不能访问实例属性 12 @classmethod 13 def test(cls): 14 print("类方法:test--国籍:{}".format(cls.country)) # Person.country, 15 16 # 定义一个类方法, 传入一个实例作为参数, 函数体中即可操作该实例(属性,方法) 17 @classmethod 18 def test2(cls, p_obj): 19 print("类方法操作实例:test2--{}, {}".format(cls.country, p_obj.name)) 20 21 @staticmethod 22 def introduce(): 23 print("我是一个静态方法, 我既不操作类, 也不操作实例") 24 25 26 p1 = Person("xixi", 8) 27 p2 = Person("haha", 7) 28 29 p1.show_info() # 使用对象调用实例方法 30 Person.show_info(p2) # 不建议 31 32 """ 33 实例方法:show_info, xixi, 8, 中国 34 实例方法:show_info, haha, 7, 中国 35 """ 36 Person.test() # 可以用类调用类方法 37 p1.test() # 也可以用实例调用类方法 38 p2.test() 39 40 p1.test2(p1) # 类方法操作实例:test2--中国, xixi 41 Person.test2(p2) # 类方法操作实例:test2--中国, haha 42 43 Person.introduce() # 我是一个静态方法, 我既不操作类, 也不操作实例 44 p1.introduce() # 我是一个静态方法, 我既不操作类, 也不操作实例
五、抽象类
抽象类是一个特殊的类,这个类只能被继承,不能被实例化
python中使用抽象类是通过一个模块实现的
* 子类必须要实现父类中规定好的方法
为什么要有抽象类
类:对同一类事物抽象的描述
类是从一堆对象中抽取的相同的内容
抽象类是从一堆类中抽取的相同的内容
苹果类, 橘子类, 葡萄类,继承自水果类(抽象类)
抽象类,只能有抽象的方法,没有实现的功能
1 from abc import abstractmethod, ABCMeta 2 3 class Payment(metaclass=ABCMeta): # 抽象类需要继承自abc.ABCMeta 元 4 @abstractmethod 5 def pay(self): 6 pass 7 8 class WeChat(Payment): 9 def pay(self): 10 print("微信支付的功能") 11 12 class Bank(Payment): 13 def pay(self): 14 print("银联支付的功能") 15 16 # p = Payment() # TypeError: Can't instantiate abstract class Payment with abstract methods pay 17 18 b = Bank() 19 b.pay() # 银联支付的功能 20 21 w = WeChat() 22 w.pay() # 微信支付的功能
六、私有属性&私有方法
起到保护核心代码的作用,通过__dict__属性查看所有属性值(包括私有)
python中关于私有,是通过改名实现的,所以在类外访问私有,可以通过对象._类名__私有名实现,但是强烈不建议这么做
1、私有属性:
__属性名,只能在本类中使用
类外不能使用,但是可以通过公有方法, 修改或者获取私有属性的值
1 class Girl: 2 def __init__(self, name): 3 self.name = name 4 self.__age = 18 # 私有属性 5 6 def show_me(self): # 通过公有方法获取私有属性值 7 print("我的名字:{}, 我偷偷的告诉你我的年龄:{}".format(self.name, self.__age)) 8 9 def set_age(self, age): # 通过公有方法修改私有属性的值, 参数为修改后的值 10 self.__age = age 11 print("我偷偷告诉你一声,我的年龄改变了,现在是:{}".format(self.__age)) 12 13 14 g1 = Girl("xixi") 15 print(g1.name) 16 # print(g1.__age) # AttributeError: 'Girl' object has no attribute '__age' 17 18 g1.show_me() 19 20 # 可以在类中定义一个公有方法set_age, 用于更改私有属性__age的值; 21 g1.set_age(8) # 年龄更改为8
2、私有方法
__方法名,类中能够使用,类外不能使用
但是可以通过公有方法访问到类的私有方法
1 class Person: 2 def __init__(self, name): 3 self.name = name 4 self.__age = 18 5 6 # 实现了某个具体的功能, 7 def __secret(self): 8 print("秘密") 9 10 # 提供公有方法作为接口 11 def get_secret(self): 12 self.__secret() # 类中调用该方法 13 14 15 p1 = Person("xixi") 16 # p1.__secret() AttributeError: 'Person' object has no attribute '__secret' 17 18 p1.get_secret() # 秘密 19 20 print(p1.__dict__) # {'name': 'xixi', '_Person__age': 18} 21 # print(p1.__age) 22 print(p1._Person__age) # 18