面向对象三大特征
面向对象三大特征
1.什么是封装?
1.如何隐藏
__名称(类名称空间内的)
__school
2.隐藏属性发生了什么?
1. 在类定义阶段,发生了语法上的变形_类名__属性名
2. 隐藏对外不对内
3. 只有在类定义阶段发生变形,其他情况都不发生变形了
3.为何隐藏
类里面的隐藏属性, 类外部可以使用,但是目的不是让类外部使用的,类外部要是想用,在类内部开放接口进行访问
可以达到对外部数据的严格控制
4.实例
class Student(): __school = 'SH' # _Student__school => _类名__属性名 def __init__(self, name, age): self.__name = name self.age = age def __tell_info(self): # _Student__tell_info => _类名__函数名 print('name: %s, age: %s' % (self.__name, self.age)) def get_school(self): return self.__school # self._Student__school def set_school(self, v): if type(v) is not str: print('数据类型不合法') # if isinstance(v, str): return self.__school = v
class Student(): __school = 'SH' # _Student__school => _类名__属性名 def __init__(self, name, age): self.__name = name self.age = age def __tell_info(self): # _Student__tell_info => _类名__函数名 print('name: %s, age: %s' % (self.__name, self.age)) @property # 把方法伪装成属性 def name(self): return "name:%s" % self.__name @name.setter def name(self, v): if type(v) is not str: print('数据类型不合法') # if isinstance(v, str): return self.__name = v @name.deleter def name(self): print('不让删') stu = Student('ly', 18) print(stu.get_name()) stu.name = 123 print(stu.name) del stu.name
2.小练习
class Bmi(): def __init__(self, height, weight): self.height = height self.weight = weight @property def get_bmi(self): return self.weight / (self.height ** 2) bmi = Bmi(1.8, 70) print(bmi.get_bmi)
3.了解(顺序问题)
class Student(): __school = 'SH' # _Student__school => _类名__属性名 def __init__(self, name, age): self.__name = name self.age = age def __tell_info(self): # _Student__tell_info => _类名__函数名 print('name: %s, age: %s' % (self.__name, self.age)) def get_name(self): return "name:%s" % self.__name def set_name(self, v): if type(v) is not str: print('数据类型不合法') # if isinstance(v, str): return self.__name = v def del_name(self): print('不让删') # 了解 # 有顺序问题 name = property(get_name, set_name, del_name) stu = Student('ly', 18) print(stu.xxx) stu.name = 'aaa' print(stu.name)
继承(重要)
1.什么是继承?
继承:就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类
子类可以使用父类中的属性或者方法
2.为什么要用继承?
类:解决了对象与对象之间的代码冗余问题
继承:解决的是类与类之间的代码冗余问题
3.如何使用继承?
新式类:
继承了object类的子子孙孙类都是新式类
经典类:
没有继承了object类的子子孙孙类都是经典类
新式类和经典类只有在python2中区分
在python3中都是新式类
class People(): school = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender
# 学生类
class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] People.__init__(self, name, age, gender) self.courses = course def choose_course(self, course): self.courses.append(course) print('%s 选课成功 %s' % (self.name, self.courses)) stu = Student('ly', 19, 'male')
# 老师类
class Teacher(People): def __init__(self, name, age, gender, level): self.level = level People.__init__(self, name, age, gender) def score(self, stu_obj, score): stu_obj.score = score # 给学生打分 print('%s给%s打了%s分' % (self.name, stu_obj.name, score)) tea = Teacher('ly', 19, 'male', 10) print(tea.name) print(tea.level)
5.怎么查看继承的所有父类
print(类名.__bases__)
print(类名.__bases__)
6.继承的属性查找顺序
1.单继承下属性查找
class Foo: def f1(self): print('Foo.f1') def f2(self): print('Foo.f2') self.f1()
class Bar(Foo): def f1(self): print('Bar.f1') obj = Bar() # {} obj.f2()
# 练习
class Foo: def __f1(self): # _Foo__f1() print('Foo.f1') def f2(self): print('Foo.f2') self.__f1() # _Foo__f1() class Bar(Foo): def __f1(self): # _Bar__f1() print('Bar.f1') obj = Bar() # {} obj.f2()
2.
新式类:
按照广度优先查询
经典类:
按照深度优先查询
class A(object): def test(self): print('from A') class B(A): # def test(self): # print('from B') pass class C(A): # def test(self): # print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): # def test(self): # print('from E') pass class F(D, E): # def test(self): # print('from F') pass f1 = F() f1.test()
# 父类 class People(): school = 'SH' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender # 子类 class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] self.course = course # People.__init__(self, name, age, gender) # 类来调用方法,就是在电影普通方法,有几个参数就传递几个参数 # super(Student, self) 返回的是一个特殊的对象 # super(Student, self).__init__(name, age, gender) # python2中写法 super().__init__(name, age, gender) Student.mro()
mro列表
练习1
class A: def test(self): print('from A.test') super().test() class B: def test(self): print('from B') class C(A, B): pass c = C() # c.test() print(A.mro())
练习2
class B: def test(self): print('B---->test') def aaa(self): print('B---->aaa') class A: def test(self): print('A---->test') super().aaa() class C(A, B): def aaa(self): print('C----->aaa') c = A() # c.test() # 打印结果: print(A.mro())
1. 什么是多态
水:液态水,固态水,气态水
动物:人,猪,狗,猫 ...
多态:指的是一种事物的多种形态
多态中的类目的:不是用来继承父类的属性和方法的,让父类来限制子类的行为
import abc # 此类已经变为抽象类, # 抽象类只能被继承,不能被实例化 class Animal(meteclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass class People(Animal): def speak(self): pass class Pig(Animal): def speak(self): pass class Dog(Animal): def speak(self): pass obj = People() obj.speak()
2.python推荐鸭子类型
# python推荐鸭子类型 class People(): def speak(self): pass class Pig(): def speak(self): pass class Dog(): def speak(self): pass obj1 = People() obj2 = Pig() obj3 = Dog() # obj1.speak() # obj2.speak() # obj3.speak() def animal(animal): return animal.speak animal(obj1) animal(obj2) animal(obj3)
3.多态性
多态带来的特性:在不用考虑对象数据类型的情况下,直接调用对应的函数
eg:len()
def animal(animal): return animal.speak() animal(obj) animal(obj1) animal(obj2) animal(obj3)
4.父类限制子类的行为
# 父类限制子类的行为: class Animal(): def speak(self): raise Exception('必须实现speak') class People(Animal): def speak(self): pass