python面向对象 - 23 三大支柱 - 继承 / 封装 / 多态

面相对象的三大支柱 - 继承 / 封装 / 多态

1.类的继承

(1).定义:

    A. 从已有的类创建新类的过程,提供继承信息的称为父类(超类/基类),得到继承信息的称为子类(派生类).

   B. 类的继承就是让一个类去拥有其他类的属性和方法的过程.

C. 继承父类除了私有以外所有的属性和方法,继承后可以在子类中添加自己独有的其他属性和方法.

(2).类继承的东西:

A. init方法

B. 除了私有的属性,其他的属性(包括类和对象)

C. getter, setter

D. 除了私有的方法,其他的方法(包括类和对象)

例如:创建一个让学生类继承人类

class Person(object):  # object:基类/父类
    """人类"""

    num = 0

    @classmethod
    def class_foo(cls):
        print('类方法')

    @staticmethod
    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  #私有的

    @property
    def age(self):
        return self._age

    @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(), 这样我们就获得了继承的另一个好处:多态。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值