OOP
-
思想
- 以模块化思想解决工程问题
- 面向过程 VS 面向对象
- 由面向过程转向面向对象
-
常用名词
- OO:面向对象
- OOA:分析
- OOD:设计
- OOP:编程
- OOI:实现
-
类 VS 对象
- 类:抽象,描述的是一个集合,侧重共性(学生)
- 对象:具象,描述的是个体(张三)
-
类的内容
- 动作,函数
- 属性,变量
-
is-a
-
定义类:class关键字
-
类命名:
- 遵循大驼峰
- 第一个字母大写
# 定义学生类,和几个学生
class Student():
name = "Yuanshuo"
age = 22
def sayHi(self):
print("Life is fantastic!")
return None
# 实例化
Yuanshuo = Student()
print(Yuanshuo)
<__main__.Student object at 0x10fa46198>
self
- self 可以用别的名称代替
- self 不是关键字
- 作用是指代本身
# self 举例
Yuanshuo = Student()
# Yuanshuo调用sayHi()没有输入参数
# 因为默认实例作为第一个参数传入
Yuanshuo.sayHi()
Life is fantastic!
类的变量作用域的问题
- 类变量:属于类自己的变量
- 实例变量: 属于实例的变量
- 访问实例的属性,如果实例没有定义属性,则自动访问类的属性,如果类也没有定义,报错|
class Student():
# name, age 是类的变量
# 注意类的变量的定义位置和方法
# 不需要前缀
name = "Yuanshuo"
age = 19
def sayHi(self):
print("My name is {}, I am {} years old.".format(self.name, self.age))
return None
# 示例说明,实例变量可以借用类的变量
Yuanshuo = Student()
Yuanshuo.sayHi()
My name is Yuanshuo, I am 19 years old.
class Student():
# name, age 是类的变量
# 注意类的变量的定义位置和方法
# 不需要前缀
name = "Yuanshuo"
age = 19
def sayHi(self, n, a):
self.name = n
self.age = a
print("My name is {}, I am {} years old.".format(self.name, self.age))
return None
# 示例说明,
Yuanshuo = Student()
Yuanshuo.sayHi("Dapeng", 17)
# 如果访问实例的属性没有定义,则自动访问类的属性
# 如果类也没有定义,报错
print(Yuanshuo.wife())
My name is Dapeng, I am 17 years old.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-4649390c3408> in <module>
18 # 如果访问实例的属性没有定义,则自动访问类的属性
19 # 如果类也没有定义,报错
---> 20 print(Yuanshuo.wife())
AttributeError: 'Student' object has no attribute 'wife'
访问类的属性
- 在类里面如果强制访问类的属性,则需要使用class,class(注意前后两个下划线)
- 类方法:
- 定义类的方法的时候,没有self参数
- 类方法中只允许使用类的内容
- 两种用法
- 类名称.属性
- class.属性
class Student():
# name, age 是类的变量
# 注意类的变量的定义位置和方法
# 不需要前缀
name = "Yuanshuo"
age = 19
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(Student.name, __class__.age))
return None
# 体验类的方法
Yuanshuo = Student()
Yuanshuo.sayHi()
# 调用类方法的例子
Student.SOS()
My name is Yuanshuo, I am 19 years old.
My name is Yuanshuo, I am 19 years old.
构造函数
- 类在实例化的时候,执行一些基础性的初始化的工作
- 使用特殊的名称和写法
- 在实例化的时候自动调用
- 实在实例化的时候第一个被执行的函数
- 要求,第一个参数必须有, 一般推荐self
class Student():
name = "NoName"
age = 0
# 构造函数名称固定,写法相对固定
def __init__(self):
print("我是构造函数")
Yuanshuo = Student()
print("----------")
print(Yuanshuo.name)
print(Yuanshuo.age)
我是构造函数
----------
NoName
0
面向对象的三大特征
- 继承
- 封装
- 多态
继承
- 子类可以使用父类定义的内容或者行为等
- 所有类都必须有一个父类
- 如果没有,则默认为是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 = "We can fly."
def flying(self):
print("Flying!")
class BirdMan(Person, Bird):
pass
bm = BirdMan()
bm.flying()
print(bm.name)
Flying!
NoName
issubclass检测是否是子类
- 可以用来检测两个类的父子关系
# 利用上面定义的Bird, Person, BridMan, Teacher检测父子关系
print(issubclass(BirdMan,Bird))
print(issubclass(BirdMan,Person))
print(issubclass(BirdMan,Teacher))
print(issubclass(Teacher,Person))
True
True
False
True
构造函数的继承
- 构造函数默认继承,子类如果没有构造函数,则自动调用父类的构造函数
- 一旦子类定义了构造函数,则不再自动调用父类的构造函数
class Person:
def __init__(self, name, age):
print("Person=({},{})".format(name, age))
class Teacher(Person):
pass
t = Teacher("Yuanshuo", 19)
t = Teacher()
Person=(Yuanshuo,19)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-33-42c7a2d76a67> in <module>
7
8 t = Teacher("Yuanshuo", 19)
----> 9 t = Teacher()
TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
网友评论