zoukankan      html  css  js  c++  java
  • 重新精读《Java 编程思想》系列之组合与继承

    Java 复用代码的两种方式组合与继承。

    组合

    组合只需将对象引用置于新类中即可。
    比如我们有一个B类,它具有一个say方法,我们在A类中使用B类的方法,就是组合。

    public class B {
    
        public void say(){
    
        }
    }
    public class A {
    
        public void combo(){
            B b = new B();
            b.say();
        }
    }
    

    在 java编程思想中,还介绍了四种初始化引用的方式。
    1、在定义对象的地方。

    public class Bath{
        private String s1 = "happy";
        public Bath(){};
    }
    

    2、在构造器中

    public class Bath{
        private String s1;
        public Bath(){
            s1="happy";
        };
    }
    

    3、在使用对象的时候,进行初始化,也叫惰性初始化。这种方式可以减少额外的负担。

    class Lazy{
    }
    public class Bath{
        private Lazy lazy;
        public Bath(){
          
        };
        public void initLazy(){
            lazy = new Lazy();
        }
    }
    

    这样当只有调用Bath的initLazy方法的时候,Lazy对象才会被初始化,不调用的时候,不会被初始化。
    4、使用实例初始化。
    这种最简单了,我们经常使用的实例初始化就是这样的。

    public class Bath{
        public static void main(String args){
            Bath bath = new Bath();
        }
    }
    

    继承

    当我们创建一个类的时候,无时无刻不在继承,如果我们没有明确的指出继承哪个类,隐式的继承 Object 类。
    继承使用的extends关键字,子类会继承父类的所有成员变量和方法。
    继承的一个大原则就是,我们将所有的数据成员置为private,将方法设置为public。这样可以便于其他类访问被继承类的所有方法。
    Java 使用 super关键字来调用父类的构造方法。
    在子类继承父类的时候,会自动调用父类的构造函数,如果都是无参的构造函数,则不需要显示调用,如果是有参的构造函数,子类继承的时候就需要显示的用super调用。

    class Art {
        Art(){
            System.out.println("art");
        };
    }
    
    class Drawing extends Art{
        Drawing(){
            System.out.println("Drawing");
        }
    }
    
    public class Cartoon extends Drawing{
        Cartoon(){
            System.out.println("cartoon");
        }
    
        public static void main(String[] args) {
            Cartoon cartoon = new Cartoon();
        }
    }
    

    结果如下:

    如果我们的构造函数是有参的。子类继承,不调用则会提示。

    我们必须使用super显示的调用

    class Art {
        Art(String s){
            System.out.println("art");
        };
    }
    
    class Drawing extends Art{
        Drawing(){
            super("a");
            System.out.println("Drawing");
        }
    }
    

    书中这里有一道练习题,证明基类构造器,a、总是会被调用,b、在导出类构造器之前被调用。
    上面的例子,同时证明了两点。子类构造器的代码总是最后执行的。然后父类构造器中的打印代码会打在控制台上。

    代理

    在书中还介绍了一个概念代理,说是代理也是复用的一种形式。那么这个怎么理解呢。
    书中的例子举的是十分好的。
    比如我们有一个太空船的控制模块。这里简略我们只写一个想上飞和向下飞的代码。

    public class SpaceShipControls{
        void up(int a){};
        void down(int a){};
    }
    

    我们再建立一个太空飞船,飞船肯定是可以向上飞和向下飞的。所以我们第一种方案采用继承的方式。直接调用控制器的代码。

    public class SpaceShip extends SpaceShipControls{
        public static void main(String[] args){
            SpaceShipControls s = new SpaceShipControls();
            s.up(100);
        }
    }
    

    目前来看控制器的所有方法,我们太空飞船都有了。从某种意义上说 太空飞船成为了太空控制器。事实不应该这样的,应该是太空飞船向太空控制器发送指令。
    我们使用代理的方式,来创建这段代码,再来看下。

    public class SpaceShipDelegation{
        private SpaceShipControls s = new SpaceShipControls();
        
        public void up(int a){
            s.up(a);
        }
    
        public void down(int a){
            s.down(a);
        }
    
        public static void main(String args){
            SpaceShipDelegation sa = new SpaceShipDelegation();
            sa.up(100);
        }
    }
    

    通过这种代理的方式,我们可以拥有更多的控制能力,可以选择提供再成员对象方法中的某个子集。

  • 相关阅读:
    EF6 Code First 模式更新数据库架构
    bootstrap-datepicker 插件修改为默认中文
    常用网络资源下载
    jQuery框架学习第十一天:实战jQuery表单验证及jQuery自动完成提示插件
    AngularJS实现原理
    [个人翻译]GitHub指导文件(GitHub Guides[Hello World])
    年后跳槽如何准备?
    前端学数据库之子查询
    Ionic实战 自动升级APP(Android版)
    读书笔记:《HTML5开发手册》Web表单
  • 原文地址:https://www.cnblogs.com/jichi/p/12051979.html
Copyright © 2011-2022 走看看