一、接口
1.接口是public的,即使不声明,也默认是public。接口中的方法也必须是public。
2.在无法修改想要使用的类时,可以使用适配器模式。适配器接受你所拥有的接口,并产生你所需要的接口。
Thinking in JAVA P177的例子。
有两个类,Processor和Apply, Apply中用到Processor对象。现在有一个类Filter,有跟Processor一样的方法,但是因为Apply和Processor的耦合太强了,所以Filter类不能直接复用Apply中的代码。这时候可以创建一个类FilterAdapter让他继承Processor,同时这个类中聚合一个Filter对象,用Filter对象去完成processor的方法实现。这样Apply中就可以使用FilterAdapter,从而达到使用Filter的效果。这个例子同时也是代理模式。
3.使用接口的核心原因是可以向上转型为多个基类,第二个原因是防止客户端程序员创建该类的对象,确保这仅仅是一个接口。
如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类。如果知道某事物应该成为一个基类,那么第一选择应该是使它成为一个接口。
另外,使用接口而不是类的强大之处是:
我们可以在任何现有类上添加新的接口,所以这意味着让方法接受接口类型,是一种让任何类都可以对该方法进行适配的方法。
4.接口可以继承多个接口。。就像。。
interface aa<T> extends Collection<T>,Serializable{}
其中不需要添加collection的方法。
5.接口中定义的域是public,static 和 final的。
6.嵌套接口:
接口可以嵌套在类或其他接口中。
在类中定义的接口可以是private的,在接口中定义的接口必须是public。
当实现某个接口时,并不需要实现嵌套在其内部的任何接口。而且private接口不能再定义它的类之外被实现。
7.工厂方法模式
一个接口,一个产生接口的工厂的接口。 配上各种实现。
二、内部类
1.内部类能访问他的外围对象的所有成员。因为当某个外围类对象创建了一个内部类对象时,此内部类对象必定会秘密地捕捉一个指向那个外围类对象的引用。
在拥有外部类对象之前不能创建内部类对象,除非创建的是嵌套类(静态内部类)。
2.局部内部类
在类的方法中定义的类是局部内部类,只能在方法中使用。但是局部内部类可以外围类的所有成员。如下代码所示。
public class A {
int a=0;
class C{
}
public void hha(){
class B{
int c=a;
}
B b=new B();
}
public static void main(String args[]){
A a=new A();
A.C c=a.new C();
//A.B b=a.new B(); 错误,通不过编译。
}
}
3.匿名内部类
如果在匿名内部类中要使用外部定义的对象(or基本类型),那么必须把参数设置为final。
4.嵌套类
如果不需要内部类对象与其外围类对象之间有联系,那么可以把内部类声明为static,即嵌套类。
普通的内部类对象隐式的保存了一个引用,指向创建它的外围类对象。然而当内部类是static时:
1)要创建嵌套类的对象,不需要其外围类对象。
2)不能从嵌套类的对象中访问非静态的外围类对象。
嵌套类和普通类还有一个区别:普通内部类的字段和方法只能放在类的外部层次上,所以普通内部类不能有static字段和方法,但嵌套类可以有。
5.在接口中的内部类。
正常情况下不能再接口内部放置任何代码,但嵌套类可以作为接口的一部分。在接口中的任何类都自动是public,static 的。如果想要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共用,那么使用接口内部的嵌套类就显得很方便。
6.为什么要用内部类?!
每个内部类都能独立地继承自一个实现,无论外围类是否已经继承某个实现,对于内部类都没有影响。内部类使得多重继承的解决方案变得完整。接口解决了部分问题。
引用另一篇博客(链接:http://blog.csdn.net/ilibaba/article/details/3866537)的回答:
转自知乎的回答:
链接:https://www.zhihu.com/question/21373020/answer/19350215
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1.完善多重继承
- C++作为比较早期的面向对象编程语言,摸着石头过河,不幸的当了炮灰。比如多重继承,Java是不太欢迎继承的。因为继承耦合度太高。比如你是一个人,你想会飞,于是就继承了鸟这个类,然后你顺便拥有了一对翅膀和厚厚的羽毛,可这些玩意你并不需要。所以Java发明了接口,以契约的方式向你提供功能。想想看,你的程序里成员变量会比函数多吗?况且多重继承会遇到死亡菱形问题,就是两个父类有同样名字的函数,你继承谁的呢?其实C++也可以做到这些,那就是定义没有成员变量的纯虚类,而且所有函数都是纯虚函数。可是这些都是要靠程序员自己把握,并没有把这些功能集成到类似Interface这样的语法里。
- 所以Java只支持单重继承,想扩展功能,去实现接口吧。很快Java的设计者就发现了他们犯了矫枉过正的错误,多重继承还是有一定用处的。比如每一个人都是同时继承父亲和母亲两个类,要不然你的身体里怎么能留着父母的血呢?Java内部类应运而生。
- 用来开发GUI的Java Swing使用了大量内部类,主要用来响应各种事件。Swing的工作就是在事件就绪的时候执行事件,至于事件具体怎么做,这由事件决定。这里面有两个问题:1.事件必须要用到继承2.事件必须能访问到Swing。所以必须把事件写成内部类。
- 内部类是面向对象的闭包,因为它不仅包含创建内部类的作用域的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。一般使用一个库或类时,是你主动调用人家的API,这个叫Call,有的时候这样不能满足需要,需要你注册(注入)你自己的程序(比如一个对象),然后让人家在合适的时候来调用你,这叫Callback。
- 当父类和实现的接口出现同名函数时,你又不想父类的函数被覆盖,回调可以帮你解决这个问题。
7.内部类的继承
public class A {
class C implements Comparable<String>,Serializable{
C(){}
@Override
public int compareTo(String o) {
// TODO 自动生成的方法存根
return 0;
}
class CInnner{}
}
class D extends C.CInnner{
D(C c){
c.super();
}
}
}
看到在D中,D的构造函数必须包含C的对象的参数。因为在C的CInner类的子类中已经不存在可连接的默认对象了。
8.闭包?不懂。
9.内部类与控制框架?还是不懂。
留两个坑。待填。