第九章 面向对象
python是一门弱数据类型语言
python是一门既支持面向过程又支持面向对象的一门语言
9.1 类与对象
9.1.1 类的定义、属性、方法、调用
什么是类?------- 分类的类,类别,通过分析可以得到的类别,关键字class定义的,类是一种抽象的概念,也是一类事情的总称
什么是对象? ------- 类的实例(实实在在存在的案例)
定义类:
通过class关键字去定义,类里面包含了属性(名字、性别、年龄、籍贯.........),也可以包含方法(动作 函数)
类的命名规则:遵循大驼峰法
#定义类的方式 #旧式类: class Person() #新式类:class Person(object) ----- 推荐 class Person(object): #属性 ----- 相当于全局变量 #__init__(self) 是用来初始化属性的 在构造对象(方法)的时候会被自动触发 def __init__(self): print("构造对象的时候会被触发") self.name = "张三" #self ----- this关键字 self.age = 18 self.gender = "男" def study(self): print("我非常热爱学习!!!!!") if __name__ == '__main__': print("马上即将要触发了!!!!!") p = Person() # 构造对象 print("触发了结束了!!!!!") print(p.name) print(p.age) # 调用方法 p.study() #修改属性的值 p.age += 1 print(p.age)
class Person(object): def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender def study(self): print("热爱学习") print("我是"+self.name+"非常非常特别热爱学习!!!!") #相当于tostring() def __str__(self): return "[name="+self.name+"age="+self.age+"gender="+self.gender+"]" if __name__ == '__main__': p = Person("张三","18","男") # print(p) #<__main__.Person object at 0x000001A1A17C6FD0> print(p) p.study()
定义一个圆类,求圆的面积和周长
9.2 面向对象的三大特征 -------- 封装
9.2.1 基本封装的方式
广义上:将细节封装起来,提供一个公开的、好用的方法让用户进行使用的过程
面向对象的封装:将属性和方法,封装为一个类或者多个类,通过对象去调用属性或者方法
class User(object): def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender u = User("李四","20","女") print(u.gender) print(u.name) print(u.age) u.name = "王五" #对象可以操作(修改)属性 ------ 属性的是不能在外部被修改 print(u.name)
如果不想让外部去访问(操作)属性值 ----- 私有化属性 ---- 但是内部是可以的
class User(object): def __init__(self,name,age,gender): self.__name = name self.__age = age self.__gender = gender def __str__(self): return "[name="+self.__name+"age="+self.__age+"gender="+self.__gender+"]" u = User("李四","20","女") print(u)
r如果外部也想访问?
封装:真正意义上的封装,各类的属性的封装(隐藏)起来(类的属性私有化),提供公开的get和set方法供外界去使用
class User(object): def __init__(self,name,age,gender): self.__name = name self.__age = age self.__gender = gender def __str__(self): return "[name="+self.__name+"age="+self.__age+"gender="+self.__gender+"]" #提供get方法 def get_name(self): return self.__name #提供set方法 def set_name(self,name): self.__name = name u = User("李四","20","女") print(u) print(u.get_name()) u.set_name("王五") print(u) print(u.get_name())
9.2.2 property()函数进行封装
class User(object): def __init__(self,name,age,gender): self.__name = name self.__age = age self.__gender = gender def __str__(self): return "[name="+self.__name+"age="+self.__age+"gender="+self.__gender+"]" #提供get方法 def get_name(self): return self.__name #提供set方法 def set_name(self,name): self.__name = name username = property(get_name,set_name) u = User("李四","20","女") print(u) print(u.username) u.username = "王五" print(u)
9.2.3 @property装饰器进行封装
class User(object): def __init__(self,name,age,gender): self.__name = name self.__age = age self.__gender = gender def __str__(self): return "[name="+self.__name+"age="+self.__age+"gender="+self.__gender+"]" #提供get方法 @property def name(self): return self.__name #提供set方法 @name.setter def name(self,name): self.__name = name u = User("李四","20","女") print(u) print(u.name) u.name = "王五" print(u)
9.3 面向对象的三大特征 -------- 继承
9.3.1 继承的概念
子类继承父类的属性和方法
9.3.2 python中如何实现继承
类和类之间存在的一种关系 ---- 继承关系
class User(object): -------- user继承了object类
class RichMan(object): def __init__(self): self.money = 100000000000000000000000000000000000000 self.company = "阿里叭叭叭" def tell(self): print("我对钱不感兴趣!!!!!!!") class Son(RichMan): ''' 继承了RichMan类 ''' pass if __name__ == '__main__': s = Son() print(s.money) s.tell()
子类继承父类:子类可以继承父类的属性和方法(不是所有)
继承父类的时候不是继承了所有的属性和方法,私有的属性和方法是不能被继承
class RichMan(object): def __init__(self): self.money = 100000000000000000000000000000000000000 self.company = "阿里叭叭叭" self.__house = "北京别墅" def tell(self): print("我对钱不感兴趣!!!!!!!") def __str__(self): return "house = " +self.__house class Son(RichMan): ''' 继承了RichMan类 ''' def __str__(self): return "house = " + self.__house if __name__ == '__main__': s = Son() print(s.money) s.tell() print(s)
9.3.3 方法的重写(覆盖)、重载
继承也可以进行重写方法
方法的重写(覆盖 override):在继承的基础之上,如果子类继承了父类的方法但是不能满足自己使用的时候,我们可以进行方法的重写
class RichMan(object): def __init__(self): self.money = 100000000000000000000000000000000000000 self.company = "阿里叭叭叭" self.__house = "北京别墅" def tell(self): print("我对钱不感兴趣!!!!!!!") def __str__(self): return "house = " +self.__house def __speak_english(self): print("可以非常流程的说英文") def working(self): print("认为A员工的工作非常的认真!!!") class Son(RichMan): ''' 继承了RichMan类 ''' #方法的重写 def working(self): print("认为B员工工作比较认真") if __name__ == '__main__': s = Son() print(s.money) s.tell() print(s) s.working()
注意:重写方法的时候方法名称和方法的参数必须保持一致(跟父类),并不是覆盖了父类的方法
面试题:python中有函数的重载吗?有方法的重写吗?
结论:python中是有方法的重写,并没有方法(函数)的重载
重写:方法的名称参数的个数和类型都相同
重载(overload):函数的名称相同,但是参数的个数或者类型不同
但是可以通过某些特殊的方法去实现方法的重载(装饰器)
总结:继承的本质就是为了实现代码的复用
python可以不可以实现多继承?支持多继承 class Son(RichMan,object,.........)
问题:那么如果现在A类继承了B和C,B和C分别有一个H(),那么请问A继承的是B中H还是A中的H?
class B(object): def H(self): print("这是B中的H") class C(object): def H(self): print("这是C中的H") class A(C,B): pass a = A() a.H()
python3中继承是按照继承的顺序来找的(就近原则 广度优先)
9.3.4 super关键字
super关键字:相当于一个指针,默认指向的是父类
self关键字:相当于一个指针,默认指向的是自己本身
class RichMan(object): def __init__(self): self.money = 100000000000000000000000000000000000000 self.company = "阿里叭叭叭" self.__house = "北京别墅" def tell(self): print("我对钱不感兴趣!!!!!!!") def __str__(self): return "house = " +self.__house def __speak_english(self): print("可以非常流程的说英文") def working(self): print("认为A员工的工作非常的认真!!!") class Son(RichMan): ''' 继承了RichMan类 ''' #方法的重写 def working(self): print("认为B员工工作比较认真") def test(self): self.working() #指向的是自己的working() super().working() #super指向的是父类 如果有参数必须传入参数 if __name__ == '__main__': s = Son() s.test()
9.4 面向对象的三大特征 -------- 多态
多态:指的是对象的多种形态,多态是在继承的基础之上而言,父类的引用指向子类的实例的这种现象叫做多态
ArrayList a1 = new ArrayList() List ls = new ArrayList()
python是一门弱数据类型语言,声明变量的时候不用声明变量类型(数据类型)(python中多态不是特别重要),天生就支持多态。