本节内容

1、概述

2、类的继承

3、总结

4、练习

一、概述

  之前我们说到了类的公有属性和类的私有属性,其实就是类的封装,下面我们来讲讲继承,是面向对象的第二大特性。

  面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

  通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

  继承概念的实现方式主要有2类:实现继承、接口继承。

  1. 实现继承是指使用基类的属性和方法而无需额外编码的能力。
  2. 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。

  在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

  抽象类仅定义将由子类创建的一般属性和方法,OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段

二、类的继承

2.1 继承的定义

说明:在类名的括号中写入需要继承的类名即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person(object):
 
    def talk(self):
        print("person is talking...")
 
class BlackPerson(Person):  #继承Person这个类
 
    def walk(self):  #定义子类自身的walk方法
        print("BlackPerson is walking.....")
 
 
= BlackPerson()
b.talk()   #由于继承了父类的talk()方法,所以可以被调用
b.walk()  #调用子类自身的walk方法
 
#输出
person is talking...
BlackPerson is walking.....

2.2、构造方法的继承

说明:因为子类有自己的属性,但是又想继承父类的属性,所以需要先继承,再重构

继承类的构造方法2种写法:

  1. 经典类写法:父类.__init(self,name,age)
  2. 新式类写法:super(子类,self).__init__(name,age)

注:建议使用新式类的写法,因为使用经典类的写法,在多继承的情况下,会出现重复调用参数的可能

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.sex = "noraml"
 
    def talk(self):
        print("person is talking...")
 
class BlackPerson(Person):
    def __init__(self,name,age,strength):  #定义时需要传入父类的属性名
        Person.__init__(self,name,age)  #继承父类的构造方法,也可以写成:super(BlackPerson,self).__init__(name,age)
        self.strength = strength   #定义子类本身的属性
        print(self.name,self.age,self.sex)
 
    def walk(self):
        print("BlackPerson is walking.....")
 
= BlackPerson("xiaogao",18,"strong")
 
#输出
xiaogao 18 noraml

这边不禁的有一个疑问?我不能重新写一遍,我为啥要继承父类中的方法呢?因为你重新写一遍的话,只能继承self.name和self.age,那self.sex怎么办,它也需要重写吗?所以啊,只有把父类中的构造函数全部继承过来,只能用上面这种办法?那它是怎么实现的呢?我们来画一个图:

2.3、子类对父类方法的重写

说明:如果我对父类中的方法不满意,我可以重写父类中的方法,当然还可以继承父类中的方法,但是我们一般不这样干。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
        self.sex = "noraml"
 
    def talk(self):
        print("person is talking...")
 
class BlackPerson(Person):
 
    def talk(self):  #重写父类的方法
        Person.talk(self)  #调用父类的方法
        print("BlackPerson is talking ...")
 
    def walk(self):
        print("BlackPerson is walking.....")
 
= BlackPerson("xiaogao",18)  #子类不写,则继承父类的构造方法
b.talk()
b.walk()
 
#输出
person is talking...
BlackPerson is talking ...
BlackPerson is walking.....

其实重写不是上面说的那么简单,只需要子类的方法名和父类的中的方法名一样就算重写了,其实不然,那怎么样才算重写呢?

重写的条件:

  1. 重写方法的方法名必须和父类中被重写的方法名一模一样
  2. 重写方法的传入的参数名和参数的个数必须和父类中被重写的方法一样

我们再来看看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person(object):
 
    def talk(self,food):
        print("person is talking...{0}".format(food))
 
class BlackPerson(Person):
 
    def talk(self):  #方法名和父类的方法名一样,但是少了一个food参数
        print("BlackPerson is talking ...")
 
= BlackPerson("xiaogao",18,"strong")
b.talk()
 
#输出
BlackPerson is talking ...

有些同学说,这明明是重写了呀!其实不是重写,根据重写的条件明显两个方法的传入参数名和参数的个数都不一样,其实上面这种只是子类自己写了一个talk方法,只是名字一样,但是传入的参数和参数的个数不一样,并不是重写了父类中的方法。下面这个才是真正的重写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person(object):
 
    def talk(self,food):
        print("person is talking...{0}".format(food))
 
class BlackPerson(Person):
 
    def talk(self,food):  #重写父类的方法(方法名和传入的参数名以及参数的个数与父类的方法一样)
        print("BlackPerson is talking ...{0}".format(food))
 
= BlackPerson("xiaogao",18,"strong")
b.talk("hotdog")
 
#输出
BlackPerson is talking ...hotdog

三、练习

3.1 类的继承练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
class SchoolMember(object):
    '''学校成员基类'''
 
    member = 0  #设置类属性
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex =sex
        self.enroll()  #每次生成一个对象注册一次
    def enroll(self):
        "注册"
        print("just enroll a new school member [{0}]".format(self.name))
        SchoolMember.member += 1
 
    def tell(self):
        print("------info:{0}-----".format(self.name))
        for k,v in self.__dict__.items():  #__dict__()函数是获取对象的属性,以字典的形式返回
            print("\t",k,v)
        print("------end--------")
 
    def __del__(self):
        print("开除了[{0}]...".format(self.name))
        SchoolMember.member -= 1
 
class Teacher(SchoolMember):
    "讲师类"
 
    def __init__(self,name,age,sex,salary,course):
        SchoolMember.__init__(self,name,age,sex)
        self.salary = salary
        self.course = course
 
    def teaching(self):
        "讲课方法"
        print("Teacher [{0}] is teaching [{1}]".format(self.name,self.course))
 
class Student(SchoolMember):
    "学生类"
    def __init__(self,name,age,sex,couser,tuition):
        SchoolMember.__init__(self,name,age,sex)
        self.couser = couser
        self.tuition = tuition
        self.amount = 0
 
    def pay_tuition(self,amount):
        print("student [{0}] has just paied [{1}]".format(self.name,amount))
        self.amount += amount
 
t1 = Teacher("xiaogao",18,"F*M",3000,"Python")
s1 = Student("shuaigao",19,"M","PYS15",300000)
s2 = Student("gaogao",12,"M","PYS15",11000)
 
print(SchoolMember.member)
del s1  #删除一个变量
t1.tell()
s2.tell()
print(SchoolMember.member) #会执行__del__函数
 
#输出
just enroll a new school member [xiaogao]
just enroll a new school member [shuaigao]
just enroll a new school member [gaogao]
3
开除了[shuaigao]...
------info:xiaogao-----
     salary 3000
     sex F*M
     course Python
     name xiaogao
     age 18
------end--------
------info:gaogao-----
     couser PYS15
     sex M
     name gaogao
     amount 0
     tuition 11000
     age 12
------end--------
2
开除了[gaogao]...
开除了[xiaogao]...

面向对象【day07】:类的继承(七)的更多相关文章

  1. Java面向对象-Java类的继承及super关键字

    Java面向对象-Java类的继承 1,继承定义以及基本使用 定义:子类能够继承父类的属性和方法: 注意点:Java中只支持单继承: 私有方法不能继承: 上代码: package com.java12 ...

  2. php面向对象:类的继承实例讲解

    什么是类的继承?说白了,我觉得就是提高代码使用效率的.下面我就给大家介绍下继承.大理石平台维修 类的继承概念 子类继承父类的所有成员变量个方法,包括构造方法,当子类被实例化时,php会现在子类中查询构 ...

  3. python面向对象-4类的继承与方法的重载

    1.类的继承与方法的重载 上面就是先定义了一个类A,然后由定义了一个类B,B继承了类A,这样B就有了A的非私有属性和方法. class Washer: company='ZBL' def __init ...

  4. python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法

    对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...

  5. python-day6面向对象、类的继承

    @面向对象三大特性:封装encapsulation.继承inheritance.多态(一个接口,多个实现)polymorphism. @面向对象介绍http://www.cnblogs.com/ale ...

  6. Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...

  7. 【Python】面向对象:类与继承简单示例

    Python 面向对象 Python 是一门面向对象的设计语言,与此对应的就是面向过程编程与函数式编程 面向对象的一个优点就是更好的增强代码的重用性. 面向过程编程可以简单的理解为:重点在步骤,将一个 ...

  8. JavaScript 类式继承与原型继承

    交叉着写Java和Javascript都有2年多了,今天来总结下自己所了解的Javascript类与继承. Javascript本身没有类似Java的面向对象的类与继承术语,但其基于原型对象的思想却可 ...

  9. Lua面向对象----类、继承、多继承、单例的实现

    (本文转载)学习之用,侵权立删! 原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...

随机推荐

  1. BugPhobia进阶篇章:功能规格说明书

    0x01 :特别鸣谢 首先特别鸣谢<构建之法>中并没有给出固定化格式的功能规格说明书的样例,因此在此次的说明书中将尽可能用生动形象的例子展示软件交互阐释 因此受到它本身的启发,此次团队功能 ...

  2. java面对对象(六)--内部类、匿名内部类

    内部类 可以在一个类的内部定义另一个类这种类成为内部类或嵌套类,比如: class Outer{ … class Inner{ …. } } class Outer1{} // 这个Inner1不是O ...

  3. 『编程题全队』Beta 阶段用户使用调查报告

    目录 一.项目概述 1.1项目名称 1.2项目简介 1.3项目预期达到目标 1.4项目测试方法 二.项目测试过程 2.1测试对象 2.2测试时长 2.3用户测试反馈 一.项目概述 1.1项目名称 本次 ...

  4. Golang的panic和recover

    panic 关键字panic的作用是制造一次宕机,宕机就代表程序运行终止,但是已经“生效”的延迟函数仍会执行(即已经压入栈的defer延迟函数,panic之前的). 为什么要制造宕机呢?是因为宕机不容 ...

  5. CentOS7 完整安装后创建私有的yum仓库

    1. 安装 CentOS7 安装的包比较全,应用可以直接用. 2. 第一步创建 yum 包的存放路径 mkdir -p /var/www/html/ 3. 创建私有仓库 createrepo -v / ...

  6. 数组 this.setData快捷赋值

    let list=this.data.list; let listString = `{"list[${index}].sliderSure":${!list[index].sli ...

  7. ubuntu更改分辨率

    1. 输入:$cvt 1920 1080 2 输入: $xrandr 3 输入: $sudo xrandr --newmode "1920x1080_60.00" 173.00 1 ...

  8. VMware虚拟机看不到共享目录

    1. 确认VMtools已经装好,开启共享文件夹,设置好共享目录 2.执行命令 sudo mount -t vmhgfs .host:/ /mnt/hgfs如果出现错误: Error: cannot ...

  9. BZOJ2004 HNOI2010公交线路(状压dp+矩阵快速幂)

    由数据范围容易想到矩阵快速幂和状压. 显然若要满足一辆公交车的相邻站台差不超过p,则每相邻p个站台中每辆车至少经过一个站台.可以发现这既是必要的,也是充分的. 开始的时候所有车是相邻的.考虑每次把一辆 ...

  10. LOJ6387 [THUPC2018] 绿绿与串串 【manacher】

    题目分析: 比较简单,先跑一边manacher,然后对于回文部分可以碰到末尾的一定满足条件,否则向后转移. 代码: #include<bits/stdc++.h> using namesp ...