合理使用继承,可以大大减少类与类之间的重复代码,让程序事半功倍,而不当的继承关系,则会让类与类之间建立起错误的强耦合,带来大片难以理解和维护的代码。 正是因为这样,对继承的态度也可以大致分为两类。...出处: Liskov substitution principle - Wikipedia 如果把它比较通俗的翻译过来,大概是这样:当你使用继承时,子类(派生类)对象应该可以在程序中替代父类(基类)对象使用...不当继承关系如何违反 L 原则 现在,假设我们需要写一个新函数,它可以同时接受多个用户对象作为参数,批量将它们停用。...这时因为 Admin 虽然是 User 类型的子类,但它的 list_related_posts 方法返回却是一个可迭代的生成器,并不是列表对象。而生成器是不支持 len() 操作的。...要符合 L 原则,我们一定得让子类方法和父类返回同一类型的结果,支持同样的操作。或者更进一步,返回支持更多种操作的子类型结果也是可以接受的。
有两个途径能帮我们达到这个目的,一个是通过 defaultdict,这个类型而不是普通的 dict,另一个 是给自己定义一个 dict 的子类,然后在子类中实现 __missing__ 方法。...也就是说,如果 有一个类继承了 dict,然后这个继承类提供了 __missing__ 方法,那 么在 __getitem__ 碰到找不到的键的时候,Python 就会自动调用它, 而不是抛出一个 KeyError...OrderedDict 的 popitem 方法默认删除并返回的是字典里的最后一个元素,但是如果像 my_odict.popitem(last=False) 这样调用 它,那么它删除并返回第一个被添加进去的元素...collections.ChainMap 该类型可以容纳数个不同的映射对象,然后在进行键查找操作的时候,这些对象会被当作一个整体被逐个查找,直到键被找到为止。...更倾向于从 UserDict 而不是从 dict 继承的主要原因是,后者有时 会在某些方法的实现上走一些捷径,导致我们不得不在它的子类中重写 这些方法,但是 UserDict 就不会带来这些问题。
你需要找出一些抽象,让程序在变得复杂时也易于管理。下面先来列举一些潜在的组件。 解析器:添加一个读取文本并管理其他类的对象。 规则:对于每种文本块,都制定一条相应的规则。...---- 注意 这里之所以使用术语处理程序(而不是渲染程序等),旨在指出它负责处理解析器生成的方法调用,而不必像HTMLRenderer那样使用标记语言渲染文本。...换而言之,发现使用了标题规则(这表明当前文本块为标题)后,就不应再试图使用段落规则。为实现这一点,一种简单的方法是让解析器依次尝试每个规则,并在触发一个规则后不再接着尝试。...你可编写多个独立的规则和过滤器,再使用方法add_rule和add_filter将它们添加到解析器中,同时确保在处理程序中实现了相应的方法。...5.8.整合起来 现在,只需创建一个Parser对象,并添加相关的规则和过滤器。下面就来这样做:创建一个在构造函数中完成初始化的Parser子类,在使用它来解析sys.stdin。
问题 你如何组织你的代码使其可以容易的添加基本的或者一些很少用到的 特性,而不是直接不额外的代码写在你的类的内部? 3. 解决方案 装饰器模式:动态地给一个对象添加一些额外的职责或者行为。...如果你拥有一族子类(从一个父类派生而来),你需要在与子类独立使用情况下添加额外的特性,你可以使用装饰器模式,以避免代码重复和具体子类数量的增加。 4....此外,为一个特定的Component类提供多个不同的 Decorator类,这就使得你可以对一些职责进行混合和匹配。使用Decorator模式可以很容易地重复添加一个特性。...你需要让你检验有效性的代码也可以应用到其它部件,这样不用再更多的子类上进行有效性验证。 ? 这里子类溢出并不是唯一的问题。想一想那些重复的代码,你需要重新设计你的整个类层次。有没有更好的方法!...至少WidgetDecorator类应该能够在它的构造函数中接受一个组件, * 并复制公共方法paint() * */ class WidgetDecorator { protected $_widget
通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。如果 你希望改变一个已经初始化的对象的行为,你怎么办?...问题 你如何组织你的代码使其可以容易的添加基本的或者一些很少用到的 特性,而不是直接不额外的代码写在你的类的内部? 3....如果你拥有一族子类(从一个父类派生而来),你需要在与子类独立使用情况下添加额外的特性,你可以使用装饰器模式,以避免代码重复和具体子类数量的增加。 4....此外,为一个特定的Component类提供多个不同的 Decorator类,这就使得你可以对一些职责进行混合和匹配。使用Decorator模式可以很容易地重复添加一个特性。...至少WidgetDecorator类应该能够在它的构造函数中接受一个组件, * 并复制公共方法paint() * */ class WidgetDecorator { protected
而 Null 类型是所有引用类型的子类型,它只有一个实例:null。 语法 主方法是一个程序的入口点。JVM要求一个名为main的主方法,接受一个字符串数组的参数。你可以如下所示来定义一个主方法。...包对象 在 Scala 中,包对象(Package Object)是一种特殊的对象,它与包同名,并且可以在包中定义一些公共的成员和方法,供包中的其他类和对象直接使用。...由于包对象与包同名且位于同一包中,因此可以直接使用它们。 特质 在Scala中,类是单继承的,但是特质(trait)可以多继承。 这意味着,一个类只能继承一个父类,但可以继承多个特质。...传名参数使用 => 符号来定义,以表示传递的是一个表达式而不是具体的值。 传名参数的特点是,在每次使用参数时都会重新求值表达式,而不是在调用函数时进行求值。...它提供了一种方法来访问集合中的元素,而不需要暴露集合的内部结构。在 Scala 中,你可以使用 iterator 方法来获取一个集合的迭代器。
而 Null 类型是所有引用类型的子类型,它只有一个实例: null。语法主方法是一个程序的入口点。JVM要求一个名为main的主方法,接受一个字符串数组的参数。你可以如下所示来定义一个主方法。...包对象在 Scala 中,包对象(Package Object)是一种特殊的对象,它与包同名,并且可以在包中定义一些公共的成员和方法,供包中的其他类和对象直接使用。...由于包对象与包同名且位于同一包中,因此可以直接使用它们。特质在Scala中,类是单继承的,但是特质(trait)可以多继承。这意味着,一个类只能继承一个父类,但可以继承多个特质。...传名参数使用 => 符号来定义,以表示传递的是一个表达式而不是具体的值。传名参数的特点是,在每次使用参数时都会重新求值表达式,而不是在调用函数时进行求值。...它提供了一种方法来访问集合中的元素,而不需要暴露集合的内部结构。在 Scala 中,你可以使用 iterator 方法来获取一个集合的迭代器。
继承是类之间的一种关系,其中子类可以继承(获得)父类的属性和方法,同时可以添加自己独有的属性和方法。 举例说明:假设有一个父类Animal,它有属性name和方法sayHello()。...现在有一个子类Dog,想要重写eat()方法并定义自己的进食行为。子类Dog可以通过重写父类的eat()方法,在自己的eat()方法中实现狗狗特有的进食行为。...例如,在一个计算器类中,可以有两个同名的add函数,一个接受两个整数参数,另一个接受两个浮点数参数。 函数覆盖(也称为函数重写或方法重写)则是指子类重写了父类中的同名函数。...函数重载与函数签名有关,可以在同一个类中有多个同名函数,但参数类型或个数必须不同;而函数覆盖则是子类重写了父类中的同名函数,要求函数名、返回类型和参数列表都相同。...举例:想象你是一名旅行者,你需要租一辆车去探索一个城市。你不需要亲自去了解车子的每个零件如何工作,你只需要知道如何使用它们。租车公司为你提供了一辆可用的车,而不是让你去修理引擎或更换轮胎。
当两种接口中有相同签名的方法,子类实现他俩时,需要覆写冲突的方法:可以重定义 jim() 方法,也能使用 super 关键字选择基类实现中的一种。...3 抽象类和接口 ? 抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。 尽可能地抽象 因此,更倾向使用接口而不是抽象类。 只有当必要时才使用抽象类。...在简单情况下体现在一个方法接受接口作为参数,该接口的实现和传递对象给方法则交由你来做。 因此,接口的一种常见用法是策略设计模式。 编写一个方法执行某些操作并接受一个指定的接口作为参数。...可以说:“只要对象遵循接口,就可以调用方法” ,这使得方法更加灵活,通用,并更具可复用性。 例如,类 Scanner 的构造器接受的是一个 Readable 接口。 ?...因为你可以以这种方式在已有类中增加新接口,所以这就意味着一个接受接口类型的方法提供了一种让任何类都可以与该方法进行适配的方式。这就是使用接口而不是类的强大之处。
当两种接口中有相同签名的方法,子类实现他俩时,需要覆写冲突的方法:可以重定义 jim() 方法,也能使用 super 关键字选择基类实现中的一种。...3 抽象类和接口 ? 抽象类仍然是一个类,在创建新类时只能继承它一个。而创建类的过程中可以实现多个接口。 3.1 尽可能地抽象 因此,更倾向使用接口而不是抽象类。 只有当必要时才使用抽象类。...在简单情况下体现在一个方法接受接口作为参数,该接口的实现和传递对象给方法则交由你来做。 因此,接口的一种常见用法是策略设计模式。 编写一个方法执行某些操作并接受一个指定的接口作为参数。...可以说:“只要对象遵循接口,就可以调用方法” ,这使得方法更加灵活,通用,并更具可复用性。 例如,类 Scanner 的构造器接受的是一个 Readable 接口。 ?...因为你可以以这种方式在已有类中增加新接口,所以这就意味着一个接受接口类型的方法提供了一种让任何类都可以与该方法进行适配的方式。这就是使用接口而不是类的强大之处。
,需要手动使用后才执行,该过程称为方法调用 方法注意事项 方法不能嵌套定义 方法重载 方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法相互构成重载 多个方法在同一类中 多个方法具有相同的方法名...获取数量 array.size() 返回集合中的元素个数 继承 特点 子类只能继承一个父类,而父类可以有多个子类 this this.成员变量 访问本类成员变量 this(...)...在类的局部位置:局部内部类 局部内部类是成员方法中定义的类,外界是无法直接使用,需要在方法内部创建对象并使用 该类可以直接访问外部类成员,也可以访问方法内的局部变量 匿名内部类 匿名内部类也是局部内部类...public E removeFirst() 此列表中删除并返回第一个元素 public E removeLast() 此列表中删除并返回最后一个元素 List集合子类特点 List集合常用子类:ArrayList...而重写hashCode()方法,可以实现不同对象的哈希值相同 如何保证唯一性 HashSet原理 我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率
使用return语句可以将结果返回给调用者。 方法的重载: 在一个类中,可以定义多个同名但参数列表不同的方法,这称为方法的重载。方法重载可以根据不同的参数类型和数量来执行不同的逻辑。...方法重载指在同一个类中定义多个具有相同名称但参数列表不同的方法。...这样,在同一个类中定义了多个具有相同名称但参数列表不同的方法,实现了多态性。根据实际参数的类型,调用相应的方法,从而实现不同的行为。这就是方法重载实现多态性的一种方式。...接口和抽象类 接口是一种实现多态性的方式,它定义了一组方法和属性的规范,而不包含具体的实现。一个类可以实现一个或多个接口,并提供接口中定义的方法和属性的具体实现。...4.2 继承的用法和继承链的构建 继承是面向对象编程中的重要概念,它允许一个类(子类)继承另一个类(父类)的属性和方法,并可以添加自己的额外功能。
类似于函数,继承是一种代码重用技术,您可以将其应用于类。这是将类置于父子关系中的行为,在这种关系中,子类继承父类方法的副本,使您不必在多个类中复制一个方法。...组合是一种类设计技术,它将对象包含在类中,而不是继承那些对象的类。这就是我们在给类添加属性时所做的事情。当使用继承设计你的类时,支持组合而不是继承。...我们可以创建一个父类Vehicle,并让Car、Motorcycle和LunarRover继承它,而不是将这些代码复制并粘贴到每个类中。...例如,如果构造器既可以接受新对象需要的数据字符串,也可以接受包含新对象需要的数据的文件名字符串,会怎么样呢?我们不希望__init__()方法的参数列表冗长而混乱。...使用组合而不是继承通常更灵活,因为它实现了与一个类的对象和其他类的对象的“有”关系,而不是直接从那些其他类继承方法。这意味着一个类的对象可以拥有另一个类的对象。
即: 对象 = 类() 对象.属性 对象.方法() 除此之外,还有一种绑定在类这个层面的属性和方法,叫作类属性和类方法。使用类属性和类方法时,不用创建对象,直接通过类来使用。...我们可以通过该参数来引用类属性,或类中其它类方法。 类方法中可以使用该类的类属性,但不能使用该类的对象属性。因为类方法隶属于类,而对象属性隶属于对象,使用类方法时可能还没有对象被创建出来。...和 digits 是为了提供给同一个类中的类方法使用,但我们可以通过类或对象从类的外部直接访问它们。...被继承的类叫作父类(或基类),继承者叫作子类(或派生类)。关于类的简单继承可以看下图就是一个典型的例子: 在类的继承的定义时,子类名称的后面加上括号并写入父类。...,而不是类实例化后的对象。
如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系。...对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。...重载 overloading 方法重载是 让类以统一的方式处理不同类型数据 的一种手段。多个同名函数同时存在,具有 不同的参数个数/类型 。...重载是一个类中多态性的一种表现; Java 的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。..., 被引用对象的类型 而不是引用变量的类型决定了调用谁的成员方法, 但是这个被调用的方法必须是在超类中定义过的 ,也就是说被调用的方法必须是 被子类重写的方法 。
即: 对象 = 类() 对象.属性 对象.方法() 除此之外,还有一种绑定在类这个层面的属性和方法,叫作类属性和类方法。使用类属性和类方法时,不用创建对象,直接通过类来使用。...我们可以通过该参数来引用类属性,或类中其它类方法。 类方法中可以使用该类的类属性,但不能使用该类的对象属性。因为类方法隶属于类,而对象属性隶属于对象,使用类方法时可能还没有对象被创建出来。...和 digits 是为了提供给同一个类中的类方法使用,但我们可以通过类或对象从类的外部直接访问它们。...被继承的类叫作父类(或基类),继承者叫作子类(或派生类)。关于类的简单继承可以看下图就是一个典型的例子: ? 在类的继承的定义时,子类名称的后面加上括号并写入父类。...,而不是类实例化后的对象。
这种多态性是通过方法的重载和覆盖实现的。方法重载方法重载是指在同一个类中定义多个方法,这些方法具有相同的名称但是参数列表不同。当调用这些方法时,编译器会根据参数的类型和数量来确定应该调用哪一个方法。...当我们需要编写多个类似的方法时,可以使用方法重载来避免编写大量重复的代码。当我们需要编写多个类似的类时,可以使用继承来避免编写大量重复的代码。提高代码复用性多态可以提高代码的复用性。...当我们需要编写一个通用的方法时,可以使用接口来定义方法的规范,然后让多个类实现这个接口。这样,我们就可以在不修改方法的情况下,通过传递不同的对象来执行不同的行为。...提高程序的可扩展性多态可以提高程序的可扩展性。当我们需要添加新的功能时,可以通过添加新的类和接口来实现这个功能,而不需要修改现有的代码。四、多态的注意点多态只适用于方法调用,不适用于属性访问。...当我们访问对象的属性时,实际访问的是对象本身的属性,而不是对象的子类属性。静态方法不能被重写,因此静态方法不具备多态性。
对象使用。...这个胶水类中的 _handlePointerEvent 方法。...close 方法,下面代码我们可以看到,如果前面 Down 事件中没有通过 addPointer 添加成员到 _arenas 中,那会连参加的机会都没有,而进入 _tryToResolveArena 之后...回到我们前面的上下滑动可点击列表,是不是很明确了:如果是点击的话,没有产生 MOVE 事件,所以 DragGestureRecognizer 没有被接受,而Item 作为 Child 第一位,所以响应点击...,导致内部确定位置的 pixels 发生改变,并执行父类 ChangeNotifier 的方法notifyListeners 通知更新。
领取专属 10元无门槛券
手把手带您无忧上云