1.什么是内部私有类?

在一个java类里创建一个private的class;

2.内部私有类的功能:

在大部分的java编码中,我们的编码都是依赖于class的,但内部类可以实现无依赖类型编码;

对外部而言,可以完全隐藏实现的细节;

3.具体实现:

1)定义接口(为内部类方法的访问做准备):

package think.ten;


 public interface Contents {
 int getValue();
 void setValue(int i);
 }2)定义内部类
package think.ten.impl;


 public class par {
 private int i;


 public int getI() {
 return i;
 }
 public void setI(int i) {
 this.i = i;
 }
 public void pri(){
 System.out.println("I'm par!");
 }
 }package think.ten;


 import think.ten.impl.par;


 public class InnerClass {
 /**
 * 因为内部私有类只能被其外围类使用,所以其定义是不可以具体实现的,也就是不可以对外进行实例化,只能由其外部对象使用相应方法进行完成
 * 但为了能够使用内部实现的具体方法,可以使用接口嫁接模式,用一个公共接口来作为返回对象,调用其方法,
 * 也可以使用继承某个类,或者抽象类来实现。总之就是为了能使内部类的外围类对象在实例化完内部私有类之后有个接受的调用容器;
 * @author Administrator
 *使用内部类可以完全组织任何依赖于类型的编码,并且达到完全隐藏实现细节的功能
 *
 */
 private class PCotents extends par implements Contents{
 private int i=0;
 @Override
 public void setValue(int i){ this.i=i;}
 @Override
 public int getValue() {
 return i;
 }
 }
 public Contents getPc(){
 return new PCotents();
 }
 public par getPc1(){
 return new PCotents();
 }
 }

上述代码中的继承par说是作为一个调用容器,但一般需要经过方法的Override来实现,使用抽象类继承是一种更好的方案。

3)方法调用展示:

package think.ten.impl;


import think.ten.Contents;
import think.ten.InnerClass;


public class shixian {
public static void main(String[] args){
InnerClass in =new InnerClass();
Contents s=in.getPc();
par p=in.getPc1();
s.setValue(2);
System.out.println(s.getValue());
System.out.println(p.getI());
p.pri();
}
}

通过本节学习,和IOC中实现依赖与抽象作比较发现,内部类方法的调用也是通过抽象调用来进行的。只是将类的实例化交由内部类来实现。

内部类的优点:

1.封装性强,可以不让外界知道其名字;

2.可以使用外部类的变量;outClass.this 用来屏蔽内部类和外部相同的变量名

3.内部类可以是静态的,但非静态内部类中不可以有静态变量和静态方法

4.内部类是局部的,它可以定义在一个方法或者一段代码块内;

5.匿名内部类的使用:

public content1 getContent(){
return new content1(){
private int i=0;
public int getValue(){
return this.i;
}
}
}

6.java内部类加上接口可以实现多重继承;示例代码:

package com.learn.unit;


 public class InnerClass {
 public static void main(String[] args){
 InnerTest tmp=new InnerTest(14,"杨铁心");
 //tmp.getInner().getTotalAge();//类方法的调用是依赖于对象
 TotalAge tmp2=tmp.getInner();//接口接受返回方法
 tmp2.getTotalAge();
 tmp2.printAge();
 }
 }


 class InnerTest extends Parent1 {
 InnerTest(int age,String name){
 super(age,name);
 }
 private class MyInner extends Parent2 implements TotalAge{
 MyInner(int age,String name){
 super(age,name);
 }
 @Override
 public int getTotalAge() {
 // TODO Auto-generated method stub
 return super.getAge2()+getAge1();
 }


 @Override
 public void printAge() {
 // TODO Auto-generated method stub
 System.out.println("age1:"+getAge1()+"    age2:"+super.getAge2());
 }

 }

 public MyInner getInner(){
 return new MyInner(13, "欧阳锋");
 }
 }
 interface TotalAge{
 int getTotalAge();
 void printAge();
 }
 class Parent1{
 private int age1;
 private String name1;
 Parent1(int age1,String name1){
 this.age1=age1;
 this.name1=name1;
 };
 public int getAge1() {
 return age1;
 }
 public void setAge1(int age1) {
 this.age1 = age1;
 }
 public String getName1() {
 return name1;
 }
 public void setName1(String name1) {
 this.name1 = name1;
 }
 }


 class Parent2{
 private int age2;
 private String name2;
 Parent2(int age2,String name2){
 this.age2=age2;
 this.name2=name2;
 }
 public int getAge2() {
 return age2;
 }
 public void setAge2(int age2) {
 this.age2 = age2;
 }
 public String getName2() {
 return name2;
 }
 public void setName2(String name2) {
 this.name2 = name2;
 }

 }package inner_double_extends;


 public class InnerDoubleExtends {
 public static void main(String[] args){
 c c=new c();
 c.satAll();
 }
 }
 /**
  * 内部类实现双重继承
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>Company: </p> 
 * @author 
 * @date
  */
 class a{
 public void sayA(){
 System.out.println("I'm a!");
 }
 }


 class b{
 public void sayB(){
 System.out.println("I'm b!");
 }
 }


 class c extends a{
 private class inner extends b{
 public void tt(){
 sayA();
 super.sayB();
 }
 };
 public  void  sayA(){
 super.sayA();
 }
 public void satAll(){
 new inner().tt();
 }
 }

综上所述,内部类本身是在外部类需要操作一个外部特别复杂的属性,该属性设计的范围特别广,则可以考虑使用内部类来解决这个问题,从而实现对外隐藏实现过程;

内部静态类与内部非静态类的区别:

在此之前 先说说静态类的本质,

如果是一个类里面的静态成员变量和静态成员方法,它是存储在方法区的,静态成员变量是在方法区的静态域里面,而静态成员方法是在方法区的class二进制信息里面(.class文件和方法区里面的二进制信息不一样,读取.class文件按照虚拟机需要的格式存储在方法区。这种格式包括数据结构方面),静态成员和静态成员方法使用时不用创建对象,即类加载初始化后就可以使用,并且是线程共享的。

方法区是线程安全的。由于所有的线程都共享方法区,所以,方法区里的数据访问必须被设计成线程安全的。例如,假如同时有两个线程都企图访问方法区中的同一个类,而这个类还没有被装入JVM,那么只允许一个线程去装载它,而其它线程必须等待 !

静态类位于方法区,并且静态方法不能调用非静态方法,所以在内部静态类中,则不能使用外部类相关的非静态成员变量及方法;并且内部静态类的实例化也不依赖于外部类,因为其本身已经在方法区实例化了;

内部静态类:


package com.jdd.learn.innerClass;

public class StaticInnerClass {
    private String name;

    public static class Inner1{
        public void print(){
            System.out.println("I’m static inner class");
        }
    }
}


内部静态类的使用


@Test
void testStaticInnerClass(){
    StaticInnerClass.Inner1 temp=new StaticInnerClass.Inner1();
    temp.print();
}


由此可见,内部静态类的实例化不依赖于外部类,而且在使用上,也不能共享外部类的成员变量及方法,本质上就是一个内部类;优点是在内部类与外部无任何关联的情况下,使用可以少创建很多的内部实例,节省内存空间。并且内部静态类的成员变量是线程安全的。

代码如下所示


package com.jdd.learn.innerClass;

public class StaticInnerClass {
    private String name;

    public static class Inner1{
        private static Integer  seq=0;
        public void print(){
            System.out.println("I’m static inner class");
        }
        public void seq(){
            seq++;
        }
    }

    public void say(){
        new StaticInnerClass.Inner1().seq();
    }

    public void getSeq(){
        System.out.println(new Inner1().seq);
    }
}


调用:


@Test
void testStaticInnerClass(){
    StaticInnerClass.Inner1 temp=new StaticInnerClass.Inner1();
    temp.print();
    StaticInnerClass staticInnerClass = new StaticInnerClass();
    staticInnerClass.say();
    staticInnerClass.getSeq();
    StaticInnerClass staticInnerClass2 = new StaticInnerClass();
    staticInnerClass2.say();
    staticInnerClass2.getSeq();
    StaticInnerClass staticInnerClass3 = new StaticInnerClass();
    staticInnerClass3.say();
    staticInnerClass3.getSeq();
    StaticInnerClass staticInnerClass4 = new StaticInnerClass();
    staticInnerClass4.say();
    staticInnerClass4.getSeq();
    StaticInnerClass staticInnerClass5 = new StaticInnerClass();
    staticInnerClass5.say();
    staticInnerClass5.getSeq();
}


输出:

I’m static inner class
1
2
3
4
5

内部静态类又称嵌套类,因为他不能访问外部的非静态方法及成员变量,所以只是一个嵌套关系,在实例化时,不需要依赖外部的对象;而内部类可以访问外部的方法及成员变量,实例化需要依赖外部对象;