一、类
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