Java【内部类】

内部类:

将一个类定义在另一个类的内部,内部的类称为内部类;

如:

public class A{
    public class B{
        //省略
    }
}

 

特点:

  1. 内部类可以很好的实现隐藏,可以使用protect、private修饰。
  2. 内部类可以访问外部类的所有成员,包括私有成员。
  3. 外部类不能直接访问内部类的成员,必须要建立内部类的对象才可访问。
  4. 内部类可以解决一些问题,比如间接的去实现多继承。可以避免修改接口而实现同一个类中两个同名的方法调用。

成员内部类

特点:

  1. 成员内部类属于外部类的实例成员,成员内部类可以有public、private、default、protect权限修饰符。在成员内部类中访问外部类的方法和属性,要用"外部类名.this.成员方法""外部类名.this.成员属性"的形式。
  2. 创建成员内部类的实例使用"外部类名.内部类名  实例名 = 外部类实例名.new 内部类构造方法(参数)"的形式

限制:

  1. 成员内部类不能与外部类重名;
  2. 不能再内部类定义static属性、方法 和类(static fianl形式的常量定义除外)。因为一个成员内部类必定与一个成员外部类实例关联,static成员完全可以移除到外部类去;
class Main{
    public static void mian(String [] args){
        //创建外部类对象
        Outer outer = new Outer();
        //创建内部类对象
        Outer.Inner inner = outer.new Inner();
        inner.innerShow();
    }

}

class Outer{
    private String name = "李四";
    private int age = 10;

    public void outerShow(){
        System.out.printf(name );
        System.out.printf(age );
        //   System.out.printf(hiegt); 外部类不能直接访问内部类属性
    }
    
    class Inner{
       
        private String name = "张三";
        private int hiegt =55;

        public void innerShow(){
            System.out.printf(name);
            System.out.printf(Outer.this.name);    //内部类访问外部类属性
            outerShow();    //内部类可以直接访问外部类方法
            System.out.printf(hiegt);
        }

    }
}

静态内部类

特点:

  1. 使用static修饰的成员内部类叫静态内部类;
  2. 静态内部类跟外部类无任何关系,只是在生成类名和类定义时有影响。静态内部类可以看作与外部类平级的类。使用方法与外部类完全相同。
  3. 创建静态内部类的实例使用 外部类名.内部类名 实例名 = new 外部类名.内部类名(参数)

限制:

  1. 静态内部类不能与外部类重名;
  2. 静态内部类不能访问外部类的非静态的属性和方法。外部类不能访问内部类的非静态的属性和方法;
class Main{
    public static void mian(String [] args){
        
        //创建一个静态内部类对象
        Outer.Inner inner = new outer.Inner();
        inner.innerShow();
    }

}

class Outer{
    private String name = "李四";
    private int age = 10;
    private static int weight = 10;
    public void outerShow(){
        System.out.printf(name );
        System.out.printf(age );
       
    }
    
    public static class Inner{
       
        private String name = "张三";
        private int hiegt =55;

        public void innerShow(){
            System.out.printf(name);
            //  System.out.printf(Outer.this.name);    静态内部类不能访问外部类非静态成员
            System.out.printf(Outer.weight);
 
        }

    }
}

 

匿名内部类

特点:

  1. 匿名内部类是没有名称的内部类,没办法引用它们。必须在创建时,作为new语句的一部风来说声明并创建它们的实例
  2. 匿名内部类必须继承一个个类(抽象、非抽象的)或实现一个接口。如果父类是抽象类,则内部类必须实现其所有抽象方法
  3. 匿名内部类可以定义代码块,用与实例的初始化,但不能定义静态代码块

语法:

new interfance/superclass(){ // 类体 }

这种形式的new语句声明一个新的匿名类,它对一个给定的类进行拓展,或者实现一个给定的接口,并同时创建该匿名类的新实例。

public class Mian{
    public static void main(String [] args){
        A a = new A();
       // B c = new C();
       // a.feed(c);
      //匿名内部类写法
      a.feed(new B(){
        public void eat(){
            System.out.printf("吃东西");
         }
      });
    }
}
class A{
    public void feed(B b){
        b.eat();
    }
}

class B{
    public abstract void eat();
}
/*
class C extends B{
     public void eat(){
        System.out.printf("吃东西");
     }
}*/

局部内部类

特点:

  1. 定义在代码块、方法体内的类叫局部类
  2. 局部内部类访问外部类的属性、方法使用“外部类名.this.属性名” 和“外部类名.this.方法名(参数)
  3. 对外部世界完全隐藏,只能在其作用域内生成对象

限制:

  1. 局部内部类不能加访问修饰符,因为他们不是类成员。
  2. 局部内部类不能与外部类重名
  3. 局部内部类访问的作用域的局部变量,该局部变量需要用final修饰
 class Main{
    public static void main(String [] args){
        Outer  outer = new Outer();
        outer.showOuter();
    }
}

class Outer{
    private String name = "张三";
    Private int num =10;
    private static int num1 =19;
    public void showOuter(){
        fianl int num3 = 50;
        //局部内部类不能加访问修饰词
        class Inner{
             private int name4 = 60;
             Private int num =130;
                public void showInner(){
                    System.out.printf(num4);
                    System.out.printf(Outer.num1);    //访问外部类静态属性
                    System.out.printf(Outer.this.num);    //访问外部类属性
                     System.out.printf(num3 );    //局部内部类只能访问声明其方法中的常量
                }
        }
        Inner inner = new Inner();
        inner.showInner();
    }

}

 

使用内部类开发一个存放数据的容器:

public class Main{

  public static void main(String [] args){
      MyContainer myContainer  new MyContainer ();
      myContainer.put("wsd","kl");
      myContainer.put("wsdsd","uyrt");
      myContainer.put("wsfwewed","ytn");
      myContainer.put("wstrwyed","4v");
       myContainer.put("wcssd","ggkl");
    
      MyContainer.Entry [] entrys = myContainer.entryArrays();
      for(int i=0;i<entrys.length;i++){
          MyContainer.Entry  entry =entrys[i];
          System.out.printf(entry.getKey() +"---"+entry.getValue());
      } 
    }
}

class MyContainer{
    priavte Entey [] enteys = new Entey [5];
    private int count =0;
    //对外提供一个接口向容器中存放封装好的数据(Entey 对象)
    public void put (String key,String value){
        Entey entey = new Entey();
        entey.setKey(key); 
        entey.setValue(value); 
        enteys[count++] = entey;
        //数组的扩容
        if(enteys.length <= count){
            int newCapactiy =entrys.length*2;
            //把老数组中的数据拷贝到新数组中去
            entrys = Array.copyOf(entrys,newCapactiy );
        }
    }
    
    //把容器中有数据的内容返回
    public Entery[] entryArrays(){
        return Arrays.copyOfRange(entrys,0,count);
    }

    //把键值封装在Entey 对象中
    public static Class Entry{
          private String key;
          private String value;
          public void setKey(String key){
                this.key = key;
          }
          
          public void getKey(String key){
                return key;
         }
        
         public void setValue(String value){
                this.value= value;
          }
          
          public void getValue(String value){
                return value;
         }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值