目录
1.面向对象编程
(1)什么是面向对象编程
- 面向对象编程 Object Oriented Programming,简称OOP是一种程序设计思想。
- OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
- 在python中,所有数据类型都被视为对象,也可以自定义对象。
(2)面向对象技术简介
- 类(Class): 用来描述具有相同的属性和方法的对象的集合,对象是类的实例。
- 方法:类中定义的函数。
- 类变量(属性):类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:对从父类继承的方法其进行改写,这个过程称为方法重写。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- 多态:对不同类的对象使用同样的操作
- 封装:对外部世界隐藏对象的工作细节
2.__init__作用
__init__()为构造函数
- (1)定义实例变量
- (2)初始化实例,给实例绑上实例变量
3.self作用
- (1)self代表类的实例,而非类。
- (2)__init__与其他函数的第一参数为self
- (3)self不必非写成self,写成self不过是原因习惯,可以将self改成其他单词代替
4.类变量,实例变量,局部变量
Python类中有类变量、实例变量(也叫成员变量、对象变量) 和 局部变量
(1)类变量
- 存在于函数体外,即在class与 __init__之间,可被所有实例化对象引用。
- 类变量通常不作为实例变量使用,如果类变量和实例变量同名,会优先调用实例变量。
(2)实例变量
- 实例变量是在构造函数__init__中通过“self.变量名”方式定义的。
(3)局部变量
- 定义在方法中的变量,只作用于当前实例的类。
例子:注意类变量、实例变量、局部变量定义时所在的位置,并引用方法
class people(object):
#定义类变量
name='len'
age='31'
def __init__(self,lan,food):
#定义实例变量
self.language=lan
self.food=food
self.age='33'
def speak(self,con1):
#函数中引用类变量与实例变量
print(self.name,"speak",self.language,"and say",con1)
def eat(self,con2):
print(self.name,"eat",self.food,"and love to eat",con2)
def info(self):
#定义局部变量
_date='2019'
#类变量与实例变量都有age,会优先调用实例变量
print(self.name,'is ',self.age,' old at ',_date)
if __name__=='__main__':
#类实例化
len=people('chinese','meat')
#输出实例的类变量
print(len.name)
#输出实例的方法
print(len.language,len.food)
len.speak("nice to meet you")
len.eat('breef')
len.info()
#len
#chinese meat
#len speak chinese and say nice to meet you
#len eat meat and love to eat breef
#len is 33 old at 2019
5.类属性和方法
(1)内置类属性
- __dict__ : 类的属性
- __doc__ :类的文档
- __name__: 类名
- __module__: 类定义所在的模块
- __bases__ : 类的所有父类构成元素
(2)类的私有属性
- 由两个下划线开头,不能在类的外部被使用或直接访问。在类内部用self.__private_attrs调用。
(3)类的方法结
- 在类的内部,使用 def 关键字可以为类定义一个方法,第一个参数必须为 self 。
(4)类的私有方法
- 由两个下划线开头,不能在类的外部被使用或直接访问。在类内部用self.__private_methods调用。
(5)单下划线、双下划线、头尾双下划线说明
- __foo__: 特殊方法,一般是系统定义名字 ,类似 __init__() 之类的。
- _foo: 为被保护类型的变量,只能允许其本身与子类进行访问,不能用于 from module import *
- __foo: 表示是私有类型的变量, 只能允许这个类本身进行访问。
6.类继承相关概念
- 父类、超类、基类、子类、派生类
- 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。
- 继承、派生
- 继承和派生是一回事,子类继承父类,父类派生子类。
7.子类继承父类—类变量
(1)直接调用父类类变量
子类会直接继承父类的类变量,故不用另外声明,直接使用即可,使用时在类变量前加上self
class Person():
info='person'
def __init__(self):
self.name='len'
print(self.info)
class Chinese(Person):
def __init__(self):
self.high=169
def get_info(self):
print(self.info)
if __name__ == "__main__":
p=Person()
a = Chinese()
a.get_info()
(2)子类父类有同名类变量,如何指定子类是调用父类的
class Person():
info='person'
def __init__(self):
self.name='len'
print(self.info)
class Chinese(Person):
info='Chinese'
def __init__(self):
self.high=169
def get_info(self):
print(self.info)
print(super().info)
if __name__ == "__main__":
a = Chinese()
a.get_info()
8.子类继承父类—构造函数(实例变量)
(1)子类没有构造函数时则会直接继承父类构造函数中的实例变量
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def speak(self,language):
print(("speaking {}").format(language))
class Chinese(Person):
def eat(self,food):
print(("len eats {}").format(food))
if __name__ == "__main__":
#输入父类的参数
a = Chinese('len','21',67)
a.speak('english')
(2)子类有构造函数时则不会直接继承父类构造函数中的实例变量
- 子类会直接继承父类的类变量和方法函数,但当子类有自己的构造函数时,则不会直接继承父类的实例变量,需另外声明才能继承,在没有另外声明情况下,当子类调用父类的方法函数时,若该函数用到父类的实例变量,会报错.
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def speak(self,language):
print(("speaking {}").format(language))
class Chinese(Person):
def __init__(self,h):
self.high=h
if __name__ == "__main__":
a = Chinese(167)
print(a.high)
a.speak('english')
(3)声明子类继承父类构造函数的实例变量
class Person():
def __init__(self):
self.name='len'
def speak(self,language):
print(("{} is speaking {}").format(self.name,language))
class Chinese(Person):
def __init__(self,h):
Person.__init__(self)
self.high=h
if __name__ == "__main__":
a = Chinese(167)
print(a.name)
a.speak('english')
(4)父类构造函数有参数,子类构造函数要带上
- 在子类调用父类的构造函数时,参数名称不一定相同,但数量与输入顺序必须一致
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def speak(self,language):
print(("{} is speaking {}").format(self.name,language))
def eat(self,food):
print(("{} eats {}").format(self.name,food))
class Chinese(Person):
def __init__(self,n,a,w,h):
Person.__init__(self,n,a,w)
self.high=h
if __name__ == "__main__":
a = Chinese('len','21',67,169)
print(a.high)
a.eat('meat')
9.子类继承父类—调用方法函数
(1)子类实例化后调用父类方法函数
- 子类会直接继承父类的方法函数,但不会直接继承实例变量,故要注意函数是否用到父类的实例变量
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def speak(self,language):
print(("{} is speaking {}").format(self.name,language))
class Chinese(Person):
def __init__(self,n,a,w,h):
Person.__init__(self,n,a,w)
self.high=h
if __name__ == "__main__":
a = Chinese('len','21',67,169)
a.speak('english')
(2)子类方法函数中调用父类方法函数
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def speak(self,language):
print(("{} is speaking {}").format(self.name,language))
class Chinese(Person):
def __init__(self,n,a,w,h):
Person.__init__(self,n,a,w)
self.high=h
def say(self,language):
self.speak(language)
print("so I say hello to him")
if __name__ == "__main__":
a = Chinese('len','21',67,169)
a.say('english')
10.子类继承父类—重写父类方法函数
(1)重写父类方法函数
重写父类方法函数,即子类中有一方法与父类的同名,子类的会直接覆盖父类同名的方法
class Person():
def __init__(self, n, a, w):
self.name = n
self.age = a
self.weight = w
def speak(self, language):
print(("{} is speaking {}").format(self.name, language))
class Chinese(Person):
def __init__(self, n, a, w, h):
Person.__init__(self, n, a, w)
self.high = h
def speak(self, context):
print(context)
if __name__ == "__main__":
a = Chinese('len', '21', 67, 169)
a.speak("nice to meet you")
(2)在重写方法时如何调用父类的同名方法
class Person():
def __init__(self, n, a, w):
self.name = n
self.age = a
self.weight = w
def speak(self, language):
print(("{} is speaking {}").format(self.name, language))
class Chinese(Person):
def __init__(self, n, a, w, h):
Person.__init__(self, n, a, w)
self.high = h
def speak(self, context):
super(Chinese,self).speak("english")
print(context)
if __name__ == "__main__":
a = Chinese('len', '21', 67, 169)
a.speak("nice to meet you")
#结果:
#len is speaking english
#nice to meet you
(3)子类实例化后如何调用父类中已被重写的方法
class Person():
def __init__(self, n, a, w):
self.name = n
self.age = a
self.weight = w
def speak(self, language):
print(("{} is speaking {}").format(self.name, language))
class Chinese(Person):
def __init__(self, n, a, w, h):
Person.__init__(self, n, a, w)
self.high = h
def speak(self, context):
super(Chinese,self).speak("english")
print(context)
if __name__ == "__main__":
a = Chinese('len', '21', 67, 169)
#调用父类方法speak()
super(Chinese, a).speak("english")
#结果:
#len is speaking english
11.子类继承父类—多继承
(1)多继承概念与规则
- 多继承指一个子类同时继承自多个父类
- 类变量:父类中存在相同的类变量,默认调用括号里的第一个父类的类变量
- 实例变量:父类中存在相同的实例变量,默认最后一个被调用的父类构造函数中实例变量
- 方法:父类中存在相同的方法,默认调用括号里的第一个父类的方法
- 注:类变量与实例变量同名时,优先使用实例变量
(2)多继承时若子类没构造函数则直接继承第一个父类的构造函数
- 子类从多个父类派生,而子类又没有自己的构造函数时,则直接继承第一个父类的构造函数,第一个父类没有构造函数,则继承第2个父类的构造函数,以此类推
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def name(self):
print('his name is {}'.format(self.name))
class Chinese():
def __init__(self,l):
self.language=l
def speak(self):
print(("he speaks {}").format(self.language))
class Student(Person,Chinese):
def grades(self):
print("he is {} years old and in grades 3".format(self.age))
if __name__ == "__main__":
a = Student('len','21',67)
a.grades()
(2)多继承中子类如何继承所有父类带参数的构造函数
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
class Chinese():
def __init__(self,l):
self.language=l
class Student(Person,Chinese):
def __init__(self,n,a,w,l,g):
Person.__init__(self, n, a, w)
Chinese.__init__(self,l)
self.grades=g
def learn(self):
print("he learns {} and in grades {}".format(self.language,self.grades))
if __name__ == "__main__":
a = Student('len','21',67,'chinese',3)
a.learn()
(3)多继承中父类中存在同名方法,如何指定
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
def eat(self):
print('he eats meat')
class Chinese():
def __init__(self,l):
self.language=l
def eat(self):
print('he eats rice')
class Student(Person,Chinese):
def __init__(self):
pass
def live(self):
super().eat() #Person的eat()
super(Student,self).eat() #Person的eat()
super(Person,self).eat() #Chinese的eat()
if __name__ == "__main__":
a = Student()
a.live()
#结果:
#he eats meat
#he eats meat
#he eats rice
12.子类继承父类—super
(1)super继承父类构造函数-单继承
class Person():
def __init__(self,n,a,w):
self.name=n
self.age=a
self.weight=w
class Chinese(Person):
def __init__(self,n,a,w,l):
super().__init__(n,a,w)
self.language=l
if __name__ == "__main__":
a = Chinese('len','21',67,169)
print(a.name)
(2)super继承父类构造函数-多继承且父类有同名实例变量
class Person():
def __init__(self,n,g):
self.name=n
self.age=g
class Chinese():
def __init__(self,l,g):
self.language=l
self.age=g
class Student(Person,Chinese):
def __init__(self,n,g,l):
super().__init__(n,g)
super(Person, self).__init__(l,g)
if __name__ == "__main__":
a = Student('len',32,'chinese')
print(a.name)
print(a.age)
print(a.language)
(3)super继承父类方法-单继承
class Person():
def __init__(self,n,g):
self.name=n
self.age=g
def speak(self,language):
print(("{} is speaking {}").format(self.name, language))
class Chinese(Person):
def __init__(self,n,g,l):
self.language=l
super().__init__(n,g)
def say(self):
super().speak(self.language)
print("nice to meet you")
if __name__ == "__main__":
a = Chinese('len',32,'chinese')
a.say()
(4)super继承父类方法-多继承
- 参考:多继承中父类中存在同名方法,如何指定
(5)super继承父类方法-实例化后继承
- 参考:子类实例化后如何调用父类中已被重写的方法
13.其他
(1)class()与class(object)区别
- #1:经典类与新式类
- python2中不继承object的类叫经典类,继承object的类叫做新式类;经典类是默认没有派生自某个基类的,而新式类默认派生自object基类。
- python3中,类定义默认继承object,即只承认新式类,所以写不写没有区别
- #2:经典类与新式类的区别
- 搜索次序区别:经典类继承父类的顺序采用深度优先算法,新式类的继承顺序采用C3算法
- 类可用变量与方法不同
(2)多态
- https://www.cnblogs.com/rainbow-ran/p/12204897.html