zoukankan      html  css  js  c++  java
  • 面向对象——继承与组合

    1、组合的特点

    2、继承带来最大的坏处

    3、设计父类遵循的规则

    4、何时使用继承

    5、何时使用组合

    1、组合的特点

        提高代码复用性,增加has-a关系,增强理解

    2、继承带来最大的坏处

        破坏父类的封装性(每个类都应该封装它内部信息和实现细节,而只暴露必要的方法给其他类使用。但继承关系中,子类可以直接访问父类的属性(内部信息)和方法,从而造成子类和父类的严重耦合)。采用组合方法来实现类重用则能提供更好的封装性。

    3、设计父类遵循的规则

    为了保证父类良好的封装性,不会被子类随意改变,设计父类通常应该遵循以下规则:

    ① 尽量隐藏父类的内部数据(private);

    ② 不要让子类可以随意访问、修改父类的方法。辅助方法设为private,需要被外部调用public,不希望子类重写加上final,若希望重写但是不希望其他类自由访问,设为protected;

    ③ 在父类构造器中不调用被子类重写的方法(否则会引起空指针异常)。

    比如:new 父类时调用的是父类自己的方法,而通过子类new一个父类时,在父类构造器中实际上调用的是子类方法。

    例1

    public class FatherSonTest {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Father f = new Son();
            f.getNum();
        }
    
    }
    class Father{
        private int num;
        public Father() {
            num = getNum();
            System.out.println("Father, num="+num);
        }
        public int getNum() {
            System.out.println("this is Father!");
            return 4;
        }
    }
    class Son extends Father{
        private int num;
        public Son() {
            num = getNum();
            System.out.println("Son, num="+num);
        }
        public int getNum() {
            System.out.println("this is Son!");
            return 5;
        }
    }

    output:

    this is Son!

    Father, num=5

    this is Son!

    Son, num=5

    this is Son!

    例2:

    public class a { 
        public static void main(String[]args){  
            a c=new b();  
            //下面这里打印的是a的成员变量s=AAAA  
            System.out.println(c.s); 
        }
        public String s="AAAA";  
        //父类构造函数 
        public a(){  
            call(); 
        }
        public void call(){  
            System.out.println("a class call()="+s); 
        } 
    }
    class b extends a{ 
        public String s="BBBB"; 
        //子类构造函数 
        public b(){  
            System.out.println("b class b()="+s); 
        }
        //重写父类中的call函数 
        public void call(){  
            System.out.println("b class call()="+s); 
        }
    }

    output:

    b class call()=null

    b class b()=BBBB

    AAAA

    由于父类第一次调用子类的call方法时,子类还没有初始化非静态变量以及构造方法(静态成员被初始化了),因此输出是null。

    注意:通过父类的引用类型变量指向子类类型对象,访问成员变量时是访问的父类的成员变量。

    (类加载时会为静态变量赋初值,执行静态代码块,但不会为实例变量赋初值,只有构造函数执行时才会赋值)

    若希望某些类不被继承,可以用final修饰类,或者将所有构造器设为private,保证子类无法调用该类的构造器,从而无法继承。

    4、何时使用继承

    保证子类是一种特殊的父类,加上以下两个条件之一:

    ①   子类需要额外增加属性,而不仅仅是属性值的改变;

    ②   子类需要增加自己独有的行为方式。

    5、何时使用组合

    若只是出于类复用的目的,并不一定需要使用继承,完全可以使用组合来实现。

    通常将新类中嵌入旧的对象修饰为private

  • 相关阅读:
    Algorithm Gossip (48) 上三角、下三角、对称矩阵
    .Algorithm Gossip (47) 多维矩阵转一维矩阵
    Algorithm Gossip (46) 稀疏矩阵存储
    Algorithm Gossip (45) 费氏搜寻法
    Algorithm Gossip (44) 插补搜寻法
    Algorithm Gossip (43) 二分搜寻法
    Algorithm Gossip (42) 循序搜寻法(使用卫兵)
    Algorithm Gossip (41) 基数排序法
    Algorithm Gossip (40) 合并排序法
    AlgorithmGossip (39) 快速排序法 ( 三 )
  • 原文地址:https://www.cnblogs.com/datamining-bio/p/13125938.html
Copyright © 2011-2022 走看看