在使用面向对象编程时,要先考虑要什么对象,而这个对象要具备咋样的属性与行为,再根据属性与行为创建对应的类.
类属性与对象属性
一)属性应该放入类中还是对象
1.类中存储的是所有对象共有的内容每
2.对象中只是存储每个对象独有的内容
__init__方法的作用
init是初始化的缩写 ,是给对象的属性设置初始值的
特点:1,执行时机:当实例化产生对象时会自动执行该函数
2. 会自动传入需要初始化的值
3.初始化必须包含至少一个参数 ,表示对象本身
4.该函数不允许有返回值
绑定方法:== 绑定函数 :是把函数与对象绑定到一块
why 绑定:因为每个程序的本质都是在处理函数,所以要明确 数据在哪 怎么处理
优点: 将要处理的数据与处理数据的方法绑定到一起后, 你获得一个对象时就会同时获得他的数据以及相应的处理方法,这样直接调用就行了啦
默认情况下,在类中定义的方法 都是绑定方法
绑定给谁: 当你的方法在执行过程中需要使用到对象中的数据是 绑定给对象,当你的方法在执行过程中需要使用到泪中的数据时 绑定给类
方法 一 绑定方法
1.1 对象绑定方法
在使用对象调用时会自动传入对象本身 类调用时不会自动传入函数,有几个就需要传几个
1.2类绑定方法: @ slassmethod
不仅在使用对象调用时会传入类本身;而且在使用用类调用时也会自动传入类本身,通常单例模式中常使用 @ slassmethod
方法 二 非绑定方法 @staticmethod在使用
既不需要对象中的数据,也不需要类中的数据, 就定义为非绑定方法 他就是一种普通函数 谁调用时都不会自动传参
继承 : 要使用 继承 至少要两个类
现实中:继承指的是一种关系,继承者可以通过继承关系 继承被继承者所拥有的一切。继承者为子,被继承者为父
oop中:是类和类之间的关系 eg:a继承b a能直接使用b类中的属性和方法
b是父类(基类,超类) a 是子类(派生类)b
优点:极大地提高了代码的复用性
```python class Teacher: school = "oldboy" def __init__(self,name,age): self.name = name self.age = age def say_hi(self): print("hello i am %s" % self.name) def teach(self): print("正在教书......") class Student(Teacher): pass print(Student.school) print(Student.say_hi) print(Teacher.say_hi) s = Student("rose","123") s.say_hi() s.teach()
在上述案例中通过继承 学生就拥有了老师的所有内容 但是学生不应该有教书这个技能意味着这个继承关系 有问题 不合理所以要需要先抽象 在继承
抽象与继承
抽象:是将一系列类中相同特征和相同行为抽取,形成一个新的类,会产生一些与原本业务不相关的类 在不同的角度会产生不同的抽象结果
因为继承之后可以直接使用父类的属性与方法,所以说如果继承关系不合理就没意义了,所以继承时要先抽象,在继承。
# 抽象得到的公共父类 class OldBoyPerson: school = "oldboy" def __init__(self,name,age): self.name = name self.age = age def say_hi(self): print("hello i am %s" % self.name) class Teacher(OldBoyPerson): def teach(self): print("正在教书......") class Student(OldBoyPerson): pass # 测试 t = Teacher("owen",38) t.say_hi() t.teach() s = Student("歌王",20) s.say_hi()
在py3 中,任何类都直接或间接继承自object,object是所有类的基类,
在py中,万物皆对象是说:在py中所使用的任何数据都是对象 int float list dict 模块 包 函数
属性的查找顺序: 对象自己 >所在的类>所在类的父类>父类的父类>object
class A: name = "scot" # def __str__(self): # print("111111111") # pass pass class B(A): name = "rose" pass b = B() # b.name = "jack" print(b.name)
派生与覆盖
派生:子类有于父类不同的内容 就成为派生
覆盖;子类出现了与父类完全相同的名称,根据查找顺序 会优先找子类,就会覆盖了父类的内容
class Person: text = "321" def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def sleep(self): print("人类 午睡 躺着睡!") def say_hi(self): print("my name :%s my age :%s my gender: %s " % (self.name,self.age,self.gender),end="") class Student(Person): text = "123" def __init__(self,name,age,gender,number): #======================================================================重点在这里 # 由于父类已经存在一个方法可以完成这个三参数的初始化 # 所以可以直接调用父类的初始化完成这部分的初始化工作 # 方法1 # Person.__init__(self,name,age,gender) # 指名道姓的调用 # 方法2 在py2中不支持 super().__init__(name,age,gender) # py2的写法 # super(Student, self).__init__(name,age,gender) self.number = number #====================================================================== # 访问父类的属性 def show_text(self): print(self.text) print(super().text) def say_hi(self): super().say_hi() print("my number: %s" % self.number) # print("my name :%s my age :%s my gender: %s my number: %s" % (self.name, self.age, self.gender,self.number)) s = Student("jack",20,"man","007") s.say_hi() # s.show_text()