Python学习记录5-面向对象
OOP
-
思想
- 以模块化思想解决工程问题
- 面向过程 vs 面向对象
- 由面向过程转向面向对象
-
常用名词
- OO:面向对象
- ooa:分析
- ood:设计
- oop:编程
- ooI:实现
- ooa -> ood -> ooi
-
类 vs 对象
- 类:抽象,描述的是一个集合,侧重于共性
- 对象:具象,描述的是个体
-
类的内容
- 动作,函数
- 属性,变量
-
is-a
-
定义类:class关键字
-
类命名:
- 遵循大驼峰
- 第一个字母大写
#定义学生类,和几个学生
>>> class Student():
# 此处定义一个空类
# pass是关键字,表示占位用的,无意义
pass
# 定义一个对象
>>> xiaobai = Student()
>>> class PythonStudent():
name = "NoOne"
age = 18
course = "Python"
#定义类中的函数,一般需要有self关键字,其余跟普通函数基本相同
>>> def giveMeMoney():
print("给我钱")
return None
>>> xiaobai = PythonStudent()
>>> print(xiaobai.name)
>>> print(xiaobai.age)
>>> print(xiaobai.course)
输出:
NoOne
18
Python
类的属性
# 类的例子
# 注意类的定义
>>> class Student():
name = "哈哈哈"
age = 19
>>> def sayHi(self):
print("小乔要努力变强")
return None
# 实例化
>>> zhaosi = Student()
>>> print(zhaosi.name)
>>> zhaosi.sayHi()
输出:
哈哈哈
小乔要努力变强
self
- self可以用别的名称代替
- self不是关键字
- 作用是指代本身
# self
# 实例调用函数
>>> class Student():
name = "哈哈哈"
age = 19
>>> def sayHi(self): # self不是一个关键字 只是一个形参 可以任意替换
print("小乔要努力变强")
return None
>>> xiaoqiao = Student()
# 打招呼
>>> xiaoqiao.sayHi() #上面定义的sayHi()方法 是需要一个参数的 但是这里是默认将调用者放入了
#此时不能再传入参数 会报参数过多的错误
输出:
小乔要努力变强
类的变量作用域的问题
- 类变量:属于类自己的变量
- 实例变量:属于实例的变量
- 访问实例的属性,如果实例没有定义属性,则自动访问类的属性,如果类也没有定义则报错
>>> class Student():
# name,age是类的变量
# 注意类的变量的定义位置和方法
# 不需要前缀
name = "哈哈哈"
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
# 实例变量可以使用类的变量
>>> hh = Student()
>>> hh.sayHi("嘻嘻",17)
>>> print("My name is {},i am {} years old".format(Student.name,Student.age))
>>> print("My name is {},i am {} years old".format(hh.name,hh.age))
输出:
My name is 嘻嘻,i am 17 years old
My name is 哈哈哈,i am 19 years old
My name is 嘻嘻,i am 17 years old
访问类的属性
- 在类里面如果强制访问类的属性,则需要使用_class_,(注意前后的两个下划线)
- 类方法:
- 定义类的方法的时候,没有self参数
- 类的方法中只允许使用类的内容
- 两种用法
- ClassName
- class ,前后各两个下划线
>>> class Student():
# name,age是类的变量
# 注意类的变量的定义位置和方法
# 不需要前缀
name = "哈哈哈"
age = 19
>>> def sayHi(self):
print("My name is {},i am {} years old".format(self.name,self.age))
return None
# sayHi是类方法
# 如何访问类的变量
# 但是调用需要用到特殊的方法
>>> def sos():
# 类方法中不允许访问实例的任何内容
print("My name is {},i am {} years old".format(Student.name,__class__.age))
return None
# 类的方法
>>> s = Student()
>>> s.sayHi()
>>> Student.sos()
输出:
My name is 哈哈哈,i am 19 years old
My name is 哈哈哈,i am 19 years old
构造函数
- 类在实例化的时候,执行一些基础性的初始化的工作
- 使用特殊的名称和写法
- 在实例化的时候自动执行
- 是在实例化的时候第一个被执行的函数(此处先这样理解)
# 注意类的定义
>>> class Student():
name = "NoName"
age = 0
# 构造函数名称固定,写法相对固定
>>> def __init__(self):
print("我是构造函数")
>>> xiaoming = Student()
>>> print("-------------")
>>> print(xiaoming.name)
>>> print(xiaoming.age)
输出:
我是构造函数
-------------
NoName
0
面向对象的三大特征
- 继承
- 封装
- 多态
继承
- 子类可以使用父类定义的内容或者行为等
- 继承的实现
- 父类、基类、超类:被继承的类,Base Class,Supper 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 = "I can fly"
>>> def flying(self):
print("我会飞了")
>>> class BirdMan(Person,Bird):
pass
>>> bm = BirdMan()
>>> bm.flying()
>>> print(bm.name)
输出:
我会飞了
NoName
issubclass检测是否是子类
- 可以用来检测两个类的父子关系
# 利用刚才定义的Bird,BirdMan,Person,Teacher检测父子关系
>>> print(issubclass(BirdMan,Bird))
>>> print(issubclass(BirdMan,Person))
>>> print(issubclass(BirdMan,Teacher))
输出:
True
True
False
构造函数
- 在函数实例化的时候调用的一个函数
- 自动调用
- 要求,第一个参数必须有,一般推荐self
- 构造函数的调用时间:一般认为在实例化的时候第一个被调用
- 一般不手动调用,实例化的时候自动调用,参数需写入类名称后面的括号中
>>> class Bird():
>>> def __init__(self):
print("我被调用了")
return None
#此时被调用的构造函数
>>> b = Bird()
输出:
我被调用了
---------------------------------------------------------------------------------------------------
# 构造函数2
>>> class Person():
def __init__(self,name,age):
print(name,age)
>>> p = Person("哈哈哈",19)
输出:
哈哈哈 19
构造函数的继承
- 构造函数默认继承
- 一旦子类定义了构造函数,则不再自动调用父类构造函数
# 构造函数默认继承
>>> class Person():
def __init__(self, name, age):
print("Person=({},{})".format(name, age))
>>> class Teacher(Person):
pass
>>> t = Teacher("哈哈哈",19)
# 上面的构造函数是需要两个参数的,而下面却没有给出所以会报错
#t = Teacher()
输出:
Person=(哈哈哈,19)
总结
Python和Java都是面向对象的,因此还是比较好理解的,但是Python定义的语法上还是跟Java有一些区别的,消化吸收,加油。