Python面对对象重要知识点
类名必须采用驼峰体
类在运行阶段会运行类体代码(不包括类中的方法,因为方法属于函数),函数在定义阶段只检查语法错误
0.属性的查找顺序
先对象本身-->类-->父类-->父类的父类
1.self
在类中,敲函数时会自动填入参数self,它只作用在实例化对象(生成对象)的时候,self代表的就是那个对象。
所以对象实例化时不需要手动传参self,但类调用__init__时需要传入一个self参数,因为只有在实例化过程中self才是默认自动的
python
class People():
def __init__(self, name, age):
self.name = name
self.age = age
def running(self):
print('i am running')
People.__init__(111,'xiaoming',15) #需要给self传一个参进去
stu=People('xiaoming',15) #无需传参self,self默认就是stu
print(stu.name)
2.只有在类中定义__init__函数,实例化对象时,在对象的__dict__才能打印出属性
实例化对象的过程中,类中的__init__函数会自动执行
3.类的继承和派生
(1)继承:直接在子类的括号中添上父类就完成了继承,但继承最好少用,实在要用继承也最多继承一个父类,不然容易因为多种继承出现逻辑上的混乱
python
class Foo:
def __init__(self,gender,age):
self.gender=gender
self.age=age
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
name='xiaoya'
def f1(self):
print('Bar.f1')
(2)派生:子类中新定义的属性的这个过程叫做派生,并且需要记住子类在使用派生的属性时始终以自己的为准
python
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex, stu_id):
super().__init__(name, age, sex)
self.stu_id = stu_id
def choose_course(self):
print('%s is choosing course' % self.name)
stu1 = OldboyStudent('tank', 19, 'male', 12)
print(stu1.__dict__)
4.类的组合
组合的本质就是把对象当做变量值/函数的形参/函数的实参/函数的返回值来用;
下面是简简单单的举例:(非常非常简易的学生选课系统)
python
class People:
def __init__(self, name, gender):
self.name = name
self.gender = gender
def eat(self):
print('i am eating')
class Student(People):
def __init__(self, student_id, name, gender):
super().__init__(name, gender)
self.student_id = student_id
def choose(self,course):
self.course=course
print(f"{self.name}选课{course.name}")
class Teacher(People):
def __init__(self, level, name, gender):
super().__init__(name, gender)
self.level = level
def score(self, student, course, score):
print(f'{self.name}给{student.name}课程{course.name}打分{score}')
class Admin(People):
def create_course(self, name,price):
course=Course(name,price)
print(f"管理员{self.name}创建了课程{name}")
return course
class Course():
def __init__(self,name,price):
self.name=name
self.price=price
# 类的组合
#学生
xiaoming=Student('01','xiaoming','male')
lili=Student('02','lili','male')
#老师
wang_teacher=Teacher('1','wanggang','male')
zhang_teacher=Teacher('2','zhangli','female')
#管理员
li_monitor=Admin('li_monitor','female')
#业务逻辑
#1.管理员创建课程
python=li_monitor.create_course('python',8888)
linux=li_monitor.create_course('linux',6666)
# print(type(linux))
#2.学生选择课程
xiaoming.choose(python)
lili.choose(linux)
#3.老师给学生打分
wang_teacher.score(xiaoming,python,80)
5.菱形继承问题
(1)经典类和新式类
经典类:没有继承object的类以及该类的子类,都是经典类;只有python2中才有经典类
新式类:继承了object的类以及该类的子类,都是新式类;Python3中的所有类都是新式类
(2)菱形继承面试考点:
如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种:
(1)经典类按照深度优先查找继承
(2)新式类按照广度优先查找继承
6.封装
封装分为两种:
(1)对象拿到类的东西,但是类拿不到对象的东西,这种就是最基本的实例化
(2)在类的内部可以使用,但在外部不能使用,这种封装只需要在属性或方法名前加__
python
class People():
__lashi='lashi' #这个属性是People内部的,只能内部使用
def __init__(self,name,age,bra_value):
self.name=name
self.age=age
self.__bra_value=bra_value #这里的bra_value参数是实例化对象self独有的
def __eat(self): #这个方法只能在类内部被调用
print('i am eating')
def chifan(self):
__eat() #这个方法只能在类内部被调用
p=People('lili',18,30)
print(p.__bra_value) #在外部使用会报错
7.类的property属性
property装饰器用于将类中被装饰的方法伪装成一个属性,在使用时可以不用加括号而直接调用该方法
python
class People():
def __init__(self, name, gender):
self.name = name
self.gender = gender
@property
def eat(self):
print("i am eating")
p = People('lili', 18)
p.eat #i am eating
8.绑定方法和非绑定方法
(1)绑定到类的方法用装饰器:@classmethod
python
class Foo:
def __init__(self,name,gender):
self.name=name
self.gender=gender
@classmethod #绑定装饰器,也就是这个函数的参数是类,而不是通俗的对象
def eat(cls):
print(cls)
print('i am eating')
(2)非绑定方法
在类内部使用 @staticmethod 修饰,这类方法和普通定义的函数没有区别,不与类或对象绑定,二者都可以调用,且没有自动传值效果
9.isinstance和issubclass
isinstance()用来取代type()
issubclass()用来判断某个类是否为另一个类的子类
python
#isinstance()
class Foo:
def __init__(self,name,gender):
self.name=name
self.gender=gender
class Bar(Foo):
def eat(self):
print("i am eating")
b=Bar('lili','male')
print(isinstance(b,Bar)) #True
print(isinstance(b,Foo)) #True
##############################
#type和isinstance的区别:
#(1)type获取实例化出对象的类,**但是不会检测父类**
#(2)isinstance判断对象是否为这个类实例化出来的,**会检测父类**
#issubclass()
class Foo:
def __init__(self,name,gender):
self.name=name
self.gender=gender
class Bar(Foo):
def eat(self):
print("i am eating")
print(issubclass(Bar,Foo)) #True