面向对象汇总
1.什么是类?
抽象的模板,表示就是对具有相同属性和方法对象的集合
2.定义一个类的语法规则是什么?
class ClassName(subClass):
pass
3.通过类创建对象的语法规则是什么?
obj = ClassName(xx,yy)
4.init方法如何定义?有什么作用?
init是在对象创建好之后被调用的,作用就是用来初始化实例变量.
5.下划线str方法的作用是什么?
决定打印对象返回的内容是什么
6.方法中的self表示什么?
就是self所在的这个方法的调用者表示的对象引用
7.修改一个对象的属性有几种方法?分别是什么
对象名打点访问属性在修改
在成员方法内部修改
8.保护属性安全性的一般处理方式是什么?
私有属性
9.要将一个属性私有化的方式是什么?
加上下划线
10.如果一个子类中没有定义init方法,但是要实例化一个子类对象,可以操作成功吗?
可以,因为init可以从父类中继承过来
11.什么叫做单继承?
只有一个父类
12.在子类中重写了init方法,如果在其内部想要调用父类的init方法,如何实现?
super()可以在子类中访问父类中指定的成员
13.定义一个类,提供可以重新设置私有属性name的方法,限制条件为name字符串的长度小于10,才可以修改
class Test():
def __init__(self,name):
self.__name = name #私有属性
def setName(self,newName):
if len(self.__name) < 10:
self.__name = newName
14.在一个对象销毁的时候,可以在什么方法中释放资源?
析构方法:del
15.简单描述什么叫做重写
子类从父类中继承到的方法满足不了子类的需求,则子类需要在父类方法原有功能基础上新增加一些操作.
16.下列代码输出什么?
class People(object):
__name = "luffy"
__age = 18
p1 = People()
print(p1.__name, p1.__age) #报错
print(p1._People__name,p1._People__age) #正确
17.下列代码输出什么?
class People(object):
def __init__(self):
print("__init__")
def __new__(cls, *args, **kwargs):
print("__new__")
return object.__new__(cls, *args, **kwargs)
p = People()
#__new__
#__init__
18.查看下列代码存在的问题
class A(object):
def __init__(self):
pass
def foo():#需要补充一个self
print('executing foo!')
@classmethod
def class_foo(self):
self.foo() #self只可以表示类名
@staticmethod
def static_foo(self):
self.foo() #self无法表示对象的引用或者类名
a = A()
19.解释下列输出结果是什么
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
print(Parent.x, Child1.x, Child2.x) #1,1,1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)#1,2,1
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)#3,2,3
20.编写程序:A继承了B,两个类中都有handle方法,在A的handle方法中调用B的handle方法
class B():
def handle(self):
pass
class A(B):
def handle(self):
super().handle()
pass
21.解释下列代码输出的结果是什么
class Father():
address = 'Beijing'
@classmethod
def getAddr1(cls):
print(cls.address)
@classmethod
def getAddr2(cls):
print(Father.address)
class Son(Father):
address = "Shanghai"
Son.getAddr1() #shanghai
Son.getAddr2() #beijing
面向对象知识点
-
创建类的语法结构
class ClassName():
pass
-
实例化对象语法结构
objName = ClassName()
#等号右侧是真实创建出来的对象,等号左侧是对象的一个引用
obj_new = objName #给当前对象添加了一个新的引用
-
实例变量:定义在init内部. 还可以在类的外部通过对象的引用动态创建
-
实例表示就是创建出来的对象(对象变量)
class Test():
def __init__(self,name,age):
self.name = name
self.age = age
test = Test()
#实例变量的访问方式
test.name = 'zhangsan' #修改实例变量的值
test.age #访问实例变量 -
还可以在类的外部通过对象的引用动态创建
class Test():
pass
test = Test()
#在动态的给test对象添加新的实例变量
test.name = 'zhangsan'
test.age = 20
-
类变量
-
定义在类的内部,方法的外部
class Test():
#类变量
address = None
classNum = 102
-
类变量本质是属于类所有的,但是实例或者对象都是由类创建的,因此类变量可以被所有的实例或者对象共享.
-
class Test():
#类变量
address = None
classNum = 102
#访问类变量(正统的方式)
Test.address = 'beijing' #通过类名访问类变量对其进行修改
Test.classNum #通过类名访问类变量
#可以通过对象的引用访问类变量 (少用)
test = Test()
test.address #对象的引用访问类变量
-
-
如何修改类变量的值
-
可以通过类名访问类变量对其进行修改
-
注意:
-
虽然通过对象的引用也可以访问类变量,但是仅仅可以访问不可以对其进行修改.why?
-
Python是一个动态语言.如果通过对象的引用访问了类变量然后对其进行修改,实际上是动态的给当前对象添加了一个新的实例变量.
-
class Test():
#类变量
address = None
classNum = 102
test = Test()
test.address = 'shanghai'
print(Test.address) #None
print(test.address) #shanghai
-
-
-
-
实例方法定义的语法结构
-
class Test():
def __init__(self):
pass
def methodName(self,xx,yy):
pass
-
-
什么是self
-
self不是python中的关键字.
-
self只可以出现在类的内部被使用.
-
self表示的就是self出现在的这个方法的调用者.
-
self表示的就是对象的一个引用.
-
-
init实例方法(构造方法):
-
作用:用来在对象被创建好之后,对对象的实例变量进行初始化操作.
-
何时被调用:不需要我们手动调用.当通过类名加括号的方式创建对象的时候,当对象创建好之后,init就会被自动调用.
-
ClassName()当这个语句执行后,表示init方法被调用
-
注意:如果init方法中除了self还有其他的参数,这些参数什么时候被赋值?ClassName(a,b,c),a,b,c就会传递给init方法中声明的其他参数!
-
class Test():
#name = zhangsan age = 20 #2
def __init__(self,name,age):
self.name = name
self.age = age
test = Test('zhangsan',20) #1
#此处动态添加的实例变量只会作用在当前对象中,不会触发在类模板中
test.school = 'xxx'
a = Test('lisi',30)
-
-
-
self使用场景
-
在实例方法内部调用其他的实例方法
-
class Test():
def __init__(self):
self.name = 'zhangsan'
def func1(self,classNum):
print('i am func1')
def func2(self):
#在func2的内部调用func1
self.func1(102)
self.name = 'lisi'
print('i am func2')
test = Test()
test.func2()
-
-
-
-
对象之间的交互
class Person():
def __init__(self,name,blood,agg_value):
self.name = name
self.blood = blood
self.agg_value = agg_value
def hitDog(self,d):
d.blood -= self.agg_value
class Dog():
def __init__(self,name,blood,agg_value):
self.name = name
self.blood = blood
self.agg_value = agg_value
def hitPerson(self,p):
p.blood -= self.agg_value
d1 = Dog('dou',100,20)
p1 = Person('li',200,40)
p1.hitDog(d1)
d1.hitPerson(p1)class Phone():
def __init__(self,color,size):
self.color = color
self.size = size
def watchMovie(self):
pass
class Person():
def __init__(self,name):
self.name = name
self.phone = Phone('red','30')
def speak(self):
pass
p = Person('lisi')
p.phone.watchMovie()
-
类方法
-
class Test():
@classmethod
#cls == Test
def classFunc(cls,xx,yy):
pass -
cls不是python中的关键字
-
cls表示的是当前类方法存在的那个类名
-
-
静态方法
-
class Test():
@staticmethod
def staticFunc(xx,yy):
pass -
在静态方法中可不可以访问类的相关成员?
-
可不可以访问实例方法和实例变量?
-
在类的一个成员方法中想要访问实例变量或者实例方法必须基于self实现,但是在静态方法中不存在self
-
-
可不可以访问类方法和类变量?
-
可以.因为可以直接通过类名访问类变量和类方法.
-
-
-
-
单继承的语法结构
-
class Test(superClass):
pass -
-
-
查看父类的哪些成员可以继承给子类
-
父类中的所有的类变量,实例变量,类方法,静态方法,实例方法都可以继承给子类.
-
-
派生
-
子类除了可以继承父类的属性和方法之外还可以生成自己独有的属性和方法.
-
如果一个子类仅仅是继承父类的成员,对于子类来讲意义不大,除非子类还派生出自己独有的属性和方法.
-
继承的初步的作用:
-
可以实现程序的复用.
-
-
-
如何在子类中调用父类中指定的成员
-
class Father():
def __init__(self,name):
self.name = name
def getName(self):
print(self.name)
def func(self):
pass
class Son(Father):
def __init__(self,age,name):
#调用父类的构造方法
super().__init__(name) -
为什么需要在子类中调用父类中的指定成员?
-
为了实现父类方法的重写
-
子类从父类中继承到的某个方法,可能满足不了子类的需求,则子类需要在继承到父类方法后,对该方法进行拓展(在原有父类方法的功能基础上新增添一些功能)
-
class Father():
def __init__(self,name):
self.name = name
#进行常规登录
def login(self):
print('常规登录操作')
class Son(Father):
#子类要进行的登录多了一个认证的功能,而这个功能是父类的login中没有实现的
def login(self):
print('新增加的认证功能')
super().login()
-
继承中相关的self和cls的区别
-
class SuperClass():
def normalFunc(self):
print(self)
@classmethod
def classFunc(cls):
print(cls)
class SubClass(SuperClass):
pass
#实例化了一个子类对象
sub = SubClass()
sub.normalFunc() #self表示就是子类对象
SubClass.classFunc() #cls表示的一定是子类类名
-
-
-
-
-
多继承的语法结构
-
class Obj(F1,F2):
pass
-
-
多父类的继承顺序
-
深度优先/深度继承
-
-
type和instance的使用
-
type:返回的是对象的直系类型
-
instance:考虑到继承的关系.一个子类对象可以被视为是父类类型.
-
-
接口类
-
接口类是作为父类存在的.接口类当做是一种协议.
-
一个子类继承了接口类之后,就表示这个子类要遵从且实现接口类这个父类中制定好的规范.
-
接口类的实现:(abc模块)
-
1.让接口类的元类为ABCMeta
-
2.在接口类中定义抽象方法
-
抽象方法是什么?
-
使用@abstractmethod装饰器装饰的方法,且该方法不可以有实现.
-
接口类对子类的规范就是由抽象方法来表示/实现
class AbsObj(ABCMeta):
@abstractmethod
def fun1(self):
pass-
注意:接口类是不可以被实例化.
-
-
-
-
-
多态
-
一个操作会返回多种状态的结果.
-
python中的多态是伪多态
-
python的语法中是没有类型检查.
class Animal():
def show_kind(self):
pass
class Dog(Animal):
def show_kind(self):
print('Dog')
class Cat(Animal):
def show_kind(self):
print('Cat')
class Train():
def show_kind(self):
print('Train')
#具有多态性质的函数
def giveAnimal(a):
a.show_kind()
c = Cat()
d = Dog()
t = Train()
gievAnimal(c)
gievAnimal(d)
gievAnimal(t)
-
-
-
类方法的作用示例
-
每创建好一个学生对象,就需要让班级总人数加一.最终我需要查看班级的总人数.
-
__new__的作用:
1.new方法是一个类方法,然后在创建对象之前被调用.(init是在创建对象之后被调用)
2.在实例方法的参数中,第一个参数必须是self,self表示的是对象,那么这个对象就是由new方法创建好且返回过来的.
2.1 new方法如何创建一个实例对象?
- 只需要在new方法中返回:
return super().__new__(cls) -
class Test():
def __init__(self):
print('i am init')
def __new__(cls, *args, **kwargs):
print('i am new')
test = Test()
#程序输出的结果只有:i am new
#分析:为什么init没有被调用?
因为我们知道,只有当对象创建好之后,init才会被调用.现在init没有被调用只能说明对象没有被创建好.
思考:为什么没有创建好对象?
因为对象的创建是由new方法实现,new需要创建好对象,然后将其返回给init的self. -
class Test():
def __init__(self):
print('i am init')
def __new__(cls, *args, **kwargs):
print('i am new')
#创建好了对象,将其返回给了init
return super().__new__(cls)
test = Test()
class Test():
def __init__(self):
print('i am init')
def __new__(cls, *args, **kwargs):
print('i am new')
#创建好了对象,将其返回给了init
return super().__new__(cls)
test = Test()
#输出的结果就正常了:
i am new
i am init -
-
class S_Class():
# 类变量
stu_counts = 0
@classmethod
def addStu(cls):
cls.stu_counts += 1
@classmethod
def showStuNum(cls):
print(cls.stu_counts)
def __new__(cls, *args, **kwargs):
S_Class.addStu()
return super().__new__(cls)
class Stu(S_Class):
def __init__(self, name):
self.name = name
s1 = Stu('zhang')
s2 = Stu('li')
S_Class.showStuNum()
-
-
私有成员:在类的内部可以访问,外部不可以被访问
-
如何创建私有成员
-
在私有成员标识符前面加入两个下划线
-
私有成员也是一个伪机制
-
_ClassName__私有成员标识符
-
-
-
私有成员继承的问题:私有成员无法被继承
-
class Father():
def __init__(self,name):
self.__name = name
def __normalFunc(self):
print('i am normalFun')
class Son(Father):
pass
s = Son('bobo')
print(s._Father__name)
s._Father__normalFunc() -
一般情况下,私有成员是不暴露给外部调用者,但是可以提供私有成员的访问机制:
-
get/set方法
-
class Father():
def __init__(self,name):
self.__name = name
def __normalFunc(self):
print('i am normalFun')
def get(self):
print('添加访问私有成员的限制')
return self.__name
def set(self,value):
print('添加访问私有成员的限制')
self.__name = value -
-
-
-
魔术成员
-
__class__
__slots__
__del__():析构方法,在对象被回收的时候被调用一次
__str__()
__getitem__()
__setitem__()
__call__() -
反射
-
hasattr
-
getattr
-
-
单例模式
-
异常处理的语法结构
-
try:
一组代码
except 某一类型的异常:
对异常的修复代码
-
-
异常类型
-
程序产生不同的错误,这些错误都被封装成了异常类
-
-
通用异常类
-
Exception:可以表示任意的异常信息
-
-
异常传播
-
try:
try:
pass
except XXX:
pass
except YYY:
pass -
-
-
精准异常捕获处理
-
try:
pass
except XXX:
pass
except YYY:
pass
-
-
finally和else子句
-
finally:try中的代码有没有发生错误,finally语句永远会执行
-
else:只有try的代码块没有发生错误执行else语句
-
-
迭代是什么
-
遍历,遍历过程的本质就是在迭代
-
-
迭代类型对象
-
可以作用在for循环中的对象.
-
如何判断一个对象是否为可迭代类型的对象
-
collections导出Iterable类,然后基于instance来鉴定对象的类型.
-
-
-
迭代器对象和其作用
-
可以被for进行遍历且可以作用在next函数中的对象.
-
-
迭代器的作用
-
节省内存
-
-
迭代器的缺点
-
只可以从前往后遍历,不能回溯
-
无法预知迭代器的长度
-
-
自定义迭代器/迭代器协议
-
iter和next方法 == 迭代器协议
-
iter方法:只会被调用一次,且直接返回自定义迭代器对象本身即可(return self)
-
next方法:在外部将迭代器对象作用在next函数中,就是在调用该对象的next方法.
-
-
生成器的创建方式
-
生成器推导式
-
-
-
迭代器和生成器的关系
-
生成器就是一个特殊的迭代器
-
-
yield关键字
-
在返回值的角度和return作用一样
-
-
装饰器
-
给函数或者方法在原有实现的基础上增添一些新的功能.
-
使用了装饰器是符合程序设计的开闭原则.
-
-