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

posted @ 2018-11-05 15:01  jimcsharp  阅读(523)  评论(0编辑  收藏  举报