`
xueyong
  • 浏览: 61423 次
  • 来自: ...
社区版块
存档分类
最新评论

使用继承——IS 原则

 
阅读更多
继承在java里体现在2个关键字,extends和implements。类和类之间继承使用extends,而类到接口使用的implements。
   
单从英文字面上理解,extends就是“扩展”的意思,也就是增强原来类的功能。是不是只要增强就使用继承?显然有问题。不要因为“增强”类的功能,而改变类原来的面貌,甚至把这个类改造成一个“全新”的类,这样会导致从现实角度理解两个毫不相关的类有很强的耦合关系。另外一个使用extends诱惑就是代码复用,父类有的子类都可以使用,好像只要使用一个关键字extends就可以省去n多代码,导致的结果和“增强”类似。

如有一个马类,和一个狗类
马{
    跑(){}
    骑(){}
}
狗 extends 马{
    看家(){}  //增加看家方法,复用跑的功能
}

马能跑和骑。现在要定义一个狗类,狗不但能跑还能看家,于是就出现狗继承马,再加一个能看家的本领。我们怎么理解这条狗?!客户程序拿到马后就要“骑”,但确发出旺旺的狗叫声。你可能对着你的兄弟大声宣布,狗就是狗不能骑,只能跑。狗是狗,马是马,为什么不在代码上彻底理清关系。

有父子关系的类,父类和子类一定能像动植物学里一样,能划分到同一个科种。父类一定比子类更抽象,父类描述的是一般普遍具有的,子类描述相对父类而言是更进一步的具体行为和特征。这就是使用继承最原始的动力。

这里引出另外一个概念就是“具体依赖于抽象”。在java里使用extends的继承,父类和子类都是具体类。虽然能从代码上分辨出谁的抽象程度高,很多人不推荐使用extends,具体类永远没有接口(纯抽象)来的抽象,还是有一定道理。“具体依赖于抽象”还有把潜在错误丢给具体的意思,越抽象的或越概括的东西越不容易错。

使用implements的原则和使用extends一样,但implements一定暗示着多态。若一个接口只有一个实现类,那么这个接口就没有存在的必要(若后期又要增加实现类,只要重构提取出这个接口即可)。

使用继承用一句直白的话描述就是“子类IS父类”,这就是唯一的IS原则。可能很多人从书中不止一次看到过,很容易滑过。如:
马{}
黑马 extends 马{} //黑马是马
白马 extends 马{} //白马也是马

兽{}
马 extends/implements 兽{} //马是兽
狗 extends/implements 兽{} //狗也是兽


若一个类要使用另一个类里的功能,怎么办?!用委派合成等手段来实现,不要轻易使用继承实现这种复用或增强,使用前一定要用IS原则衡量一下。
分享到:
评论

相关推荐

    C ++程序设计语言——详解源码

    - 这种继承模式常用于表示“is-implemented-in-terms-of”关系,即派生类是用基类的方法实现的,但不希望外部直接访问基类的公有成员。 6. **多继承**: - 虽然文中未提及,但C++还支持多继承,即一个派生类可以...

    Java基础篇——三大特性(继承)

    【Java基础篇——三大特性(继承)】 Java作为一种面向对象的编程语言,其核心思想是通过类(class)来封装数据和功能...因此,应谨慎使用继承,尤其是单一职责原则和开闭原则的考虑,避免滥用继承导致设计上的问题。

    JS在继承方法中在加其他处理

    - **面向对象设计原则**:此示例遵循了面向对象设计原则之一——“开放封闭原则”(Open-Closed Principle),即软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。通过继承和重写,我们可以轻松地扩展功能而...

    ruby——course.pdf

    但是,Ruby的设计原则之一是“最少惊讶原则”(POLs),这意味着它的语法和行为旨在遵循直观的逻辑,减少意外情况。然而,对于熟悉其他编程语言的人来说,Ruby的某些特性可能会带来惊喜,比如它的`case`语句可以非常...

    OO设计原则-里氏替换原则

    ### OO设计原则——里氏替换原则详解 #### 一、引言 面向对象设计原则(Object-Oriented Design Principles)是一套指导软件开发者如何更好地设计类、接口等面向对象元素的原则集合,旨在提高代码的可复用性、可...

    c++编程惯用法——高级程序员惯常用方法和技巧

    书中可能讨论智能指针(如unique_ptr、shared_ptr)的使用,以避免内存泄漏和悬挂指针问题,同时也可能涉及RAII(Resource Acquisition Is Initialization)原则。 6. **标准库的使用**:C++标准库包含大量实用的...

    php面向对象——记忆卡

    #### 魔术方法:`__get()`, `__set()`, `__isset()`, `__unset()` 魔术方法在特定条件下自动调用,例如尝试访问未定义的属性时调用`__get()`,为未定义的属性赋值时调用`__set()`等。 示例: ```php class ...

    C++编程规范——101条规则、准则与最佳实践,英文版,高清。

    遵循RAII(Resource Acquisition Is Initialization)原则,确保资源在对象生命周期内正确管理。 5. **类型安全**:尽量避免隐式类型转换,使用显式转换操作符或类型别名。避免使用C风格的数组和指针,转而使用STL...

    高质量C++编程规范——林锐博士编写

    避免大范围的使用公有继承,考虑使用接口(纯虚类)和组合。 8. **异常安全**:在抛出和捕获异常时,要保证对象状态的完整,避免数据损坏。了解不同级别的异常安全性,如基本异常安全和强壮异常安全。 9. **编译期...

    面向对象编程思想小谈——类和对象.pdf

    在面向对象的程序设计中,封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)是三个核心原则。封装是把数据和操作数据的方法绑定在一起,构成一个对象;继承是一个类可以继承另一个类的属性和方法,...

    c++编程惯用法——高级程序员常用方法和技巧

    3. **RAII(Resource Acquisition Is Initialization)**:这是一种设计原则,确保资源在创建对象时获取并在对象销毁时自动释放。智能指针(如`std::unique_ptr`和`std::shared_ptr`)是RAII的一个典型应用,它们自动...

    30天掌握C++精髓——经典教程

    - **RAII资源管理**:掌握Resource Acquisition Is Initialization模式,实现自动资源管理。 #### 2. STL标准库 - **容器**:介绍vector、list、map等常用容器的使用方法及其特性。 - **算法**:学习STL中提供的...

    OC封装继承多态演示

    在这个"OC封装继承多态演示"的例子中,我们将深入探讨这三个关键的OOP原则。 **封装**是面向对象编程的核心特性之一,它涉及到将数据(属性)和操作这些数据的方法(函数)捆绑到一个独立的单元——对象中。在OC中...

    C++编程惯用法——高级程序员常用方法和技巧

    - 使用RAII(Resource Acquisition Is Initialization)原则,将资源的生命周期与对象绑定。 3. **模板**: - 利用模板元编程进行编译时计算,提高程序运行效率。 - 使用`template <typename T>`定义泛型函数,...

    程序面试试题汇总——C/C++/Java/软件测试

    2. 了解并正确使用RAII(Resource Acquisition Is Initialization)原则。 3. 掌握C++内存管理,理解何时使用new/delete,何时使用智能指针。 4. 使用异常安全的编程技巧,确保异常发生时程序不会崩溃。 5. 尽量减少...

    非常好的C++设计模式项目资源,分享出来.zip

    这样,你就能一次又一次地使用该方案而不必做重复劳动”。 ——Christopher Alexander 如何解决复杂性? 分解 人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单...

    我的C#面对对象编程学习文档与近百道oop试题

    《面向对象编程——继承和多态》.doc很可能是关于这个主题的深入讨论,可能包含如何创建和使用继承的示例。 多态则是指同一种行为在不同的对象上表现出不同的形式,这是通过接口和重写方法来实现的。在`面向对象...

    Python基础知识笔试.pdf

    `x=y=z=1` —— 此表达式允许在Python中使用,它会将`x`, `y`, 和`z`都赋值为`1`。 - B. `x=(y=z+1)` —— 这个表达式是非法的。在Python中,你不能在一个赋值语句中使用等号(`=`)进行比较。正确的做法是先给`y`...

Global site tag (gtag.js) - Google Analytics