面向对象
目录- 动静态方法
- 面向对象之继承的概念
- 面向对象之继承本质
- 面向对象之名字查找顺序
- 面向对象之经典类与新式类
- 面向对象之派生方法
动静态方法
1.绑定给对象的方法
'''
类中直接定义函数 默认绑定给对象 类调用有几个参数传几个 对象调用第一个参数就是对象自身
'''
class Student:
school_name = '摆烂大学'
def func1(self):
print('看谁最能摆烂 真的好棒棒!!!')
obj = Student()
obj.func1()
Student.func1(123)
2.绑定给类的方法
'''
被@classmethod修饰的函数 默认绑定给类 类调用第一个参数就是类自身
对象也可以调用并且会自动将产生该对象的类当做第一个参数传入
'''
class Student:
school_name = '摆烂大学'
@classmethod
def fun2(cls):
print('嘿嘿嘿 猜猜我是干嘛的',cls)
Student.func2() # fun2(Student)
obj.func2() # func2(Student)
3.调用静态方法
'''
不管是用类调用还是对象调用,有几个形参就调几个实参 都必须自己手动传参
'''
class Student:
school_name = '摆烂大学'
@staticmethod
def func3(a):
print('哈哈哈, 猜猜我又是干什么的', a)
Student.func3(123)
obj.func3(321)
面向对象之继承的概念
面向对象三大特性分别是:继承(核心 实操最多 体验最强) 、封装、 多态
1.继承的含义
现实中:用来描述人与人直接资源的关系
eg:儿子继承父亲的财产,拥有了父亲所有的资源
编程中:用来描述类与类之间数据的关系
eg:类A继承类B,类A可以使用类B所有的数据和功能
2.继承的目的
在现实生活中儿子继承父亲就拥有了父亲所有资源的支配权限
在编程世界中类A继承类B就拥有了类B中所有的数据和方法使用权限
3.继承的实操
结构语法:
class 类名(继承的父类)
pass
1.定义类的时候在类名后加括号
2.括号内填写你需要继承的类名
3.括号内可以填写多个父类 逗号隔开即可
我们将被继承的类称之为: 父类或基类或超类
我们将继承类的类称之为: 子类或派生类
ps:平时最常用的就是父类和子类
class Father:
money = 100000000000000
def run(self):
print('几百万的豪车')
class Son(Father):
pass
print(Son.money) # 100000000000000
class F1:
name = 'from f1'
class F2:
name = 'from f2'
class F3:
name = 'from f3'
class MyClass(F1,F2,F3):
pass
面向对象之继承的本质
1.什么时候可以用继承
就是当两个类里面代码重复时,可以用继承,为了是减少代码
2.使用继承
class Teacher:
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def teach_course(self):
print('老师正在手舞足蹈的讲课')
class Student(Teacher):
# def __init__(self,name,age,gender):
# self.name = name
# self.age = age
# self.gender = gender
def teach_course(self):
print('同学们正在打瞌睡,昨晚又去做贼了')
# stu1 = Student() # TypeError: __init__() missing 3 required positional arguments: 'name', 'age', and 'gender'
'''
在有__init__的时候(不论是直接有还是间接有),这个类在加括号的时候都会自动出发这个方法然后运行,那么在这个时候就要必须传入设置的形参
'''
stu1 = Student('kerry', 18, 'famale')
print(stu1) # <__main__.Student object at 0x00000140514B3A60>
print(stu1.__dict__) # {'name': 'kerry', 'age': 18, 'gender': 'famale'}
将多个类共同的数据或功能抽取出来形成一个父类
继承的关系
"""
对象:数据与功能的结合体
类(子类):多个对象相同数据和功能的结合体
父类:多个类(子类)相同数据和功能结合体
ps:类与父类本质都是为了节省代码
"""
继承本质应该分为两部分
抽象:将多个类相同的东西抽出去形成一个新的类
继承:将多个类继承刚刚抽取出来的新的类
ps:一定要掌握继承的本质 这样以后你才会在代码中自己定义出子类父类
面向对象之名字查找顺序
1.不继承情况下名字的查找顺序
class C1:
name = 'jason'
def func(self):
print('from func')
obj = C1()
# print(C1.name) # 类肯定找的自己的
obj.name = '你迷了吗' # 由于对象原本没有name属性 该语法会在对象名称空间中创建一个新的'键值对'
print(obj.__dict__)
print(obj.name) # 你迷了吗
print(C1.name)
"""
对象查找名字的顺序
1.先从自己的名称空间中查找
2.自己没有再去产生该对象的类中查找
3.如果类中也没有 那么直接报错
对象自身 >>> 产生对象的类
"""
2.单继承情况下名字的查找顺序
class A1:
def func1(self):
print('from A1 func1')
def func2(self):
print('from A1 func2')
self.func1()
class B1(A1):
def func1(self):
print('from B1 func1')
obj = B1()
obj.func2()
"""
查找的顺序:
对象自身 >>> 产生对象的类 >>> 父类
强调:对象点名字 永远从对象自身开始一步步查找
以后在看到self.名字的时候 一定要搞清楚self指代的是哪个对象
"""
class F3:
# name = 'jerry'
pass
class F2(F3):
# name = 'tony'
pass
class F1(F2):
# name = 'jason'
pass
class S1(F1):
# name = 'kevin'
pass
obj1 = S1()
obj1.name = '嘿嘿嘿'
print(obj1.name)
'''
和上面一样的查找的顺序一样都是:
对象自身 >>> 产生对象的类 >>> 父类
'''
3.多继承情况下名字的查找顺序
'''多继承的情况下名字的查找顺序'''
菱形继承
广度优先(最后才会找闭环的定点)
非菱形继承
深度优先(从左往右每条道走完为止)
ps:mro()方法可以直接获取名字的查找顺序
3.1非菱形继承
''' 对象自身 >>> 产生对象的类 >>> 父类(从左往右)'''
class G:
name = 'from G'
pass
class A:
# name = 'from A'
pass
class B:
# name = 'from B'
pass
class C:
# name = 'from C'
pass
class D(A):
# name = 'from D'
pass
class E(B):
# name = 'from E'
pass
class F(C):
# name = 'from F'
pass
class S1(D,E,F):
pass
obj = S1()
# print(obj.name)
print(S1.mro())
3.2菱形继承
''' 对象自身 >>> 产生对象的类 >>> 父类(从左往右)'''
class G:
name = 'from G'
pass
class A(G):
# name = 'from A'
pass
class B(G):
# name = 'from B'
pass
class C(G):
# name = 'from C'
pass
class D(A):
# name = 'from D'
pass
class E(B):
# name = 'from E'
pass
class F(C):
# name = 'from F'
pass
class S1(D,E,F):
pass
obj = S1()
# print(obj.name)
print(S1.mro())
面向对象之经典类与新式类
__bases__:查看当前这个类继承了哪些父类,只会看到第一层级的类
__base__:拿一个
经典类
不继承object或其子类的类(什么都不继承)
新式类
继承了object或其子类的类
"""
在python3中所有的类默认都会继承object
也就意味着python3里面只有新式类
在python2中有经典类和新式类
由于经典类没有核心的功能 所以到了python3直接砍掉了
以后我们在定义类的时候 如果没有想要继承的父类 一般推荐以下写法
class MyClass(object):
pass
目的是为了兼容python2
"""
以后写代码针对object无需关心 知道它的存在即可
面向对象之派生方法
子类中定义类与父类一模一样的方法并且扩展了该功能称之为派生
用别人的方法,但是不够用,想基于别人的方法进行扩展
代码如下:
class Person:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(Person):
def __init__(self, name, age, gender, sid):
super().__init__(name, age, gender) # 子类调用父类的方法
self.sid = sid
class Teacher(Person):
def __init__(self, name, age, gender, level):
super().__init__(name, age, gender)
self.level = level
stu1 = Student('jason', 18, 'male', 666)
print(stu1.__dict__)
tea1 = Teacher('tony', 28, 'female', 99)
print(tea1.__dict__)
class MyList(list):
def append(self, values):
if values == 'jason':
print('jason不能尾部追加')
return
super().append(values)
obj = MyList()
print(obj, type(obj))
obj.append(111)
obj.append(222)
obj.append(333)
obj.append('jason')
print(obj)
标签:__,name,self,面向对象,pass,print,class
From: https://www.cnblogs.com/zjl248/p/16855497.html