`

java内部类详解

    博客分类:
  • java
阅读更多

内部类

可以将一个类的定义放在另一个类的定义内部,这就是内部类。

内部类可以是静态static的,也可用public,default,protected和private修饰。

内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。

 

成员内部类

 

public class OuterClass {
	private int outerInt = 1;
	
	private int outerInt2 = 2;
	
	class InnerClass {
		private String str = "inner class";
		
		private int outerInt2 = 3;
		
		public void value() {
			System.out.println(str);
			System.out.println("访问外部类的成员变量outerINt:" + outerInt);
			System.out.println("访问自身成员变量outerINt2:" + outerInt2);
			System.out.println("访问外部类的成员变量outerINt2:" + OuterClass.this.outerInt2);
		}
	}
	
	public static void main(String[] args) {
		OuterClass outer = new OuterClass();
		OuterClass.InnerClass c = outer.new InnerClass();
		c.value();
		
	}
}

 

 

成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。因为当某个外部类对象创建一个内部类对象时,此内部类对象会秘密的捕获一个指向外部类对象的引用。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。

成员内部类不能含有static的变量和方法。

在成员内部类要引用与外部类对象同名的成员变量或者方法时,要使用OuterClassName.this来表示外部类对象;

创建内部类对象,可以使用OuterClassName.InnerClassName  inner = OuterClassObject.new InnerClassName;

 

局部内部类

Thinking in Java给了这么两个例子:

定义在方法内:

 

public class Parcel4 { 
    public Destination destination(String s) { 
        class PDestination implements Destination { 
            private String label; 
 
            private PDestination(String whereTo) { 
                label = whereTo; 
            } 
 
            public String readLabel() { 
                return label; 
            } 
        } 
        return new PDestination(s); 
    } 
 
    public static void main(String[] args) { 
        Parcel4 p = new Parcel4(); 
        Destination d = p.destination("Tasmania"); 
    } 
} 

 

 

定义在作用域里:

 

public class Parcel5 { 
    private void internalTracking(boolean b) { 
        if (b) { 
            class TrackingSlip { 
                private String id; 
                TrackingSlip(String s) { 
                    id = s; 
                } 
                String getSlip() { 
                    return id; 
                } 
            } 
            TrackingSlip ts = new TrackingSlip("slip"); 
            String s = ts.getSlip(); 
        } 
    } 
 
    public void track() { 
        internalTracking(true); 
    } 
 
    public static void main(String[] args) { 
        Parcel5 p = new Parcel5(); 
        p.track(); 
    } 
} 

 

 

局部内部类也像别的类一样进行编译,但只是作用域不同而已,只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的。

局部内部类只能访问方法体中的常量,即用final修饰的成员。

外围类看不见方法中的局部内部类的,但是局部内部类可以访问外围类的任何成员。

方法体中可以访问局部内部类,但是访问语句必须在定义局部内部类之后。

注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

 

静态内部类

 

class Outter {
    public Outter() {
         
    }
     
    static class Inner {
        public Inner() {
             
        }
    }
}

public class Test {
    public static void main(String[] args)  {
        Outter.Inner inner = new Outter.Inner();
    }
}

 

 

静态内部类,就是修饰为static的内部类。声明为static的内部类,不需要内部类对象和外部类对象之间的联系,就是说我们可以直接引用outer.inner,即不需要创建外部类,也不需要创建内部类。

静态内部类不能访问外部类的非静态成员变量和方法。

嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不能声明为private,一般声明为public,方便调用。

接口中可以存在静态内部类。(如果想要创建某些公共的代码。使得每个实现该接口的类可以共用)

 

声明内部类:OuterClassName.InnerClassName

创建内部类:OuterClassObject.new InnerClassName

创建内部类之前,必须是首先创建外部类对象。

 

匿名内部类

 

new Thread(new Runnable() {
    @Override
    public void run() {
    }
}).start();

 

 

这里创建了一个实现Runnable接口的匿名对象,并通过new表达式返回了一个被自动向上转型为对Runnable的引用。

匿名内部类是不能加访问修饰符的。

匿名内部类既可以扩展类,也可以实现接口,但是不能两者兼备。而且实现接口,也只能一次实现一个。

要注意的是,new 匿名类,这个类是要先定义的,看下面例子:

 

public class Outer { 
    public static void main(String[] args) { 
        Outer outer = new Outer(); 
        Inner inner = outer.getInner("Inner", "gz"); 
        System.out.println(inner.getName()); 
    } 
 
    public Inner getInner(final String name, String city) { 
        return new Inner() { 
            private String nameStr = name; 
 
            public String getName() { 
                return nameStr; 
            } 
        }; 
    } 
} 
interface Inner { 
    String getName(); 
}

 

 

同时在这个例子,留意外部类的方法的形参,当所在的方法的形参需要被内部类里面使用时,该形参必须为final。这里可以看到形参name已经定义为final了,而形参city 没有被使用则不用定义为final。

因为匿名内部类,没名字,是用默认的构造函数的,无参数的,那如果需要参数呢?则需要该类有带参数的构造函数:

public class Outer { 
    public static void main(String[] args) { 
        Outer outer = new Outer(); 
        Inner inner = outer.getInner("Inner", "gz"); 
        System.out.println(inner.getName()); 
    } 
 
    public Inner getInner(final String name, String city) { 
        return new Inner(name, city) { 
            private String nameStr = name; 
 
            public String getName() { 
                return nameStr; 
            } 
        }; 
    } 
} 
abstract class Inner { 
    Inner(String name, String city) { 
        System.out.println(city); 
    } 
    abstract String getName(); 
} 

 

注意这里的形参city,由于它没有被匿名内部类直接使用,而是被抽象类Inner的构造函数所使用,所以不必定义为final。

 

匿名内部类通过实例初始化,可以达到类似构造器的效果:

public class Outer { 
    public static void main(String[] args) { 
        Outer outer = new Outer(); 
        Inner inner = outer.getInner("Inner", "gz"); 
        System.out.println(inner.getName()); 
        System.out.println(inner.getProvince()); 
    } 
 
    public Inner getInner(final String name, final String city) { 
        return new Inner() { 
            private String nameStr = name; 
            private String province; 
 
            // 实例初始化 
            { 
                if (city.equals("gz")) { 
                    province = "gd"; 
                }else { 
                    province = ""; 
                } 
            } 
 
            public String getName() { 
                return nameStr; 
            } 
 
            public String getProvince() { 
                return province; 
            } 
        }; 
    } 
} 
interface Inner { 
    String getName(); 
    String getProvince(); 
} 

 

 

 

内部类继承

内部类的继承,是指内部类被继承,普通类 extents 内部类。而这时候代码上要有点特别处理,具体看以下例子:

public class InheritInner extends WithInner.Inner { 
 
    // InheritInner() 是不能通过编译的,一定要加上形参 
    InheritInner(WithInner wi) { 
        wi.super(); 
    } 
 
    public static void main(String[] args) { 
        WithInner wi = new WithInner(); 
        InheritInner obj = new InheritInner(wi); 
    } 
} 
 
class WithInner { 
    class Inner { 
 
    } 
} 

 

可以看到子类的构造函数里面要使用父类的外部类对象.super();而这个对象需要从外面创建并传给形参。否则,编译器会报错。

 

内部类覆盖

当类A继承了类B,并且声明了一个和B类中同名的内部类时,覆盖并没有发生,这两个内部类时完全独立的两个实体,各自在自己的命名空间内;

 

内部类的使用场景和好处

1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

 

2.内部类使得多继承的解决方案变得完整;而且可以让多个内部类以不同的方式实现同一个接口,或继承同一个类

 

3.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。

 

分享到:
评论

相关推荐

    java内部类详解共10页.pdf.zip

    本资料"java内部类详解共10页.pdf.zip"显然是一个详细探讨Java内部类的教程,包含10页内容。虽然无法在这里直接提供PDF的具体内容,但我们可以根据通常内部类的讲解内容进行详述。 1. **什么是内部类:** 内部类...

    Java内部类详解

    Java内部类详解 Java内部类是Java语言中的一种编程机制,它允许将一个类定义在另一个类的内部。内部类可以访问外部类的成员变量和成员方法,包括private的成员变量和成员方法。内部类也可以被外部类访问,但需要...

    Java内部类详解.pdf

    以下是对Java内部类的详细解释: 1. **定义**: 内部类(也称为嵌套类)是在另一个类的定义内声明的类。在给定的例子中,`Contents`是`First`类的内部类。在Java代码中,我们可以看到`Contents`被定义在`First`类...

    java内部类的讲解

    ### Java内部类详解 #### 一、内部类的分类与概念 Java的内部类机制是其强大特性之一,它允许类作为另一个类的成员存在,从而增强了代码的封装性和复用性。根据定义和作用域的不同,Java内部类主要分为四类: 1. ...

    JAVA 内部类详解及实例

    Java 内部类详解及实例 Java 内部类是一种特殊类型的类,它定义在一个类的内部。这种设计模式在 Java 中提供了许多便利,比如封装、抽象和代码复用。以下将详细介绍内部类的种类、特性以及如何使用它们。 1. 成员...

    Java语法总结 - 内部类

    Java内部类详解 Java内部类是Java语言中的一种特殊类别,它是指定义在另外一个类内部的类。内部类可以访问外部类的所有成员变量和方法,包括私有的变量和方法。内部类可以分为四种:成员内部类、静态嵌套类、方法...

    Java内部类总结

    ### Java内部类详解 #### 一、什么是内部类? 内部类,顾名思义,是在另一个类的内部定义的类。这种独特的结构让内部类能够访问包含它的外部类的私有成员,包括变量和方法。这为编程提供了一种封装更紧密、功能更...

    Java内部类.pdf

    ### Java内部类详解 #### 一、定义及意义 **定义**:内部类是指在一个类的内部定义的类。它可以存在于任何位置,如类、方法甚至是条件语句中。内部类同样可以继承其他类或者实现接口,这为设计更为灵活且紧密耦合...

    JAVA内部类

    ### JAVA内部类详解 #### 引言 自Java1.1版本起,内部类的引入为面向对象编程提供了更为灵活的封装机制。然而,如同所有强大的特性,内部类的不当使用可能导致代码复杂度的增加,甚至产生维护上的困难。本文旨在...

    Java内部类(innerclass).docx

    ### Java内部类详解 #### 一、嵌套类概述 在Java编程中,嵌套类是一种重要的面向对象设计工具,它允许程序员在一个类的内部定义另一个类。这种特性极大地增强了Java语言的灵活性和封装能力。 #### 二、嵌套类分类...

    Java内部类

    ### Java内部类详解 在Java编程语言中,内部类(Inner Class)是一种非常重要的概念,它使得类的设计更加灵活和高效。本文将详细介绍Java内部类的相关知识点,包括其定义、分类以及应用场景等。 #### 一、Java内部...

    java 内部类

    ### Java内部类详解 #### 一、Java内部类概述 在Java编程语言中,内部类是一种特殊的类形式,它被定义在另一个类的内部。Java内部类可以分为四种类型:成员内部类、局部内部类(方法内部类)、静态内部类(也称为...

    Java 内部类

    ### Java内部类详解 #### 一、内部类概述 内部类,顾名思义,是在另一个类的内部定义的类。这种独特的结构使得内部类能够访问外部类的私有成员,包括变量和方法,这在Java编程中提供了一种强大的封装机制。内部类...

    java内部类应用详解

    Java内部类是Java语言中一个独特且强大的特性,它允许我们在一个类的内部定义另一个类。内部类可以作为外部类的成员,具有访问外部类的所有域的权限,无论是public、protected还是private。这种访问能力使得内部类能...

    java 内部类的实例详解

    Java内部类是Java语言中一个独特且强大的特性,它允许在一个类的定义内定义另一个类。内部类可以分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。下面我们将深入探讨内部类的使用方法和优势。 首先...

Global site tag (gtag.js) - Google Analytics