一、类

  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