在设计类时,慎用继承,或尽量少用继承

原创 2007年09月21日 09:53:00



 模式设计告诉我们在设计类时,尽量用以下原则:
1)、对接口编程,而不对实现编程
2)、对类的功能扩展,要多用组合,少用继承。
为什么要多用组合,少用继承呢?因为子类可能继承了对子类没用的或者有害的方法。请看下例:
要求:我们在输入以下键和值时,输出也保持值的顺序
  map.put("a","111");
  map.put("v","190");
  map.put("d","132");
1、采用继承的方式来设计类

import java.util.ArrayList;
import
 java.util.HashMap;
import
 java.util.List;

//采用继承的方式来设计类

public class ListMap extends HashMap  {

    
private static final long serialVersionUID = -6040757858724463221L
;
    
private
 List list;
    
public
 ListMap(){
        
super
();
        
this.list=new
 ArrayList();
    }
    
    
//重写父类中的方法put在此映射中关联指定值与指定键

    public Object put(Object key,Object value)
    {
        
if
(list.contains(key))
        {
            list.remove(key);
        }
        
this
.list.add(key);
        
return super
.put(key,value);
    }
    
    
public Object getKey(int
 i){
        
return this
.list.get(i);
    }
    
    
//获得对应键的值

    public Object getValue(int i){
        
return this
.get(getKey(i));
    }
    
    
public int
 size()
    {
        
return this
.list.size();
    }
    
    
public static void
 main(String[] args) {
        ListMap map
=new
 ListMap();
        map.put(
"a","111"
);
        map.put(
"v","190"
);
        map.put(
"d","132"
);
        
//利用自己建立的方法getValue()保证输出有序

        for(int i=0;i<map.size();i++){
            System.out.println(map.getValue(i));
        }
        
        System.out.println();
        
        
//利用从HashMap中继承的方法values()输出不保证有序

        String[] list=(String[])map.values().toArray(new String[0]);
        
for (int i = 0; i < list.length; i++
) {
            System.out.println(list[i]);
        }
    }
}

输出:
111
190
132

132
111
190
此时会发现,采用继承的方式来设计类,容易让使用者使用父类中没用的方法values(),从而不能保证结果正确
2、采用组合的方式来设计类

import java.util.ArrayList;
import
 java.util.HashMap;
import
 java.util.List;

//采用组合的方式来设计类

public class MyListMap{

    
//只利用HashMap中部分方法,定义一个HashMap的内部变量

    private HashMap map;
    
private
 List list;
    
public
 MyListMap(){
        
this.map=new
 HashMap();
        
this.list=new
 ArrayList();
    }
    
    
//自己写个方法put在此映射中关联指定值与指定键

    public Object put(Object key,Object value)
    {
        
if
(list.contains(key))
        {
            list.remove(key);
        }
        
this
.list.add(key);
        
//调用HashMap中put方法

        return this.map.put(key,value);
    }
    
    
public Object getKey(int
 i){
        
return this
.list.get(i);
    }
    
    
//获得对应键的值

    public Object getValue(int i){
        
//调用HashMap中get方法

        return this.map.get(getKey(i));
    }
    
    
public int
 size()
    {
        
return this
.list.size();
    }
    
    
public static void
 main(String[] args) {
        MyListMap map
=new
 MyListMap();
        map.put(
"a","111"
);
        map.put(
"v","190"
);
        map.put(
"d","132"
);
        
//利用自己建立的方法getValue()保证输出有序

        for(int i=0;i<map.size();i++){
            System.out.println(map.getValue(i));
        }
        
        System.out.println();
        
        
//
此时用values()就出错,因为此时不存在此方法
//
        String[] list=(String[])map.values().toArray(new String[0]);
//
        for (int i = 0; i < list.length; i++) {
//
            System.out.println(list[i]);
//        }

    }
}

输出:
111
190
132
此时使用者不能使用HashMap类中的方法values(),在次类中不存在此方法,从而避免用户误用。

所以:在设计类时,慎用继承,或尽量少用继承。

版权声明:本文为博主原创文章,未经博主允许不得转载。

面向对象设计原则之七--合成复用原则

合成复用原则又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle, CARP),其定义如下: 合成复用原则(Composite Reuse P...
  • wqc19920906
  • wqc19920906
  • 2017年06月08日 18:19
  • 166

为什么要多用组合少用继承?

面向对象编程时,有十条很重要的原则: 代码复用 封装变化 开闭原则 单一责任原则 依赖注入/依赖倒置原则 里氏替换原则(LSP) 接口隔离原则(ISP) 多用组合,少用继承 面向接口编程 委托原则...
  • zhaizu
  • zhaizu
  • 2016年09月18日 14:27
  • 2014

组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承

                                                      组合还是继承,这是一个问题                                 ...
  • hivon
  • hivon
  • 2006年01月19日 07:26
  • 6404

慎用继承

1.类继承在继承实现的同时也继承接口,因此,如果主要目的是继承实现,那么采用继承就是不当之举 2.JDK的开发者也会出现问题 java.util.Properties类,设计者选择让他继承...
  • sjdl9396
  • sjdl9396
  • 2013年02月02日 18:40
  • 469

面向对象为什么要多用对象模式而少用继承模式?

进来学习java的时候遇到了一些经验说多用对象模式,少用继承模式。现在写一点感想。 面向对象的对象之间的哦和方式有继承,实现,关联,依赖,聚合和组合。其中的继承和实现是继承这类模式。 说道的一个原...
  • ndcnb
  • ndcnb
  • 2014年06月14日 17:51
  • 1108

lua中最好不要使用继承

quick中提供了class 的语法糖,不建议在大型项目特别是服务器中使用。无法保证继承的效果,你会发现以下的问题local a = class('a') function a:ctor() ...
  • nynyvkhhiiii
  • nynyvkhhiiii
  • 2017年04月15日 18:50
  • 412

c++继承详解之一——继承的三种方式、派生类的对象模型

C++是OOP(Object Oriented Programming)语言,即面向对象编程语言。OOP的核心思想就是数据抽象(类的设计),继承和动态绑定。 类展现了C++的封装特性,即将具体的实现过...
  • lixungogogo
  • lixungogogo
  • 2016年04月11日 01:00
  • 3633

如何让一个类不能被继承

要想让一个类不能被继承,已知方法有两种。一是,将类的构造函数定义为带private属性。二是,将该类虚继承一个父类,但是该父类的构造函数是带private属性的。 关于第二个方法可行的依据是: 1...
  • CHIERYU
  • CHIERYU
  • 2015年12月03日 11:56
  • 1713

C++中定义一个不能被继承的类

一种错误的解法 最开始是从构造函数开始着手(先声明这种方法不能定义一个不能被继承的类,这是一种错误的方法,但是很容易往这方面想),假设存在下面的继承体系: 现在假设B是一个不能被继承的类,那么如果...
  • u012501459
  • u012501459
  • 2015年08月31日 10:56
  • 1975

面向对象---基于组合的继承:属性的继承基于伪装的方式实现,而方法的继承基于原型链的方式继承。

终极方案—基于组合实现继承 基于组合的继承就是:属性的继承基于伪装的方式实现, 而方法的继承基于原型链的方式继承。 function Parent(name) { this.name ...
  • guohao326
  • guohao326
  • 2017年06月11日 17:33
  • 71
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在设计类时,慎用继承,或尽量少用继承
举报原因:
原因补充:

(最多只允许输入30个字)