您的位置:首页 > 编程语言 > Java开发

JAVA 构造器, extends[继承], implements[实现], Interface[接口], reflect[反射], clone[克隆], final, static, abstrac

2013-12-17 11:40 786 查看
记录一下:

构造器[构造函数]:

在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

并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐