java基础----final与匿名内部类

来源:互联网 发布:电视剧源码 编辑:程序博客网 时间:2024/05/20 22:27

学习中遇到哪个知识点有疑惑,就花点时间学习下,查漏补缺,每天进步一点点!

静态内部类、内部类、匿名内部类,(成员内部类)为什么内部类会持有外部类的引用?持有的引用是this?还是其它?

  • 静态内部类:使用static修饰的内部类
  • 内部类:就是在某个类的内部又定义了一个类,内部类所嵌入的类称为外部类
  • 匿名内部类:使用new生成的内部类
  • 因为内部类的产生依赖于外部类,持有的引用是类名.this

1、匿名内部类(new 父类/接口(){实现具体方法};)

匿名内部类也就是没有名字的内部类

正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

 

实例1:不使用匿名内部类来实现抽象方法

abstract class Person {    public abstract void eat();} class Child extends Person {    public void eat() {        System.out.println("eat something");    }} public class Demo {    public static void main(String[] args) {        Person p = new Child();        p.eat();    }}

运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用

但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类

实例2:匿名内部类的基本实现

abstract class Person {    public abstract void eat();} public class Demo {    public static void main(String[] args) {        Person p = new Person() {            public void eat() {                System.out.println("eat something");            }        };        p.eat();    }}

运行结果:eat something

可以看到,我们直接将抽象类Person中的方法在大括号中实现了

这样便可以省略一个类的书写

并且,匿名内部类还能用于接口上

 

实例3:在接口上使用匿名内部类

interface Person {    public void eat();} public class Demo {    public static void main(String[] args) {        Person p = new Person() {            public void eat() {                System.out.println("eat something");            }        };        p.eat();    }}

运行结果:eat something

 

由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口

 

实例4:Thread类的匿名内部类实现

public class Demo {    public static void main(String[] args) {        Thread t = new Thread() {            public void run() {                for (int i = 1; i <= 5; i++) {                    System.out.print(i + " ");                }            }        };        t.start();    }}


运行结果:1 2 3 4 5

 

实例5:Runnable接口的匿名内部类实现

public class Demo {    public static void main(String[] args) {        Runnable r = new Runnable() {            public void run() {                for (int i = 1; i <= 5; i++) {                    System.out.print(i + " ");                }            }        };        Thread t = new Thread(r);        t.start();    }}

运行结果:1 2 3 4 5

参考文章:http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html

 

Android里面的匿名类与匿名内部类使用


android开发中经常碰到匿名类(和匿名内部类)的使用,那么匿名类和一般情况下使用的类有什么不同,

从实现的功能来讲是一样的,但是使用匿名更加简洁方便,形式上有点像new一个接口或类的感觉,但是我们必须

记住接口是不可以new出来的(实例化),我们要在内部重写需要的接口的方法,这样就new出了一个实现接口

方法的对象,但是这个对象的类名不可见,所以叫做匿名类。下面是功能相同的两段代码,分别用上述两种写法

实现:

匿名类

形式如下:new <类或接口> <类的主体>

button.setOnClickListener(listener );private View.OnClickListener listener = new View.OnClickListener()    {        @Override        public void onClick(View v)        {            String phonenum = phoneEditText.getText().toString();            Intent intent = new Intent("android.intent.action.CALL", Uri.parse("tel:" + phonenum));            startActivity(intent);        }    };// 在这里需要一个分号

自定义继承接口的类

button.setOnClickListener(new ButtonListener());private final class ButtonListener implements View.OnClickListener{    public void onClick(View v)    {            EditText mobileText = (EditText)findViewById(R.id.mobile);            String mobile = mobileText.getText().toString();            Intent intent = new Intent();            intent.setAction("android.intent.action.CALL");            intent.setData(Uri.parse("tel:"+ mobile));            startActivity(intent);    }}

匿名类不等同于匿名内部类

 

匿名类不等同于匿名内部类,后者也经常使用,匿名内部类是内部类的一种,使用的时候更加简洁,但是不是任何情况下都需要使用。

在thinking in java 3th 是这么阐述的:

 

简单地说:匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较

合适的:

  ·只用到类的一个实例。
  ·类在定义后马上用到。
  ·类非常小(SUN推荐是在4行代码以下)
  ·给类命名并不会导致你的代码更容易被理解。
  在使用匿名内部类时,要记住以下几个原则:

  ·匿名内部类不能有构造方法。
  ·匿名内部类不能定义任何静态成员、方法和类。
  ·匿名内部类不能是public,protected,private,static。
  ·只能创建匿名内部类的一个实例。
·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
  ·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。 

2、final

final在Java中并不常用,然而它却为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员、方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中拥有了一个不可或缺的地位,也是学习Java时必须要知道和掌握的关键字之一。


final 关键字表示'终态的','无法改变的', 它可以修饰非抽象类,非抽象方法及变量 

final类不能被继承,没有子类,final类中的方法默认是final的 
final方法不能被子类覆盖,但可以继承 
final变量只能一次赋值,不可更改 
final不能修饰构造函数 

final方法 
将方法声明为final,那就说明你已经知道这个方法提供的功能已经满足你要求,不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。另外有一种被称为 inline的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那么你的调用主体代码便会迅速膨胀,可能反而会影响效率,所以你要慎用 final进行方法定义。

1. final类 
   final类不能被继承,没有子类,final类中的方法默认是final的。 
   如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为   final类 

2. final方法 
   final方法不能被子类覆盖,但可以继承 
   第一、把方法锁定,防止任何继承类修改它的意义和实现。 
   第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 

3. final变量/常量 
   用final修饰的成员变量表示常量,值一旦给定就无法改变。 
   final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译   器都确保空白final在使用之前必须 被初始化 

5. static final 
   对于变量,表示一旦给值就不可修改,并且通过类名可以访问。 
   对于方法,表示不可覆盖,并且可以通过类名直接访问。 
   对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,但可以修改容器中存放的对象.

 

final在Java中并不常用,然而它却为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员、方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中拥有了一个不可或缺的地位,也是学习Java时必须要知道和掌握的关键字之一。
final成员 
当你在类中定义变量时,在其前面加上final关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对基本类型来说是其值不可变,而对于对象变量来说其引用不可再变。其初始化可以在两个地方,一是其定义处,也就是说在final变量定义时直接给其赋值,二是在构造函数中。这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时既在定义时给了值,又在构造函数中给另外的值。下面这段代码演示了这一点:

http://www.cnblogs.com/qinqinmeiren/archive/2011/07/14/2151692.html



0 0