zoukankan      html  css  js  c++  java
  • JAVA 构造器, extends[继承], implements[实现], Interface[接口], reflect[反射], clone[克隆], final, static, abstrac

    记录一下:

    构造器[构造函数]:

    在java中如果用户编写类的时候没有提供构造函数,那么编译器会自动提供一个默认构造函数.它会把所有的实例字段设置为默认值:所有的数字变量初始化为0;所有的布尔变量设置为false;所有对象变量设置为null;

    PS:

    只有在类中没有其它构造器的时候,系统才会提供默认构造器.如果你希望用户能能够调用不带参数的构造器,那么你就必须自己实现一个.


    extends[继承]:

    java中的继承,和C++中是有差别的.比如JAVA不支持多重继承。但是JAVA可以通过implements来实现额外的接口.

    Example:

    DogDeriveClass extends AnimalBaseClass
    {
    };

    这样DogDeriveClass就全盘继承了AnimalBaseClass中的所有方法;但是没有多重继承,那么如果还需要其它功能,那么则可以通过implements关键字来实现需要用到的接口.

    Example:

    DogDeriveClass extends AnimalBaseClass

    Implements Shot, Run
    {
         void Shot()
         {
         // Do shout something;
         }
        void Run()
        {
        // Do run something;
        }
    };

    从上面代码可以看到,虽然JAVA不支持多重继承,但是派生类可以通过实现接口的方式,来实现本身需要继承过来的功能.

    Implements[实现]:

    Implements关键字在class声明中使用,以指示所声明的类提供了在implements关键字后面的名称所指定的接口中所声明的所有方法的实现。

    接口中的字段[变量]默认是public static final类型; //从接口的调用方式可以看出来. Implements Interface.MethedOfInterface();

    接口中的方法不能是static,因为static不能被派生类重写,因为如果接口和派生类中都有一个static同名方法,那么根据static的调用方式可以看到

    Interface.StaticMethed()即可调用,但是Interface中并没有该方法的实现,只有在具体实现类中有实现,如果有两个派生类都实现了同名的static方法,则该怎么调用?

    虚拟机也不知道了!!所以不能这么做.

    Example:

    public class UserSurfaceView extends SurfaceView
    implements Android.view.SurfaceHolder.Callback  
    {
         @Override
         public void surfaceChanged(SurfaceHolder holder, int format, int with, int heigh)
         {
         //TODO Auto-generated method stub
         }
        @Override
         public void surfaceCreated(SurfaceHolder holder)
         {
         //TODO Auto-generated method stub
         }
         @Override
         public void surfaceDestroyed(SurfaceHolder holder)
         {
         //TODO Auto-generated method stub
         }
    };

    UserSurfaceView类就要实现SurfaceHolder对象中的Callback接口中所声明的所有方法的实现: surfaceChanged/surfaceCreated/surfaceDestroyed

    从SDK上看到Android.view是包名,SurfaceHolder是一个public的interface, 而Callback就自然是public static interface[从调用方式即可看出来:Android.view.SurfaceHolder.Callback ]


    Interface[接口]:

    从上面implements关键字我们已经大概的了解到了关于java中接口的相关知识,下面看看接口的声明:

    Example:
    public interface Android.view.SurfaceHolder.Callback
    {
             void surfaceChanged(SurfaceHolder holder, int format, int with, int heigh);
            void surfaceCreated(SurfaceHolder holder);
            void  surfaceDestroyed(SurfaceHolder holder);
    };
    由于接口中的方法声明默认就是public的,因此不需要特意加上public修饰符.

    reflect[反射]:

    能够分析类的能力的程序称为反射器,JAVA中提供此功能的包是java.lang.reflect.它主要是针对工具构建者而不是应用程序员的.如果你只对编写应用程序感兴趣,而不想了解如何编写供其它java程序员使用的工具,那么就不要了解该机制.

    java的反射机制主要提供了以下功能:

    1.在运行时判断任意一个对象所属的类;
    2.在运行时构造任意一个类的对象;
    3.在运行时判断任意一个类所具有的成员变量和方法[通过反射机制甚至可以调用private方法];
    4.在运行时调用任意一个对象的方法;

    java.lang.reflect包中包括下面几个主要:
    0.Class类,描述类相关信息;
    1.Field类,描述类的字段;
    2.Method类,描述类的方法;
    3.Constructor类,描述类的构造器;
    3.Array类,描述类的创建动态数组的方法,该类中所有的方法都是静态属性;

    下面我们开始介绍一些具体的用法:
    A.Class类:
        在JAVA的Object类中声明了若干个可以在所有的JAVA类中改写的方法:

    hashCode()/equals()/clone()/toString()/getClass()等,其中getClass()返回一个Class类型的对象.

        Class类和一般的类一样继承自Object, 其实体用于表达JAVA程序运行时的class和interface,以及enum, array, primitive, JAVA types和关键字void,当加载一个类时,或者当加载器[class loader]的defineClass()被JVM调用,便产生一个Class对象.

        Class是Reflection起源,针对任何你想查看的Class(类),必须先给该类生成一个Class的对象,然后才能通过这个对象调用相应的反射API。

        JAVA提供了多种途径来为一个Class类生成对应的Class对象:

        A,getClass(): Object类中的方法每个类都拥有该方法.

             Example:

             String str = "Test getClass()";

             Class cl = str.getClass();

        B,Class.getSuperclass(): Class类中的方法,返回该Class的父类的Class;

        C,Class.forName()静态方法:作用同上;

        D,类名.Class: 作用同上;

        E,primitive wrapper classer的TYPE语法:

            基本类型包装类的TYPE,Example, Integer.TYPE

            PS: TYPE的使用,只适合原生[基本]数据类型.

    B.运行时生成instance

           要生成对象的实体,在反射机制中有两种方式:

           1.针对不带参数的构造器;

               Class类中的newInstance()实现该功能;

           2.针对带参数的构造器;

               Constructor类中的newInstance()方法,实现该功能.首先准备一个Class[]作为Constructor的参数类型.然后调用该Class对象的getConstructor()得到一个专属的Constructor对象,最后再准备一个Object[]作为 Constructor对象里的newInstance()的实参.

               Example:

               Class c = Class.forName("DynamicTest");

               Class[]  pType = new Class[]{double.class, int.class};

               Constructor ctor = c.getConstructor(pType);

               Object[] obj = new Object[] {new Double(3.14), new Integer(119)};

               Object object = ctor.newInstance(obj);

               System.out.println(object);

     

    C. 运行时调用Method:

          首先必须通过Class[]作为getMethod(String name, Class[])方法的参数类型, 然后再通过Object[]存放变量,最后调用Method对象的invoke(Object obj, Object[])方法.

    D.运行时调用Field内容:

          修改Field不需要参数和变量, 首先调用Class的getField()方法并制定Field名称,获得特定的Field对象后便可以直接调用Field的get(Object obj)和Set(Object obj, Object value)方法.       


    克隆[clone]:

    其实这个方法的引入,就是为了实现类似C++中深拷贝的功能.在C++中参数的传递有:传值,传地址,传引用.

    在JAVA中参数传递、=的赋值操作都是"引用传递[浅拷贝]",因此为了避免误操作,在需要传值的时候就不能进行传引用.

    PS:如果类成员变量有数组或者复杂成员时需要进行深度克隆.浅拷贝只复制对象本身,并不复制该对象的引用、指针等成员所指向的地址.

           try{

            classObj = (classObject) super.clone(); // 通常情况下,这一行代码可以实现普通的克隆.

           }
           catch(CloneNotSupportedException e)
           {
                e.printStackTrace();
           }
            如果classObject类中包含了String name[]成员,那么就需要进行深度克隆
            try{
            classObj = (classObject)super.clone();
            classObj.name = (String)name.clone();
            }
           catch(CloneNotSupportedException e)
           {
                e.printStackTrace();
           }
    final:

    一般处于设计和效率的考虑使用final,第一final类不被继承、方法不被覆盖.第二final方法会被编译器在调用final的时候转入内嵌机制大大提高执行效率.第三防止被修改;
    final类不能被继承,final类不能有子类,final类中的方法默认是final类型.
    final方法不能被子类的方法覆盖,但可以被继承;
    final成员变量表示常量,只能赋值一次,赋值后不能再改变;
    final不能修饰构造器;
    PS:父类的private方法是不能被子类方法覆盖的,因为父类的private方法默认是final的;
    static:
    JAVA中的静态字段和方法在功能上和C++的静态字段与方法是相同的.表示属于一个类而不是属于此类的任何特定对象的变量和函数.
    调用方式:
    className.staticMethod();
    只要这个类被加载,那么JAVA虚拟机就能根据类名在运行时的数据区的方法区内找到它们;
    静态字段在内存中只有一个拷贝,JVM只为静态字段分配一次内存,在加载类的过程中完成对静态字段的内存分配;

    abstract:
    抽象类,具有一个或多个抽象方法的类必须被声明为abstract.通常要尽可能的把通用字段和非常抽象方法移到抽象超类中.
    Object类:
    Object类是JAVA中所有类的最终的祖先------每一个类都由他扩展而来.
    Internal Class内部类:
    内部类是定义在其它类内部的类,一般使用内部类有四个原因:
    1.内部类对象能够访问创建它的对象的实现---包括那些私有数据;
    2.内部类能够隐藏起来,不为同一包中的其它类所见;

    3.匿名内部类可以方便的定义运行时回调;
    4.使用内部类在编写事件驱动的程序时用起来很方便;
    PS:
    本地内部类与匿名内部类的区别在于本地内部类有构造函数,而匿名内部类只能实例初始化。
    Example:
          Thread thd = new Thread(
           new A(){//这里就是一个匿名内部类
                         }
           )
    Proxy[代理]:
    通过使用代理可以在运行时创建实现一组给定接口的新类.
    代理类具有:
    指定接口所要求的所有方法;
    Object类定义的所有方法(toString, equals等等);
    因为我们不能在运行时给这些方法定义新的代码.你必须提供一个调用处理器.调用处理器是实现了InvocationHandler接口的任意类的对象.该接口只有一个方法:
    Object invoke(Object proxy, Method method, Object[] args)
    只要调用了代理对象上的任意一个方法,调用处理器的invoke方法就会被调用,带着Method对象和原调用的参数.随后调用处理器必须指出如何处理调用.
    要创建一个代理对象,我们必须使用proxy类中的newProxyInstance方法,该方法有三个参数:
    1>类加载器.
    2>一个Class对象数组,每个元素都是需要实现的接口;
    3>一个调用处理器;
    如何定义处理器?
    对结果代理对象能做些什么?
    答案要取决于我们要使用代理机制解决的问题.代理可以用于很多目的:
    a.路由对远程服务器的方法调用;
    b.在运行程序中把用户界面事件和动作关联起来;
    c.为调试目的跟踪方法调用;

    java 中final,static,super,extends,implements,abstract   

    final
     1.final str;
         定义常量
     2.final 方法    
         一是为了锁定方法,使继承类使用方法,不能修改方法,不会被覆盖
         二是效率
     3.final 类
         不能继承,没有子类
    static
        static定义的成员可以称之为“类成员”,与类的对象无关,属于类,或者说是整个类的对象所共有

    super
       对于父类成员(方法?)子类可以重载,可以覆盖。创建子类对象时,包含从父类继承来的成员。

       如果子类覆盖了父类的方法,子类对象可以通过使用super来调用父类的方法。(若不用super,则调用的是子类的方法)

    extends
       本意是拓展,java中叫做继承,它既可以是class(类)继承class,也可以是interface(接口)继承interface,“继承”顾名思义就是把他的父类(super class)里面的非final修饰的property(属性)、method(方法)的功能原封不动的拿过来用,注意super class也不能是final修饰的;JAVA中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但 implements可以实现多个接口,用逗号分开就行了
    比如 : class A extends B implements C,D,

    implements
       是实现interface(接口),接口里面只给你提供了方法的名称,参数和返回值,你需要在他的实现里面去具体化这些方法,即implements(实现)这个接口的具体功能;

     1:父类和子类如果都是abstract,那么子类无需实现父类的abstract method,等待后面的子类去实现;
     2:父类是abstract,子类不是abstract,那么子类必须实现父类的abstract method;
     3:当父类不是abstract时,不管子类是不是abstract,其中的方法无特殊要求;
     4:当父类和子类中含有同名method(非abstract)的时候(重载),若都是private,那么两个method互不影响,否则,调用的时候,优先调用子类的方法。

    abstract
      并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。

  • 相关阅读:
    Python开发基础--- IO模型
    进程队列补充-创建进程队列的另一个类JoinableQueue
    Python开发基础--- Event对象、队列和多进程基础
    Python开发基础---多线程锁机制
    Python开发基础----多线程
    Python开发基础----socket套接字基础2
    Python开发基础----异常处理、socket套接字基础1
    Python开发基础----反射、面向对象进阶
    Python开发基础---多态与多态性、绑定方法和非绑定方法
    ubuntu添加新用户
  • 原文地址:https://www.cnblogs.com/jimcsharp/p/9909180.html
Copyright © 2011-2022 走看看