学习笔记(五)接口与内部类(一)

来源:互联网 发布:空间坐标系旋转矩阵 编辑:程序博客网 时间:2024/05/16 00:32

《Java编程思想》整理的一些学习笔记,有不对的地方,欢迎指出。

1.选择在接口中显示的将方法声明为public的,但即使你不这么做,它们也是public的。因此,当要实现一个接口的时候,在接口中被定义的方法必须被定义是public的;否则,它们将只能得到缺省的包访问权限,这样在方法被继承的过程中,其可访问权限就被降低了,这是Java编译器所不允许的。

2.使用接口的核心原因:为了能够向上转型为多个基类型。另一个原因是与使用抽象基类一样:防止客户端程序员创建该类的对象,并确保这仅仅是一个接口。现在有这么一个例子:class A  继承了 class B  实现了 接口C 和接口D,其中 class B {public void fight()},interface C{void fight();} interface D{void fly();}此时class A 中定义为 {public void fly()}。这看起来很奇怪,因为实现接口,就必须实现接口中的方法,而A显然没有实现接口C中方法,却没有错误。因为A 继承 了B,B中已经对 fight();提供了定义,所以它是被自动提供的。

3.接口也可以包含字段,但是它们隐式为static和final的。接口只提供了形式,而未提供任何具体实现。

4.类中可以嵌套接口,可以将接口声明为private类型。接口中也可以嵌套接口,但是不可以声明为private类型,因为所有的接口中的元素都必须是public的。

5.可以将一个类的定义放在另一个类的定义内部,这就是内部类。内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。然而必须要了解,内部类与组合是完全不同的概念。

6. 外部类中有一个方法,该方法返回一个指向内部类的引用,想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须像在main()方法中那样,具体的指明这个对象的类型:OuterClassName.InnerClassName。例子:

public class C {
class D {
private int i = 10;
public int value(){return i;}
}
public D get(){
return new D();
}
    public static void main(String[] args){
    C c = new C();
    //! D d = new D();
    C.D d = c.get();
    System.out.println(d.value());
}
}

当取得了一个指向基类或接口的引用时,甚至可能无法找出它确切的类型,例子:

interface Dinf{
int value();
}
class C {
private class D implements Dinf{
private int i = 10;
public int value(){return i;}
}
public D get(){
return new D();
}
}
public class E {
public static void main(String[] args){
C c = new C();
Dinf a = c.get();
System.out.println(a.value());
}
}

内部类D 是private ,除了C,没有人能访问它。这意味着,如果客户端程序员想了解或访问这些成员,那是要受限制的。实际上,甚至不能向下转型成private内部类,因为不能访问其名字。于是private内部类给类的设计者提供了一种途径,通过这种方式可以完全阻止任何依赖于类型的编码,并且完全隐藏了实现的细节。此外,从客户端程序员的角度来看,由于不能访问任何新增加的,原本不属于公共接口的方法,所以扩展接口是没有价值的。这也给Java编辑器提供了生成更高效代码的机会。    普通的(非内部类)类,不能声明为private或protected;它们只可以被赋予public或者包访问权。

7.public class A {
public C c(){
return new C(){
 // return new C (x){
private int i = 10;
public int values(){
return i;
// return super.value()*47;
}
};
}
public static void main(String[] args){
A a = new A();
C c =a.c();
}
}

c()方法将返回值的生成与表示这个返回值的类的定义结合在一起!另外,这个类是匿名的,它没有名字。更糟的是,看起来像是你正在创建一个C 对象:return new C() 但是然后在分号结束前你却说:“等一等,我想在这里面插入一个类的定义":

return new C(){
private int i = 11;
public int value(){ return i; }
};

这种奇怪的语法指的是:”创建一个继承自C的匿名类的对象“。通过new表达式返回的引用被自动向上转型为对C的引用。上述匿名内部类的语法是下述形式的简化:

class MyC implements C{
private int i = 11;
public int value(){ return i; }

return new MyC();

上述包括了 如果基类需要一个有参数构造器的情况。如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的。


0 0