1.类的继承
(1).定义:
A. 从已有的类创建新类的过程,提供继承信息的称为父类(超类/基类),得到继承信息的称为子类(派生类).
B. 类的继承就是让一个类去拥有其他类的属性和方法的过程.
C. 继承父类除了私有以外所有的属性和方法,继承后可以在子类中添加自己独有的其他属性和方法.
(2).类继承的东西:
A. init方法
B. 除了私有的属性,其他的属性(包括类和对象)
C. getter, setter
D. 除了私有的方法,其他的方法(包括类和对象)
例如:创建一个让学生类继承人类
class Person(object): # object:基类/父类 """人类""" num = 0 def class_foo(cls): print('类方法') def static_foo(): print('静态方法') # slots魔法这个属性绑定只在当前类有效(不会被继承) __slots__ = ('name', '_age', '__person_id') def __init__(self, name, age, person_id): self.name = name #公开的 self._age = age #受保护的 self.__person_id = person_id #私有的 def age(self): return self._age setter . def age(self, age): self._age = age def run(self): print('%s跑起来了' % self.name) def __eat(self): print('%s吃了一斤肉' % self.name) # =========让Student类继承Person类========== class Student(Person): """学生类""" def foo(self): # print(self.__person_id) print('=====') # 继承除了私有的属性,其他的属性(包括类和对象) stu1 = Student('HanBo', 23, '20180008') print(stu1.name) #>>>HanBo print(stu1._age) #>>>23 # 继承除了私有的方法,其他的方法(包括类和对象) stu1.foo() #>>>===== stu1.age = 19 print(stu1.age) #>>>19 stu1.run() #>>>HanBo跑起来了 # stu1.__eat() 私有的方法不能继承 Student.num = 100 print(Student.num) #>>>100 Student.class_foo() #>>>类方法 Student.static_foo() #>>>静态方法 stu1.score = 99 print(stu1.score) #>>>99 # p1 = Person('xiaoming',90,'111111') # p1.score = 90
(3).继承方法的重写
A. 定义:将从父类中继承下来的方法在子类中重新定义.
B. 是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中 的方法。
C. 什么时候需要重写:a). 在父类方法满足不了子类的需求的时候,就可以在子类中重写这个方法.
b). 如果子类和父类中有相同的方法,子类对象会调用子类中的方法.
例如:创建一个让猫类继承动物类
class Animal(object): """动物类""" def __init__(self, name, age): self.name = name self.age = age def run(self): print('%s跑起来了' % self.name) def make_voice(self): print('%s叫' % self.__class__) def foo(self): print('aaaa') # ========让猫类继承动物类========= class Cat(Animal): """猫类""" # 注意:重写init方法的时候,要注意属性的继承问题。如果全完重写,那么父类的属性就不能继承 def __init__(self, name, age, color): super().__init__(name, age) self.color = color # super(),函数是用于调用父类(超类)的一个方法,调用父类对象的属性和方法 # super,指向的当前父类的类的属性和方法 # 这种重写是完全覆盖父类原来的实现 def make_voice(self): print('%s:喵喵~' % self.name) # 这种重写可以实现在父类的功能上添加新的功能 def foo(self): # super指向的是当前这个类的父类,super()指父类对象 super().foo() print('bbbb') # cat1 = Cat('xiaohua', 4) #>>>__init__()缺少1个需要的位置参数:“color” # cat1 = Cat('yellow') cat2 = Cat('xiaohuamao', 2, 'yellow') cat2.make_voice() #>>>xiaohuamao:喵喵~ cat2.foo() #>>>aaaa bbbb print(cat2.age) #>>>2
练习1:写一个Shape类,拥有name属性,用面积和周长两个方法; 写一个Circle类继承shape类,拥有额外的属性半径; 创建Circle对象,调用方法求面积和周长
from math import pi class Shape(object): """形状类""" def __init__(self, name): self.name = name def perimeter(self): pass def area(self): pass class Circle(Shape): def __init__(self, name, radius): # 继承父类的属性 super().__init__(name) self.radius = radius def perimeter(self): return 2 * pi * self.radius def area(self): return pi * self.radius * self.radius c1 = Circle('圆', 6) print(c1.perimeter()) #>>>37.7 print(c1.area()) #>>>113.1
2. 封装
封装 - 隐藏复杂的实现细节,暴露简单的调用接口.
(1).使用当前文件中定义的类和方法
例如以上情况:调用方法: 对象名.方法
(2).使用其他文件中的类和方法
# 方式1: import 文件名 import other >>>调用时import 其他文件名 # other.foo() >>>调用其他文件中封装的方法 # p1 = other.Person('zhangsan') >>>创建对象时 文件名.封装的类名(参数) # p1.run() # 方式2: from 文件名 import 方法名, 类名 from other import foo, Person foo() p1 = Person('xiaoming') p1.run()
(3).使用包里的某个文件中的类和方法
# 方式1: from 包名 import 文件名 from Person import student student.prin_start() stu1 = student.Student() stu1.name = '呵呵' stu1.study() # 方式2: from 包名.文件名 import 类/函数 from Person.student import Student Student()
3.多态
多态: 顾名思义就是--->有多个形态的表现。
定义: 多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
存在多态的必要条件:
a. 要有继承;
b. 要有重写;
c. 父类引用指向子类对象。
例如:创建一个小孩继承人类
class Person(object): """人类""" def __init__(self,name,sex): self.name = name self.sex = sex def print_title(self): if self.sex == "male": print("man") elif self.sex == "female": print("woman") class Child(Person): # Child 继承 Person """小孩类""" def print_title(self): if self.sex == "male": print("boy") elif self.sex == "female": print("girl") May = Child("May","female") Peter = Person("Peter","male") print(May.name,May.sex,Peter.name,Peter.sex) #>>>May female Peter male May.print_title() #>>>girl Peter.print_title() #>>>man # 总结:当子类和父类都存在相同的 print_title()方法时,子类的 print_title() 覆盖了父类的 print_title(),在代码运行时,会调用子类的 print_title(), 这样我们就获得了继承的另一个好处:多态。