- python是面向对象(每个对象包含标识、类型、值的信息)的,对象的本质就是:一个内存块,拥有特定的值,支持特定类型的相关操作 。变量:对象的引用。
- Python 中“一切皆对象”, 所有的赋值操作都是“引用的赋值”
【OOP】(Object-oriented programming )面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而大大提高了编程的效率。
简介
Tips操作:
- dir() :获得一个对象的所有属性和方法,,它返回一个包含字符串的list;
常用的概念
- 【类】(class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 【方法】:类中定义的函数。
- 【类变量】:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 【数据成员】:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 【方法重写】:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 【局部变量】:定义在方法中的变量,只作用于当前实例的类。
- 【实例变量】:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
- 【继承】:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 【实例化】:创建一个类的实例,类的具体对象。
- 【对象】:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
对象的进化
- 简单数据:比如30.4,20等等;
- 数组:将同类型的数据放到一起。比如:整数数组[20,30,40],浮点数数组[10.2, 11.3, 12.4],字符串数组:["aa", "bb", "cc"]
- 结构体:将不同类型的数据放到一起,是C 语言中的数据结构(labview中的簇Cluster,python中的tuple)。比如:
struct resume{
int age;
char name[10];
double salary;
}; - 对象:将不同类型的数据、方法(即函数)放到一起,就是对象。
# coding: gbk
class Student:
company = "SXT" #类属性
count = 0 #类属性
def __int__(self,name,score):
self.name = name # 实例属性
self.score =score
Student.count = Student.count+1
def say_score(self): # 实例方法
print("我的公司是:",Student.company)
print(self.name,"的分数是",self.score)
我们前面学习的数字也是对象。比如:整数 9,就是一个包含了加法、乘法等方法的对象。
小甲鱼的例子
# coding: gbk
class Turtle: #Python中类名约定以大写字母开头
#属性
color = "green"
weigh = 10
legs =4
shell =True
#方法
def climb(self):
print("我正在努力往前爬")
def run(self):
print("我很会跑")
def eat(self):
print("我吃虫子")
tt = Turtle()
tt.climb() #输出:我正在努力往前爬
tt.run() #输出:我很会跑
tt.eat() #输出:我吃虫子
- 属性+方法=对象
- 我们通过类定义数据类型的属性(数据)和方法(行为),也就是说,"类将行为和状态打包在一起"
- 对象是类的具体实体,一般称为"类的实例",类看做"饼干模具",对象就是根据这个"模具"制造出的"饼干"
- 从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但会有自己的属性值(不共享状态),更具体一点:"方法代码是共享的,属性数据不共享"
- Python 中一切皆对象,类也称为"类对象",类的实例也称为"实例对象"
构造函数
xx
比如:
什么是self
类相当于图纸,类实例化后的对象才是能住人的房子。想一下如果有一排房子都是同一个图纸设计出来的,那么我们可以说这些房子属于同一个class类,但是房子的门牌号都不同,self就相当于门牌号码,用来区分每一个房子。python中的self相当于C++中的this指针。
调用类方法的两种方式:
- 通过实例来调用:即先Animal()实例化,实例化完成以后我们赋值变量一个dog,也就是 dog = Animal() ,dog是一个实例对象,然后就可以调用类方法比如dog.play()
- 通过类来直接调用:你需要传递一个实例对象,所以这种方法比较麻烦,因为在这一步之前你还是要实例化,也就是两步骤法 dog = Animal() Animal.play(dog) ,所以不如直接使用上一种方法
slef就是类的实例对象,它可以在每个方法中使用,因为每个方法都有self,而方法之间的相互调用和我们函数之间的嵌套调用是一样的。我们实例一个dog,那么所有的self就相当于dog,self.eat就等价于dog.eat。
# coding: gbk
class Animal(object):
def eat(self,food):
print(f"正在吃{food}")
def play(self):
print("正在玩耍")
def sleep(self):
self.eat("狗粮")
print("正在睡觉")
dog = Animal() # Animal()表示实例化,实例化完成以后我们赋值变量一个dog,dog是一个实例对象
dog.play() # 调用类中的play方法
#Animal.play() # 报错,play() missing 1 required positional argument: 'self'
#Animal.play(self) # 报错,name 'self' is not defined
Animal.play(dog) # 输出正在玩耍
Animal.eat(dog,"狗粮") # 输出正在吃狗粮
dog.sleep() # 输出正在吃狗粮 正在睡觉
参考资料:
(1) Python面向对象的self究竟是什么?
xx
封装(隐藏)
隐藏对象的属性和实现细节,只对外提供必要的方法。相当于将“细节封装起来”,只对外暴露"相关调用方法”。
通过前面学习的"私有属性、私有方法"的方式,实现“封装”。Python 追求简洁的语法,没有严格的语法级别的"访问控制符",更多的是依靠程序员自觉实现。
补充私有属性、私有方法
list是python的序列对象。list就是对象,它提供了若干种方法来让我们根据需求来调整整个列表(比如append,sort),但是我们不知道list对象里面的那些方法是如何实现的,也不知道list对象里面有哪些变量,这就是封装,只给我们需要的方法的名字。
继承
继承可以让子类具有父类的特性,提高了代码的重用性。从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进已有的算法。
多态
【多态】(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。在现实生活中,我们有很多例子。比如:同样是调用人的休息方法,张三的休息是睡觉,李四的休息是玩游戏,高淇老师是敲代码。同样是吃饭的方法,中国人用筷子吃饭,英国人用刀叉吃饭,印度人用手吃饭。 关于多态要注意以下 2 点: 1. 多态是方法的多态,属性没有多态。 2. 多态的存在有 2 个必要条件:继承、方法重写。
补充下面例子isinstance的介绍
# coding: gbk
# 多态
class Animal:
def shout(self):
print("动物叫了一声")
class Dog(Animal):
def shout(self):
print("小狗,汪汪汪")
class Cat(Animal):
def shout(self):
print("小猫,喵喵喵")
def animalShout(a):
if isinstance(a, Animal):
a.shout() # 传入的对象不同,shout方法对应的实际行动也不同
animalShout(Dog()) # 输出:小狗,汪汪汪
animalShout(Cat()) # 输出:小猫,喵喵喵
### 以下没有继承,所以不是多态
class A:
def fun(self):
print("我是小A")
class B:
def fun(self):
print("我是小B")
a = A()
b = B()
a.fun() #输出我是小A
b.fun() #输出我是小B,虽然函数名都是fun
材料科学(化学)中的多态:图中的材料都是C单质形成的物质,但是结构和性质不同,因而是不同的物质。
Some allotropes of carbon: 按顺序依次为:
- diamond
- graphite
- lonsdaleite
- C60
- C540
- C70
- amorphous carbon
- carbon nanotube
上面展示的其实就是C的同素异形体,从更大的概念上说,上面说的多态其实是【同质异形体】(polymorphism),比如Al2O3的多种晶型。进一步类比,OOP的多态前提是继承,其实就是保证我们这里化学组成相同,比如α-Al2O3和β-Al2O3都是继承自Al2O3,那么如果都调用space_group方法,得到的结果肯定不同。