1.OOP(Object Oriented Programming)
-
思想:
- 以模块化思想解决工程问题
- 面向过程 vs 面向对象
- 由面向过程转向面向对象
- 例子,我要开一个学校:
- 讲师
- 班主任
- 学生
- 教室
- 。。。。。。
-
常用名词
- OO:面向对象
- OOA:分析
- OOD:设计
- OOP:编程
- OOI:实现
- OOA -> OOD -> OOI
-
类 vs 对象 (两者是归属关系,但是不是组成关系)
- 类:抽象,描述的是一个集合,侧重于共性(学生类)
- 对象:具象,描述的是个体(张同学)
-
类的内容:
- 动作,函数
- 属性,变量
-
定义类:class关键字
-
类命名:
- 遵循大驼峰(每一个单词的首字母都采用大写字母)
- 第一个字母大写
# 定义学生类,和几个学生
class Student():
# 此处定义一个空类
# pass是关键字,表示占位用的,无意义(养成好习惯)
pass
# 定义一个对象
zhangsan = Student()
# 定义时,全体缩进
class PythonStudent():
name = "Nobody"
age = 20
course = "Python"
'''
定义类中的函数,一般要有self关键字
其余跟普通函数基本相同
'''
def giveMoney(self):
print("show me the money")
return None
lisi = PythonStudent()
print(lisi.name)
print(lisi.age)
print(lisi.course)
Nobody
20
Python
2.类的属性
# 类的例子
# 注意类的定义
class Student():
# name,age是类的变量
name = "amy"
age = 20
def sayHi(self):
print("类的属性")
return None
def sayHello(koko):
print("将self替换为koko")
return None
# 实例化
lisi = Student()
print(lisi)
2.1 self
- self可以用别的名称代替
- self不是关键字
- 作用是指代本身
# self举例
# 实例调用函
honghong = Student() # 实例化yaoyao
# 让honghong跟我打招呼
# honghong调用sayHi没有输入参数
# 因为迷人实例作为第一个传入的参数,即honghong代替self
honghong.sayHi()
# 错误的案例:
# a = "你好"
# honghong.sayHi(a)
类的属性
#这个案例说明self的名称可以更改,实际上self为形参
honghong.sayHello()
将self替换为koko
2.2 类的变量作用域的问题
- 类变量:属于类自己的变量
- 实例变量:属于实例的变量
- 以下两个案例的总结:
- 定义了实例的属性后,当访问实例的属性时,优先访问实例自己的属性;若没有,则访问类的属性。
# 案例1:
# 注意类的定义
class Student():
# name,age是类的变量
name = "amy_77"
age = 20
def sayHi(self):
print("My Name is {}, i am {} years old".format(self.name,self.age))
self.age = 21
self.name = "NoName"
return None
# 此案例说明,实例变量可以借用类的变量
qianqian = Student()
qianqian.sayHi()
My Name is amy_77, i am 20 years old
# 案例2:
# 注意类的定义
class Student2():
# name,age是类的变量
name = "amy_77"
age = 20
def sayHi(self, n, a ): # 实例变量,给self定义自己的变量name和age
self.name = n
self.age = a
print("My Name is {}, i am {} years old".format(self.name,self.age))
return None
# 此案例说明,实例变量可以借用类的变量
qianqian = Student2()
# 注意观察下面语句打开和关闭后的区别
# qianqian.sayHi("yuanyuan", 30)
print("My Name is {}, i am {} years old".format(Student2.name,Student2.age))
print("My Name is {}, i am {} years old".format(yuanyuan.name,yuanyuan.age))
#若果访问实例的属性没有定义,则自动访问类的属性
# 如果类也没有定义,则报错
My Name is amy_77, i am 20 years old
My Name is amy_77, i am 20 years old
2.3 访问类的属性
- 在类里面如果强制访问类的属性,则需要使用__class__(前后两个下划线)
- 类方法:
- 定义类的方法的时候,没有self参数
- 类的方法中只允许使用类的内容
- 两种方法
- ClassName
- __ class __(前后两个下划线)
class Student3():
# name,age是类的变量
name = "amy_77"
age = 20
def sayHi(self):
print("My Name is {}, i am {} years old".format(self.name,self.age))
return None
# SOS是类的方法
def SOS():
# 类方法中不允许访问实例的任何内容
#print("My Name is {}, i am {} years old".format(self.name,self.age))
# 如果访问想要类的内容,有下面两种方法:
print("My Name is {}, i am {} years old".format(Student3.name,__class__.age))
return None
# 体验类的方法
s = Student3()
s.sayHi()
# 调用类方法的例子
Student3.SOS()
# SOS() takes 0 positional arguments but 1 was given
# SOS()接受0个位置参数,但给出了1个
My Name is amy_77, i am 20 years old
My Name is amy_77, i am 20 years old
2.4 构造函数
- 类在实例化的时候,执行一些基础性的初始化的工作
- 使用特殊的名称和写法
- 在实例化的时候自动执行
- 是在实例化的时候 “第一个” 被执行的函数
class Student4():
name = "Everybody"
age = 0
# 构造函数名称固定,写法相对固定
def __init__(self):
print("我是一个构造函数")
qianqian = Student4()
print("*******************")
print(qianqian.name)
print(qianqian.age)
我是一个构造函数
Everybody
0
3.面向对象的三大特征
- 继承
- 封装
- 多态
3.1 继承(Python不重复造轮子)
- 字类可以使用父类定义的内容或者行为等
- 继承的实现:
-
父类,基类,超类:被继承的类,Base Class,Super Class
-
子类,有继承行为的类
-
所有类都必须有一个父类
-
如果没有,则默认是object的字类
-
# 所有类必须有父类
# 默认为object
class Person1():
pass
class Person2(object):
pass
class Person():
name = "NoName"
age = 0
# 父类写在类定义的时候的括号里
class Teacher(Person):
pass
t = Teacher()
print(t.name)
NoName
class Bird():
fly = "Yes,I can"
def flying(self):
print("飞呀飞呀")
class BirdMan(Person, Bird):
pass
bm = BirdMan()
bm.flying()
print(bm.name
飞呀飞呀
NoName
3.2 issubclass检测是否是子类
- 可以用来检测两个类的父子关系
# 利用刚才定义的Bird,BirdMan,Person,Teacher,检测父子关系
print(issubclass(BirdMan, Bird))
print(issubclass(BirdMan, Person))
print(issubclass(BirdMan, Teacher))
# help(issubclass)
True
False
False
4.构造函数
- 在函数实例化的时候调用的一个函数
- 自动调用
- 要求:
- 第一个参数必须有,一般推荐为self
- 构造函数的调用时间:一般认为在实例化的时候,第一次被调用
- 一般不手动调用,实例化的时候自动调用,参数需要写入类名称后面的括号中
class Bird():
def __init__(self):
print("我被调用了")
return None
# 此时被调用构造函数
b = Bird()
我被调用了
# 构造函数2
class Person():
def __init__(self, name, age):
print(name, age)
p = Person("amy", 21)
amy 21
4.1 构造函数的继承
- 构造函数默认继承
- 一旦子类定义了构造函数,则不再自动调用父类构造函数
# 构造函数默认继承
class Person():
def __init__(self, name, age):
print("Person = ({}, {})".format(name, age))
# Teacher自动继承上面的构造函数
class Teacher(Person):
pass
t = Teacher("amy", 21)
t = Teacher()# 此代码报错
Person = (amy, 21)