欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python类与对象--基础

程序员文章站 2022-06-17 08:13:41
## 类 - 具体事物的抽象和总结,是事物的共性,由属性和方法两个部分构成,比如一个Person类,有是身高、体重、肤色等属性,也有吃饭、睡觉、观察、等方法 ## 对象 - 具体的事物,单一、个体、特性,是一个类的具体实现,比如一个Person类的对象,此对象同样拥有身高、体重、肤色等属性,也有吃饭 ......

## 类
  - 具体事物的抽象和总结,是事物的共性,由属性和方法两个部分构成,比如一个Person类,有是身高、体重、肤色等属性,也有吃饭、睡觉、观察、等方法

## 对象
  - 具体的事物,单一、个体、特性,是一个类的具体实现,比如一个Person类的对象,此对象同样拥有身高、体重、肤色等属性,也有吃饭、睡觉、观察、等方法,但各个Person对象身高、体重、肤色的值并不相同,吃的东西,睡的床,看的电影都不一样

## 定义类

1 # 定义一个空的Person类
2 class Person(object):
3     pass
4 
5 # 类的实例化
6 someone = Person()

 

  - 对象初始化方法(构造方法),在实例化后立即调用

1 class Person(object):
2     def __init__(self):
3         print("初始化。。。")
4 
5 
6 someone = Person()  # 输出:初始化。。。

 

  - 给类添加属性
  - 这里的self指的是对象本身

1 class Person(object):
2     def __init__(self, name, age):
3         self.name = name
4         self.age = age
5 
6 
7 someone = Person("Stanley", 22)  # 实例化时传入此对象的相关属性
8 print(someone.name)              # 输出:Stanley
9 print(someone.age)               # 输出:22        

 

  - 给类添加方法
    - 在参数位置上的self表示当前对象本身(本质上来说是一个形式参数),如果通过对象调用一个方法,那么该对象会自动传入当前方法的第一个参数中
    - self并不是关键字,只是用于接收对象的普通参数,理论上可以用任何一个普通变量名代替

 1 class Person(object):
 2     def __init__(self, name, age):
 3         self.name = name
 4         self.age = age
 5 
 6     def eat(self, food):
 7         print("I'm eating %s." % food)
 8 
 9 
10 someone = Person("Stanley", 22)
11 someone.eat("instant noodle")    # 输出:I'm eating instant noodle.

 

## 代码重用与拓展 -- 继承
  - 继承就是从已经有的类中衍生出新的类,并在新的类中添加或修改部分功能
  - 使用继承的新类会自动获得父类中的所有方法

 1 class Person(object):
 2     def __init__(self, name, age):
 3         self.name = name
 4         self.age = age
 5 
 6     def eat(self, food):
 7         print("I'm eating %s." % food)
 8 
 9 
10 class Student(Person):
11     pass
12 
13 
14 stu = Student("Stanley", 22)    # Student类什么都没做,但还是拥有__init__和eat()方法
15 stu.eat("instant noodle")       # 输出:I'm eating instant noodle.

 

  - 可以使用isinstance()函数判断是否是某类的实例

  - 子类的实例一定是父类的实例,父类的实例只是父类的实例,在这个例子中,一个学生一定是一个人,但不是所有人都是学生

1 print(isinstance(stu, Person))  # 输出:True
2 print(isinstance(stu, Student)) # 输出:True

 

## 覆盖父类中的方法
  - 在子类中定义和父类中某方法名相同的方法,即可用新方法覆盖父类中的方法,包括__init__方法
  - 方法覆盖后,子类对象无法在调用父类中的该方法,而父类对象并不受影响

 1 class Person(object):
 2     def __init__(self, name, age):
 3         self.name = name
 4         self.age = age
 5 
 6     def eat(self, food):
 7         print("I'm eating %s." % food)
 8 
 9 
10 class Student(Person):
11     def eat(self, food):
12         print("I'm a student, I eat %s" % food)
13 
14 
15 per1 = Person("Lily", 22)
16 stu = Student("Stanley", 22)
17 per1.eat("instant noodle")        # 输出:I'm eating instant noodle.
18 stu.eat("apple")                  # 输出:I'm a student, I eat apple.

 

 

  - 给子类添加新方法
  - 子类中的新方法父类实例并不能调用

 1 class Person(object):
 2     def __init__(self, name, age):
 3         self.name = name
 4         self.age = age
 5 
 6     def eat(self, food):
 7         print("I'm eating %s." % food)
 8 
 9 
10 class Student(Person):
11     def eat(self, food):
12         print("I'm a student, I eat %s." % food)
13 
14     def do_homework(self):
15         print("I'm a student, I have to do homework.")
16 
17 
18 per1 = Person("Lily", 22)
19 stu = Student("Stanley", 22)
20 stu.do_homework()       # 输出:I'm a student, I have to do homework.
21 per1.do_homework()      # AttributeError: 'Person' object has no attribute 'do_homework'

 

  - 在子类中使用父类中的方法 -- super()
  - 若在子类中定义__init__方法,则会覆盖掉父类中的__init__方法,所以需要在子类中__init__方法中明确的先调用父类的__init__方法,并传入需要的初始化参数

 1 class Person(object):
 2     def __init__(self, name, age):
 3         self.name = name
 4         self.age = age
 5 
 6     def eat(self, food):
 7         print("I'm eating %s." % food)
 8 
 9 
10 class Student(Person):
11     def __init__(self, name, age, grade):
12         super().__init__(name, age)
13         self.grade = grade
14 
15     def eat(self, food):
16         print("I'm a student, I eat %s." % food)
17 
18     def do_homework(self):
19         print("I'm a student, I have to do homework.")
20 
21 
22 per1 = Person("Lily", 22)
23 stu = Student("Stanley", 22, "Junior")

 

## 对类进行访问限制 -- 封装
  - 封装就是对对象成员进行访问限制
    - 私有
      - 私有成员是*别的封装,只能在当前类或者对象中使用
      - 在成员前面添加两个下划线即可表示该属性是私有属性
      - Python的私有并不是真的私有,是一种称为mangling的改名策略,可以使用对象._classname_attrbutename访问

 1 class Student:
 2     __name = "Stanley"
 3     __age = 18
 4 
 5 
 6 stu = Student()
 7 print(stu.__name)
 8 # 私有属性无法直接访问
 9 # 输出:AttributeError: 'Student' object has no attribute '__name'
10 print(stu._Student__name)
11 # 私有属性可以通过特殊方式访问
12 # 输出:Stanley

 

本文参考:

  [美]Bill Lubanovic 《Python语言及其应用》