[JAVA] Thinking In Java细节复习(二)

来源:互联网 发布:熊猫弹幕机器人软件 编辑:程序博客网 时间:2024/06/07 07:25

1.final的作用与范围:

class Value {       int i = 1;}public class FinalData {       // Can be compile-time constants       final int i1 = 9;       static final int I2 = 99;       // Typical public constant:       public static final int I3 = 39;       // Cannot be compile-time constants:       final int i4 = (int)(Math.random()*20);       static final int i5 = (int)(Math.random()*20);          Value v1 = new Value();       final Value v2 = new Value();       static final Value v3 = new Value();       final int[] a = { 1, 2, 3, 4, 5, 6 };     public void print(String id) {              System.out.println(id + ": " + "i4 = " + i4 + ", i5 = " + i5);     }       public static void main(String[] args) {              FinalData fd1 = new FinalData();              //! fd1.i1++; // Error: can't change value              fd1.v2.i++; // Object isn't constant!              fd1.v1 = new Value(); // OK -- not final              for(int i = 0; i < fd1.a.length; i++)                     fd1.a[i]++; // Object isn't constant!              //! fd1.v2 = new Value(); // Error: Can't               //! fd1.v3 = new Value(); // change handle              //! fd1.a = new int[3];          fd1.print("fd1");              System.out.println("Creating new FinalData");          FinalData fd2 = new FinalData();              fd1.print("fd1");              fd2.print("fd2");      }}输出:fd1: i4 = 15, i5 = 9 Creating new FinalData fd1: i4 = 15, i5 = 9 fd2: i4 = 10, i5 = 9
通过输出的值可以看出,Static 强调它们只有一个,但是是可以改变的,而 final 则表明它是一个常数。


2.我们也可以将一个类设置为final。例如:

final class A{int i = 1;}
这就表明我们不希望任何类从类A继承,但除此之外,并不会对类A有更多的限制,类A的数据成员可以不是final。然而因为禁止了继承,所以类中的方法默认为final,无法对他们进行覆盖。


3.内部类:创建自己的内部类时,那个类的对象同时拥有 指向封装对象(这些对象封装或生成了内部类)的一个链接。所以它们能访问那个封装对象的成员——毋需 取得任何资格。除此以外,内部类拥有对封装类所有元素的访问权限。
在Java中内部类主要分为成员内部类、局部内部类、匿名内部类、静态内部类。
1. 成员内部类:成员内部类中不能存在任何static的变量和方法;成员内部类是依附于外围类的,所以只有先创建了外围类才能够创建内部类。
2.局部内部类:它是嵌套在方法和作用于内的,对于这个类的使用主要是应用与解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类,局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效。
3.匿名内部类:匿名类没有名字,必须要继承一个父类或者实现一个接口

public abstract class Bird {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }        public abstract int fly();}public class Test {        public void test(Bird bird){        System.out.println(bird.getName() + "能够飞 " + bird.fly() + "米");    }        public static void main(String[] args) {        Test test = new Test();        test.test(new Bird() {                        public int fly() {                return 10000;            }                        public String getName() {                return "大雁";            }        });    }}------------------Output:大雁能够飞 10000米

在使用匿名内部类的过程中,我们需要注意如下几点:
  1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
  2、匿名内部类中是不能定义构造函数的。
  3、匿名内部类中不能存在任何的静态成员变量和静态方法。
  4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
  5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

4.静态内部类:static内部类意味着: 
(1) 为创建一个 static内部类的对象,我们不需要一个外部类对象。 
(2) 不能从 static内部类的一个对象中访问一个外部类对象。 
由于static 成员只能位于一个类的外部级别,所以内部类不可拥有static 数据或 static内部类。 倘若为了创建内部类的对象而不需要创建外部类的一个对象,那么可将所有东西都设为static。通常,我们不在一个接口里设置任何代码,但 static内部类可以成为接口的一部分。由于类是“静态”的, 所以它不会违反接口的规则。


为什么要使用内部类:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建内部类对象的时刻并不依赖于外围类对象的创建。
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。




0 0