精华内容
下载资源
问答
  • 我们用两部分来写写Python的继承,分为单继承和多继承。在《流畅的Python》11和12章介绍了协议和抽象基类,以及继承的优点缺点,抽象基类这块真的很抽象…我觉得自己能看懂,却真的写不出来啥,乱写一通没有啥意思,...

    我们用两部分来写写Python的继承,分为单继承和多继承。在《流畅的Python》11和12章介绍了协议和抽象基类,以及继承的优点缺点,抽象基类这块真的很抽象…我觉得自己能看懂,却真的写不出来啥,乱写一通没有啥意思,我实在是写不好。我们就来写写继承好了,以及Python继承的一些调用方式。

    第一部分,单继承

    和C++的继承一样,子类可以继承父类的方法,我们从一个简单的例子说起

    class A():

    def fun(self):

    print('A class fun here')

    class B(A):

    pass

    b = B()

    b.fun()

    '''输出

    A class fun here

    '''

    就和我们预想的一样,虽然B类中没有fun()函数,但是因为B继承自A,所以可以调用A的fun()函数。那么如果我们在B里也定义fun()函数呢?

    class B(A):

    def fun(self):

    print('B class fun here')

    b = B()

    b.fun()

    '''输出

    B class fun here

    '''

    这样情况下将会优先调用子类的对应函数。但是我们仍然可以显示的去执行父类的函数,比如这样

    class A():

    def fun(self):

    print('A class fun here')

    class B(A):

    def fun(self):

    #这两种写法都是可以的

    super().fun()

    #super(B,self).fun()

    b = B()

    b.fun()

    '''输出

    A class fun here

    '''

    利用super()函数,我们可以选择调用父类的函数,很多时候我们都需要在子类的初始化函数中调用父类的初始化函数__init__()

    第二部分,多重继承

    结合单继承的几个例子,我们看看Python多继承是如何执行的

    class A():

    def fun(self):

    print('A class fun here')

    class B():

    def fun(self):

    print('B class fun here')

    class C(A,B):

    pass

    # class C(B,A):

    # pass

    c = C()

    c.fun()

    #输出 A class fun here

    此时C继承A和B,这个时候我们调用fun(),发现执行的是A的fun(),为什么不是B的呢?我们尝试把继承的顺序调换一下看看

    class A():

    def fun(self):

    print('A class fun here')

    class B():

    def fun(self):

    print('B class fun here')

    # class C(A,B):

    # pass

    class C(B,A):

    pass

    c = C()

    c.fun()

    #输出 B class fun here

    我们发现这个时候,执行的是B的fun(),看来到底执行那个父类的方法并不是随机的,是由什么东西控制的。其实关键就是一个叫做MRO的东西,我们看看下列代码

    class A():

    def fun(self):

    print('A class fun here')

    class B():

    def fun(self):

    print('B class fun here')

    class C1(A,B):

    pass

    class C2(B,A):

    pass

    print('C1 MRO',C1.__mro__)

    print('C2 MRO',C2.__mro__)

    C1().fun()

    C2().fun()

    '''输出

    C1 MRO (, , , )

    C2 MRO (, , , )

    A class fun here

    B class fun here

    '''

    在发现子类中没有对应方法后,开始在父类中寻找对应方法,寻找是按照一个顺序进行的,这个顺序就存放在类的__mro__成员变量中。(object是python中所有定义的类的超类,在python2中,自定义的类都要继承自object,python3中则不需要再显示的写出来,但是仍然会继承自object)

    关于Python的MRO,其实还有很多细节部分,是的,我完全写不了,,有兴趣了解的可以查看专门的介绍,另外,抽象类的继承还有更多的细节。

    第三部分,总结

    子类首先在自己的方法里找,若是找不到的话就会去继承的父类中找,单继承自然是去唯一的父类中找,若是多继承,则按照__mro__的顺序进行查找。

    虽然我进行了检查,但是也难免有出错,若有错误望指出

    展开全文
  • 生活中继承的例子有很,例如,汽车的发展历程就体现了继承。最早汽车的轮胎都是实心的,功能少,性能差,而如今汽车的功能越来越,性能越来越好,这是经过一代一代的发展而来的,每一代比上一代扩充了一些功能,...

    继承是子类复用父类的属性和方法的机制,类的继承是以生活中继承为灵感设计的。

    生活中继承的例子有很多,例如,汽车的发展历程就体现了继承。最早汽车的轮胎都是实心的,功能少,性能差,而如今汽车的功能越来越多,性能越来越好,这是经过一代一代的发展而来的,每一代比上一代扩充了一些功能,改进了一些性能。纵观整个汽车的发展史,每一代汽车都是在上一代汽车的特征和行为的基础之上,进行了设计和改良。这其中有些功能没有改变,有些功能是新增的,也有些功能经过了改良。例如,从第一代的汽车到现在的汽车,做交通工具这一特点始终都在沿用。

    生活中汽车的例子,与计算机中的继承是非常相似的。这么一代又一代的更新是有好处的。

    首先,节省了设计流程,不用闭门造车。

    其次,在前一代汽车基础之上设计,这样原来重复的生产技术还可以复用,再设计一些新增的功能,这样就能大大地提高生产效率。

    下面介绍一个实际案例,来说明继承的用处。

    假设设计一个师生管理系统,具有学生和教师两种用户,需要设计两个类,一个学生类(Student),一个教师类(Teacher)。Student类有学号、姓名、性别、年龄、用户名、密码等属性,Teacher类有姓名、性别、年龄、用户名、密码、学历等属性,这两个类中都有属性的getter和setter方法。由此可知,这两个类中有许多相同的属性和方法,也就是说代码有冗余。为了避免这样的情况,就可以使用继承来优化设计。将Student类和Teacher类中相同的属性和方法抽取出来,单独作为一个父类,这个父类称为用户类(User),而Student类和Teacher类作为子类继承父类User。Student类和Teacher类中就只放自己特有的属性和方法即可。由于这两个类都继承User类,因此User类中的属性和方法,它们可以直接使用。需要指出的是,在继承中私有属性和私有方法是不能被继承的。

    继承提高了代码的重用性,减少了代码和数据的冗余度。另外,如果要修改用户名属性,不采用继承的情况下,两个类的属性都需要修改,而使用继承后,只需要修改父类的用户名属性即可。由此可知,继承使代码的修改更加方便。

    展开全文
  • Java 接口多继承

    2021-02-13 00:10:24
    但是可以通过接口来实现类的多继承。(如何通过接口来实现多继承???)那么就一直以为Java里面是单继承,今天看FutureTask源码的时候发现,接口居然可以实现多继承,通过下面例子学习下。一个类只能extends一个父类...

    按照理解,一般都是说Java 类是单继承,但可以实现多个接口。但是可以通过接口来实现类的多继承。(如何通过接口来实现多继承???)

    那么就一直以为Java里面是单继承,今天看FutureTask源码的时候发现,接口居然可以实现多继承,通过下面例子学习下。

    一个类只能extends一个父类,但可以implements多个接口。java通过使用接口的概念来取代C++中多继承。与此同时,一个接口则可以同时extends多个接口,却不能implements任何接口。因而,Java中的接口是支持多继承的。

    下面先对接口做个总结:

    1>接口中的成员变量默认都是public,static,final(都可省略),必须被显示初始化,即接口中的成员变量必须是常量。

    2>接口中的方法默认都是public abstract类型的(都可省略),没有方法体。

    3>接口中只能包含public abstract类型的成员方法和public static final类型的成员变量。

    4>接口中没有构造方法,不能被实例化

    5>一个接口不能实现(implements)另一个接口,但是可以多继承接口

    6>Java中必须通过类来实现接口中的抽象方法

    7>当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类

    8>不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例

    9>一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承

    下面给一个接口多继承的例子,注意打印的a的值

    1 packageLesson1218Thread;2

    3 public interfaceTestIFA {4 int a = 0;5 int b = 1;6 int c = 2;7

    8 voidprintInfo();9

    10 }11

    12 packageLesson1218Thread;13

    14 public interfaceTestIFB {15 int a = 4;16 int b = 5;17 int c = 6;18

    19 voidprintInfo();20 }21

    22 packageLesson1218Thread;23

    24 public interface TestIFC extendsTestIFA,TestIFB {25 //int d = 4;

    26 int a = 7;27 }28

    29 packageLesson1218Thread;30

    31 public class IFDemo implementsTestIFC{32

    33 public static voidmain(String[] args) {34

    35 IFDemo ifdemo = newIFDemo();36 System.out.println("a is "+ifdemo.a); //a is 7, 因为这个地方实现接口TestIFC, 若是TestIFB, 则输出a is 4.

    37

    38 }39

    40 @Override41 public voidprintInfo() {42 System.out.println("which IF ?????");43

    44 }45

    46 }

    重点关注line36,   测试类实现哪个接口,输出的a就是哪个接口定义的值。

    问题1:若同时实现两个接口,调用里面相同变量 , 编译错误。 如下:

    1 packageLesson1218Thread;2

    3 public class IFDemo implementsTestIFA,TestIFC{ //同时实现两个接口4

    5 public static voidmain(String[] args) {6

    7 IFDemo ifdemo = newIFDemo();8 System.out.println("a is "+ifdemo.a); //编译错误

    9

    10 }11

    12 @Override13 public voidprintInfo() {14 System.out.println("which IF ?????");15

    16 }17

    18 }

    line8 会报编译错误: The field ifdemo.a is ambiguous

    程序不能找到应该调用哪个里面的a.

    结论:接口多继承时,接口里面有定义相同的变量,如果实现类要调用相同变量,必须显示指出来。如 TestIFA.a 。

    问题2:同时实现两个接口,若接口中的成员方法名字相同,但是返回值不一样,

    1 packageLesson1218Thread;2

    3 public interfaceTestIFA {4 int a = 0;5 int b = 1;6 int c = 2;7

    8 voidprintInfo();9

    10 }11

    12 packageLesson1218Thread;13

    14 public interfaceTestIFB {15 int a = 4;16 int b = 5;17 int c = 6;18

    19 String printInfo();20 }21

    22 packageLesson1218Thread;23

    24 public interface TestIFC extendsTestIFA,TestIFB { //编译错误25 //int d = 4;

    26 int a = 7;27 }

    接口TestIFA中含有成员方法voidprintInfo();   而接口TestIFB中含有成员方法String printInfo();  两个成员方法返回值不一样。

    接口TestIFC想继承上面两个类,编译错误。The return types are incompatible for the inherited methods TestIFA.printInfo(), TestIFB.printInfo()

    结论:被多继承的接口中,不能有方法名相同,但是返回值不一样的函数。否则没法多继承。

    展开全文
  • Java 8: 事实上的多继承语言

    千次阅读 2021-03-13 21:00:13
    然而,Java 的类单继承、接口多继承的设计,最终使 Java 走上了多重继承的老路,这最后一根稻草就是 Java 8 的 default 关键字。Java 为什么设计成单继承Java 语言在设计之初显然受到了 C++ 的很大影...

    Java 在多重继承上的设计甚至不如 C++。这个论点让人很难接受,毕竟我们在第一堂 Java 课上学到了:“Java 的优越性之一是摒除了 C++ 中易出错的多重继承”。然而,Java 的类单继承、接口多继承的设计,最终使 Java 走上了多重继承的老路,这最后一根稻草就是 Java 8 的 default 关键字。

    Java 为什么设计成单继承

    Java 语言在设计之初显然受到了 C++ 的很大影响。然而,Java 最终却没有采用 C++ 的多重继承方案。这是 Java 与 C++ 区分开的一个特点。在 Java 中,不允许“实现多继承”,即一个类不允许继承多个父类。但是 Java 允许“声明多继承”,即一个类可以实现多个接口,一个接口也可以继承多个父接口。由于接口只允许有方法声明而不允许有方法实现,这就避免了 C++ 中多继承的决议问题。

    James Gosling 在设计 Java 的继承方案时,借鉴了 Objective-C 中的“纯接口”概念。他发现,没有实现体的纯接口避免了 C++ 中的很多歧义和坑。因此 Java 引入了 interface。

    Java 8:default 关键字的引入

    Java 8 这一版本可以说是 Java 5 之后一次最大的改动了。在全面引入了 lambda 和函数式编程之后,JDK 中的很多接口也需要升级,例如 Iterable.forEach:

    1

    2

    3

    4public interface Iterable {

    Iterator iterator();

    + void forEach(Consumer super T> action);

    }

    然而,如果直接在 Iterable 接口中添加 forEach 方法。在 Java 7 及以前的所有实现 Iterable 的类都无法通过编译。为了向后兼容已有的代码,Java 8 引入了 default 关键字以及 default method,用来在接口中定义一个有方法体的方法。通过定义一个 default 的 forEach。所有实现了 Iterable 的类无需修改代码,便可在对象上调用 forEach。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10public interface Iterable{

    Iterator iterator();

    default void forEach(Consumer super T> action){

    Objects.requireNonNull(action);

    for (T t : this) {

    action.accept(t);

    }

    }

    }

    default 与多重继承

    Java 在设计之初,将 interface 设计成“没有任何实现”的纯接口,以此来避免接口多继承可能导致的问题。如果继承的多个接口中定义了相同的方法,只需要检查方法的返回值是否一致即可,例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16public class Test{

    public interface Base{

    int doSomething();

    }

    public interface Foo extends Base{

    }

    public interface Bar extends Base{

    }

    public abstract class FooBar implements Foo, Bar{

    // 编译器检查 Foo 和 Bar 中的 doSomething() 返回类型是否相同

    }

    }

    然而,在引入了 default method 之后,情况变得不太一样了。子接口可以 override 父接口定义的方法。我们可以轻易地构造出 C++ 的多重继承常出现的“菱形问题”:

    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

    26public class Test{

    public interface Base{

    int doSomething();

    }

    public interface Foo extends Base{

    @Override

    default int doSomething(){

    System.out.println("Foo::doSomething");

    return 1;

    }

    }

    public interface Bar extends Base{

    @Override

    default int doSomething(){

    System.out.println("Bar::doSomething");

    return 2;

    }

    }

    public abstract class FooBar implements Foo, Bar{

    // Error: inherit unrelated default from super-interfaces

    }

    }

    在上面的例子中,Foo 和 Bar 都重写了 doSomething,使得 FooBar 中的 doSomething 的含义出现了歧义,编译器会在此处报错。

    Interface 还是 interface 吗

    Java 8 引入的 default method 当然是一次对 interface 的极大增强(同时引入的还有 static method)。但是我们不禁思考,现在的 interface 是否还是 Java 设计之初的那个“纯接口”。上面的菱形问题的例子,我们发现,带有 default method 的接口表现得和抽象类越来越相似了。当然,interface 无法拥有和抽象类一样的能力,例如没有 private 的 method 和 field。但是以 interface 目前的能力,已经足够导致菱形问题这样的多继承问题。

    在 Java 9 中,为了解决 default method 中重复代码的例子,又为 interface 引入了 private method (以及 private static method),interface 的能力进一步得到增强。可以预料,未来 Java 中接口的能力将无限接近于抽象类。从这个层面上来讲,Java 虽然当年努力与 C++ 区分开,可还是和 C++ 越来越像。

    多继承当然是一种有力的语言机制,库和框架的开发者应该可以使用多继承实现一些酷炫的功能。但对于普通的 Java 程序员来说,interface 的语义变化会带来额外的心智负担。所以最好的办法是,忘记 default method 这件事情,让 interface 继续做最纯粹的接口。多继承这件事情,还是交给 Scala 这样更现代的语言来写吧。

    展开全文
  • 接口之间的多继承

    2021-02-18 19:24:58
    3.接口与接口之间是多继承的。 我们来重点解释第三条。 举例: public interface MyInterface1 { public abstract void method1(); public abstract void common(); } public interface MyInterface2 { ...
  • C++多继承(多重继承)详解

    千次阅读 2020-12-28 22:40:55
    除此之外,C++也支持多继承(Multiple Inheritance),即一个派生类可以有两个或多个基类。多继承容易让代码逻辑复杂、思路混乱,一直备受争议,中小型项目中较少使用,后来的 Java、C#、PHP 等干脆取消了多继承...
  • 继承,实现

    2021-03-04 07:07:25
    java中一个类只能有一个直接父类[单继承],但是一个类可以实现个接口[实现]而且一个类可以继承一个父类的同时,实现个接口格式:public class 类名 extends 父类名称 implements 接口A,接口B{//...}注意:子类/...
  • java中继承指的是什么

    千次阅读 2021-03-06 15:57:29
    java中继承指的是什么发布时间:2020-08-20 14:46:11来源:亿速云阅读:55作者:小新这篇文章将为大家详细讲解有关java中继承指的是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以...
  • python类继承(super继承

    千次阅读 2020-12-23 11:09:27
    1. python2和python3中定义类的形式不同python3中只有只有新式类class A(object): # python3中定义新式类class A: # python3中定义新式类(省略object)... # python2中定义经典类新式类和经典类只要区别在继承搜索顺...
  • 使用内部类就可以多继承,严格来说,还不是实现多继承,但是这种方法可以实现多继承所需的功能,所以把它称为实现了多继承。下面就举个例子:假如有一个打电话类Call,里面实现了一个可以打电话的功能的方法...
  • 个python类继承

    2021-01-14 12:39:04
    您只是在更改创建实例时除了C.__init__之外还运行什么初始化器方法。C同时继承{}和{},并且由于继承顺序的不同,{}的所有方法都被{}上的方法所遮蔽。在如果需要根据构造函数中的值更改类继承,请创建两个不同结构的...
  • Python多继承及MRO顺序

    千次阅读 2021-03-27 20:50:27
    方法解析顺序(Method Resolution Order),简称 MRO。用于在多继承时判断方法,属性的调用路径。
  • Java的一个子类可以继承个父类。答:×放样时的路径允许有几个?()答:1个下列有关有限合伙企业设立条件的表述中,不符合新颁布的《合伙企业法》规定的是( )答:有限合伙企业名称中应当标明\"特殊普通合伙\"字样...
  • Python 子类继承多个父类属性

    千次阅读 2020-12-31 11:36:16
    但是在子类初始化父类时,单继承和多继承稍有不同。使用单继承的初始化方法会导致父类属性无法全部继承。 单继承方式是错误的,如下: class A: def __init__(self): self.a = 'a' class B: def __init__(self):...
  • 假如说java是能够多继承的,那么,假设现在有一个A类,然后,随后又编写了两个类,B类以及C类。B类和C类分别继承了A类,并且,对于A类的同一个方法进行了重写。之后,又编写了一个D类,D类以多继承的方式同时继承了B...
  • JAVA中什么继承

    千次阅读 2021-02-12 10:29:01
    展开全部继承在本职上是32313133353236313431303231363533e78988e69d8331333366306435特殊一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的 一些属性或方法。1.Java...
  • 由于业务需要,需要在 feign 的接口上实现多层继承,开开心心撸完代码,却踩了个坑,原来 open-feign 是不支持接口的多层继承与多继承。查看几个解决方案无果,最终在源码的 issues 下找到解决方法。Issues 传送门 ...
  • 继承的概念 继承(inheritance)机制...基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能
  • 继承Thread 实现线程 , 是 ‘ 不 易 ’ 实现 资源共享 , 而不是 不能实现资源共享 !!! 看看现在网上的有些文章 (包括一些所谓的面试宝典,文字简短但是害人不浅),随便截一个图: 然后类似的例子 ...
  • 接口只是比抽象类“更纯”的一种形式。它的用途并不止那些。由于接口根本没有具体的实施...在C++中,将个类合并到一起的行动称作“多重继承”,而且操作较为不便,因为每个类都可能有一套自己的实施细节。在Java...
  • java学习笔记(12-继承、抽象类)

    千次阅读 2021-03-15 17:45:41
    1.继承关键字extendsjava中继承特点:在Java中,类只支持单继承,不允许多继承,也就是说一个类只能有一个直接父类多个类可以继承一个父类在Java中,多层继承是可以的,即一个类的父类可以再去继承另外的父类,例如C...
  • 进程中之文件描述符继承的消除

    千次阅读 2021-02-07 10:04:33
    什么是文件描述符的继承 当父进程创建子进程时,无论 fork 函数或者是 vfork 函数,子进程通常都会继承父进程的文件描述符。所谓的继承,就是子进程可以使用相同的文件描述符,和父进程操作同一个文件对象。如图所...
  • 子类可以继承父类的什么

    千次阅读 2021-03-05 22:47:45
    展开全部子类可以获得除private权限以外的所有父类属性,但是:1、在子类继承62616964757a686964616fe58685e5aeb931333431343130父类的时候,子类必须调用父类的构造函数。2、如果父类有默认构造函数,子类实例化时...
  • 继承Thread类实现线程简单实例

    千次阅读 2021-12-05 15:29:09
    文章目录继承Thread类实现线程简单实例一、线程的意义二、为什么通过线程可以提高用户体验,避免ANR三、电路图四、总结问题讨论问题和建议五、代码 一、线程的意义 1.为什么要使用线程 (a)提高用户体验...
  • java怎么继承,使用什么关键字?

    千次阅读 2021-02-28 16:43:51
    继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。 (推荐...
  • 继承人类起源非洲假说为人类的基因和语言研究提供了重要依据。()(),判断非洲智人开始走出非洲。分父类()提出“我的语言的界限意味着我的世界的界限”这一观点。个类动物的所有认知能力都不如人类。()继承()是观察...
  • java什么类不能被继承

    千次阅读 2021-02-28 12:03:58
    在java中有一些类并不能被继承,我们可以通过这些不能继承的类设计一些只读的不可变类。Java中不能被继承的类有哪些?在Java中,只要是被定义为final的类,也可以说是被final修饰的类,就是不能被继承的。这是final的...
  • 前言 Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 是 Spring 家族中的一个安全管理框架,提供了一套 Web 应用安全性的完整解决方案。...在用户授权方面,Spring ...
  • Java继承

    千次阅读 2021-02-13 02:17:13
    什么继承呢?类似人类中的继承(继承上一辈、上上辈的东西),在Java中就是将一个已知的类进行拓展,让一个新的类来继承这个已知的类,这样就能使这个新的类具有已知类的属性和行为。新的这个类被称为子类或者派生类...
  • Java 类的继承详解

    千次阅读 2021-02-12 23:53:43
    /*文章中用到的代码只是一部分,需要完整代码的可通过...先提一个问题:为什么要使用继承(后面再解答)。1.首先是类继承的写法:继承的关键字:extends格式:public class 类名(子类、派生类、超类) extends 类名(父...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,784,887
精华内容 713,954
关键字:

多继承什么意思

友情链接: kengao.zip