• Java编程思想(四) —— 复用类


    看了老罗罗升阳的专訪,不由自主地佩服,非常年轻,我之前以为和罗永浩一个级别的年龄。也是见过的不是初高中编程的一位大牛之中的一个,专訪之后。发现老罗也是一步一个脚印的人。

    别说什么难做,做不了。你根本就没去尝试。也没有去坚持。


    If you can't fly then run,if you can't run then walk, if you can't walk then crawl,but

    whatever you do,you have to keep moving forward——Martin Luther King.


    复用类这标题刚開始非常难懂。后面专门去看了书的英文原版。事实上标题是reusing classes,又一次使用类,事实上复用就是“利用现成的东西”的意思。事实上实现的两种方法就是java中常常听到的——组合和继承。


    (1)组合

    has-a的作用。

    public class TV {
       Show show;
       public String toString(){
         return "showgirl";
       }
    }
    
    class Show{
    }

    提一下toString方法,当你须要String而你是一个对象的时候,编译器会调用对象的toString方法。

    TV里有Show,如今的show没有初始化。为null,不能调用show的方法。


    组合的作用强大,以面向对象看,假如你在造一个Car类,那么你能够用组合轻易的将Glass,Light,Engine等等的Car这些部件组合起来。


    (2)继承

    is-a

    package com.myown.iaiti;
    
    public class Father {
         public int i;
         void get(){
             System.out.println("father");
         }
    }
    
    package son;
    import com.myown.iaiti.*;
    
    public class Son extends Father{
            Father f = new Father();
            int j = f.i;
            Son son = new Son();
            son.get();
        }
        
        public void get(){
            super.get();
            System.out.println("son");
        }
    }
     

    这里有个包訪问权限的问题,假如没有加public的时候。默认是包内成员訪问。不同包訪问,即Son中的Father成员訪问get方法是不可见的。而public的话是可见的,所以i訪问得到。


    private部分是不能继承,属于父类私有,而public的部分。将继承,须要改动的方法,能够进行重写。要加入的属性能够单独加入。


    并且继承的方法。假设原本的father的public方法重写之后没将public加上,会有Cannot reduce the visibility of the inherited method from Father,也就是不能降低父类中继承方法的可见性。

    super指的是父类,即Father。


    另一点是,事实上java中全部的类都隐式地继承了Object类。Object是父类,其它类是子类

    老外喜欢讲为基类。子类也叫导出类或者派生类。


    (3)代理

    设计模式里面有个比較难懂的——代理模式,作者讲的非常有趣。代理是组合和继承的中庸之道。

    package son;
    class Father{
        public void get(){
            System.out.println("father");
        }
    }
    public class Son extends Father{
        public static void main(String[] args) {
            Father f = new Father();
            f.get();
        }
    }
    
    class FatherProxy{
        private Father f = new Father();
        public void get(){
            f.get();
        }
    }

    像直接把Father当做成员,那么father的方法就暴露给这个类了,那我们能够使用FatherProxy这种代理类。我自定义好get方法是怎么拿的,我自己知道是调用father的get方法。可是使用我这个代理的人不知道,我仅仅告诉他你要用就用代理的get的方法就能够了。封装性就体现出来了。上面仅仅是随便敲的一个简单样例。


    (4)重写和重载

    class Father{
        public void get(String s){
            System.out.println("father");
        }
        
        public void get(boolean b){
            System.out.println("boolean");
        }
    }
    public class Son extends Father{
        @Override
        public void get(String s){
            System.out.println("father");
        }
        
       // @Override //会有错误提示 由于父类没有该方法,不是重写
        public void get(int i ){
            System.out.println("sonint");
        }
        
        public static void main(String[] args) {
            Son s = new Son();
            s.get("d");
            s.get(false);
            s.get(1);
        }
    }

    重写是又一次覆盖父类的方法,假设没有重写或者重载。那么子类调用一个子类没有的方法时,事实上是调用父类。


    重载是相同的方法名,但參数名称不同,为了防止你错误的进行重载能够加上@Override标签,那样会提示你并没有重写方法。


    (5)protected

    Java编程思想(三) —— 訪问权限的控制
    在前面一篇提前写了,由于之前没讲继承的东西。


    能够简单将protected看成父类给儿子继承的遗产,其它非继承类不能訪问。


    (6)finalkeyword

    加上finalkeyword的基本类型,表示这个变量初始化后不会改变。类似c的define。你希望一个变量在这个程序里就是这个值不须要改变。就能够用final。

    public class Son{
        int  age = 2;
        public static void main(String[] args) {
            
            final int i = 1;
            // i = 2;  值不能再改变
            final Son son = new Son();
            //  son = new Son();
            //The final local variable son cannot be assigned. 
            //It must be blank and not using a compound assignment
            //final修饰的局部变量son不能被分配,必须为空或者不要再次分配
            
            son.age = 4;
            //尽管引用恒定不变。可是,对象本身却能够改变。
        }
        
        void  change(final int c){
            // c= this.age; 无法赋予新值 由于值仅仅有在方法传參决定   对象引用和这个相似
            //age ++;       无法改变
        }
    }

    static本来是静态初始化,和final一起用就是占领了一块不能改变的存储空间。

    static final即编译期常量。常量名依照c的常量命名传统。所实用大写字母。单词之间用下划线分开。

    static final VALUE_ONE = 1。


    final修饰方法时

    public class Print {
        final void cannotprint(){
            System.out.println(1);
        }
    }
    
    public class PrintSon extends Print{
        //void cannotprint(){}
        //无法重写 由于被final修饰了
        
        public static void main(String[] args) {
            PrintSon ps = new PrintSon();
            ps.cannotprint();
        }
    }

    能够看成父类要求子类必须继承的不可改动財产(祖传)。private隐式地指定为final。由于private根本就不给你继承。这比给你继承但不能改动还更私有。


    顺便将权限理清。

    public,公共財产,不止是子类,其它类也能够用。

    final,祖传珍宝,留给子类,但不同意改动。

    private,父类私有財产,不会给子类继承。

    protected。父类专门留给子类的財产,其它人不能用它。


    当final修饰的是类的时候。是为了让这个类不会被继承。


    (7)继承和初始化

    这里的顺序问题是一个非常有趣的问题。

    看样例。

    class GrandFather{
        private static int i = print();
        private static int print(){
            System.out.println("g");
            return 1;
        }
    }
    class Father extends GrandFather{
        private static int i = print();
        private static int print(){
            System.out.println("f");
            return 1;
        }
    }
    public class Son extends Father{
        private static int i = print();
        private static int print(){
            System.out.println("s");
            return 1;
        }
        public static void main(String[] args) {
            System.out.println("first");
        }
    }

    打印的结果是first吗?错了。

    尽管运行的是main方法。可是看到son这个须要静态初始化的i没有,结果是s。first吗?

    这还有初始化的问题,son是继承father。那么编译器会载入father。并初始化i。那father继承grandfather。那么编译器会去载入grandfather,类似递归。

    那最后最先初始化的是grandfather的i。

    所以最后的结果是:g,f,s,first。


    至于这章提到的向上转型。是和多态联系着的,所以放到下一篇来讲。

    面向对象的三大基本特性之中的一个 —— Java编程思想(五) —— 多态。


  • 相关阅读:
    软件工程第一次作业(2)
    软件工程第一次作业
    TR111与STUN
    定制自己的ubuntu 镜像文件 (remastersys, respin, USB live CD)
    上层认证的安全协议 __〈无线局域网安全务实:WPA与802.11i〉读书笔记
    接入控制层的安全协议 __〈无线局域网安全务实:WPA与802.11i〉读书笔记
    WEP 协议__<无线局域网安全务实:WPA与802.11i〉读书笔记
    Python re模块中search与match的区别
    python中如何使用shell命令, 及python 与shell 中的变量相互通信
    sed命令简介及在sed命令中使用变量的方法
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6971541.html
Copyright © 2020-2023  润新知