一個類的定義放在另一個類的內部,這個類就叫做內部類
- 10.1創建內部類
public class First {
public class Contents{
public void f(){
System.out.println("In Class First's inner Class Contents method f()");
}
}
}
這樣的類就叫內部類,內部類了解外部類,并能與之通信
- 10.2 鏈接到外部類
package cn.zlb.innerclass;
interface Selector{
boolean end();
int current();
void next();
}
public class Sequence {
private Object[] items = null;
int next = 0;
public Sequence(int size){
items = new Object[size];
}
public void add(int i){
items[next++] = i;
}
private class SequenceSelector implements Selector{
private int i = 0;
@Override
public boolean end() {
return i==items.length;
}
@Override
public int current() {
// TODO Auto-generated method stub
return (int) items[i];
}
@Override
public void next() {
// TODO Auto-generated method stub
if(i < items.length){ i++;}
}
}
public Selector getSelector(){
return new SequenceSelector();
}
public static void main(String[] args) {
}
}
內部類自動擁有對其外圍類的所有成員的訪問權,因為當某個外圍類創建一個內部類時,次內部類必定會秘密捕獲一個指向外部類的引用用那個引用來訪問外部成員
- 10.3 使用.this 和 .new
內部類中得到當前外圍類對象的引用,可以使用.this關鍵字,.new關鍵字 如果想直接創建一個內部類對象,而不是通過外圍類對象的方法來得到,可以使用.new關鍵字 注意與new的區別
private int num ;
public Test2(){
}
public Test2(int num){
this.num = num;
}
private class Inner{
public Test2 getTest2(){
return Test2.this;
}
public Test2 newTest2(){
return new Test2();
}
}
public static void main(String [] args){
Test2 test = new Test2(5);
Test2.Inner inner = test.new Inner();
Test2 test2 = inner.getTest2();
Test2 test3 = inner.newTest2();
System.out.println(test2.num);
System.out.println(test3.num);
}
- 10.4 內部類與向上轉型
將內部類上轉型為基類時,尤其是轉型為一個接口時,內部類就有了用武之地
public interface Shape {
public void paint();
}
public class Painter {
private class InnerShape implements Shape{
public void paint(){
System.out.println("painter paint() method");
}
}
public Shape getShape(){
return new InnerShape();
}
public static void main(String []args){
Painter painter = new Painter();
Shape shape = painter. getShape();
shape.paint();
}
}
此時,內部類是private的,可以它的外圍類Painter以外,沒人能訪問。 這樣,private內部類給累的設計者提供了一種途徑,通過這種方式可以完全阻止任何依賴于類型的編碼,并完全隱藏實現的細節。
- 10.5在方法和作用域內的內部類
- 10.6匿名內部類
public interface Shape {
public void paint();
}
public class Painter {
public Shape getShape(){
return new Shape(){
public void paint(){
System.out.println("painter paint() method");
}
};
public static void main(String [] args){
Painter painter = new Painter();
Shape shape = painter.getShape();
shape.paint();
}
}
注意匿名內部類一定要以分號結束 在這個匿名內部類中使用了默認的構造器來生成Shape(),如果你的基類需要一個有參數的構造器呢?
如果在這個內部類中需要用到這個參數那么這個參數一定的是final類型的
public class B {
public A getA(int num){
return new A(num){
};
}
}
public class A {
private int num;
public A(int num){
this.num = num;
}
public A(){
}
}
另外,還可以在匿名內部類里定義屬性 由于類是匿名的,自然沒有構造器,如果想模仿構造器,可以采用實例初始化({})
public A getA(){
return new A(){
int num = 0;
String str;
{
str = "javaeye";
System.out.println("hello robbin");
}
};
}
- 10.6.1 使用匿名內部類改造工廠方法
package cn.zlb.factory;
interface Service{
void method1();
void methid2();
}
interface ServiceFactory{
Service getService();
}
class ImplementService1 implements Service{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("ImplementService1 method1");
}
@Override
public void methid2() {
// TODO Auto-generated method stub
System.out.println("ImplementService1 method2");
}
//使用匿名內部類
private ServiceFactory serviceFactory = new ServiceFactory() {
@Override
public Service getService() {
// TODO Auto-generated method stub
return new ImplementService1();
}
};
}
class ImplementServiceFactory1 implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new ImplementService1();
}
}
class ImplementServiceFactory2 implements ServiceFactory{
@Override
public Service getService() {
// TODO Auto-generated method stub
return new ImplementService2();
}
}
class ImplementService2 implements Service{
@Override
public void method1() {
// TODO Auto-generated method stub
System.out.println("ImplementService2 method1");
}
@Override
public void methid2() {
// TODO Auto-generated method stub
System.out.println("ImplementService2 method2");
}
private ServiceFactory serviceFactory = new ServiceFactory() {
@Override
public Service getService() {
// TODO Auto-generated method stub
return new ImplementService2();
}
};
}
public class factory {
public static void method(ServiceFactory sf){
Service s = sf.getService();
s.methid2();
s.method1();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
method(new ImplementServiceFactory1());
method(new ImplementServiceFactory2());
}
}
- 10.7 嵌套類
static的內部類就叫做嵌套類 前面提到了很多次,嵌套類是個例外 使用嵌套類時有兩點需要注意:
a、創建嵌套類對象時,不需要外圍類
b、在嵌套類中,不能像普通內部類一樣訪問外圍類的非static成員
另外,嵌套類還有特殊之處,就是嵌套類中可以有static方法,static字段與嵌套類,而普通內部類中不能有這些 - 10.8為何需要內部類
a、內部類提供了某種進入外圍類的窗戶。
b、也是最吸引人的原因,每個內部類都能獨立地繼承一個接口,而無論外圍類是否已經繼承了某個接口。 因此,內部類使多重繼承的解決方案變得更加完整。 在項目中,需要多重繼承,如果是兩個接口,那么好辦,接口支持多重繼承。 如果是兩個類呢?這時只有使用內部類了。