Java中内部类(成员内部类、静态内部类、局部内部类、匿名内部类)

什么是内部类?我们知道当我们去描述一个汽车时,我们会定义车的名字,车的年限,车的颜色,车的发动机年限,车的发动机的年龄。

public class Car{
    String carName;
    int carAge;
    String carColor;
    String engineName;
    int engineAge;
}

但是我们发动机的年限和发动机的年限不属于车的属性,且单独存在没有意义。

这时,我们就可以用到内部类(内部类表示的事物是外部类的一部分,内部类单独出现没有任何意义)

public class Car{
   String carName;
   int carAge;
   String carColor;

   class Engine{                           //成员内部类,与上面的成员变量地位一样
      String engineName;
      int engineAge;
   }
}

内部类的访问特点:

                         ①内部类可以直接访问外部类的成员,包括私有

                         ②外部类要访问内部类的成员,必须创建对象

内部类分为:①成员内部类

                      ②静态内部类

                      ③局部内部类

                      ④匿名内部类

①成员内部类:上面书写的第二张图片就是成员内部类的书写,成员内部类的地位和成员变量是一样的,所以它也同样能被public、protected、默认、private、static修饰,在JDK16之后,成员内部类中变量也可以被private修饰。

那么如何获取成员内部类对象?

1.在外部类中编写方法,对外提供内部类的对象(当内部类用private修饰时一般用这个)

2.直接创建格式:外部类名.内部类名  对象名=外部类对象.内部类对象;

public class Outer{
    String name;
    

    private class Inner{
        
    }

    public Inner getInstance(){              //在外部类中编写方法,对外提供内部类对象
        return new Inner();
    }
}






public class Test{
    public static void main(String[] args){   //通过Outer类调用getInstance方法返回内部类的对象
        Outer o=new Outer();
        Object Inner=o.getInstance();         //因为Inner类没有手动添加继承,可以利用多态用
        System.out.println(o.getInstance());  //最大的类Object接收      
    }                                         
}
public class Outer{
    private String name;
    
    class Inner{
       
    }
}






public class Test{
    public static void main(String[] args){
        Outer.Inner oi=new Outer().new Inner();  //由于测试类无法直接获取成员内部类的对象,需要                                              
    }                                            //通过先创建外部类对象再通过访问内部类成员来 
}                                                //创建,因为成员方法的地位和成员内部类的地位 
                                                 //是一样的 
                                                                                          

那我们如何在内部类中获得外部类中的变量呢?

public class Outer{
    private int a=10;

    class Inner{
       private int a=20;

       public void show(){
           int a=30;
           System.out.println(a);             //30
           System.out.println(this.a);        //20
           System.out.println(Outer.this.a);  //10
       }
    }
}

②静态内部类:被static修饰的内部类(静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象)

注意事项:1.静态内部类也是成员内部类中的一种

                  2.静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建外部类的对象

  

创建静态内部类对象的格式:外部类名.内部类名  对象名=new 外部类名.内部类名();

使用非静态方法的格式:先创建对象,用对象调用

调用静态方法的格式:外部类名.内部类名.方法名();

public class Car{                             //外部类
    String carName;
    int carAge;
    String carColor;

    static class Engine{                      //静态内部类
        String engineName;
        int engineAge;
    }
}



public class Test{
    public static void main(String[] args){            //静态的成员可以直接由类名调用
        Car.Engine ce=new Car.Engine();
    }
}

③局部内部类:1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量

                         2.外界是无法直接使用局部内部类,需要在方法内部创建对象并使用

                         3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量

④匿名内部类:隐藏了名字的内部类,可以写在成员位置,也可以写在局部位置

格式:        new 类名或者接口名(){

                               重写方法:

                   };

格式的细节:包含了继承或实现,方法重写,创建对象。

                     整体就是一个类的子类对象或者接口的实现类对象

使用场景:当方法的参数是接口或者类时,

                 以接口为例,可以传递这个接口的实现类对象,

                 如果实现类只要使用一次,就可以用匿名内部类简化代码。

public class Test{
    public static void main(String[] args){
        new Swim(){
            @Override
            public void swim(){
                System.out.println("重写了游泳的方法");
            }
        };

         
        new Animal(){                 //利用匿名内部类继承了抽象类,所以要重写抽象类里所有的
            @Override                 //抽象方法,匿名内部类的整体是一个对象
            public void eat(){
                System.out.println("重写了eat方法");
            }
        };
        method(
                new Animal(){         //创建一个继承于Animal的子类作为参数传给Animal父类
                    @Override
                    public void eat(){
                        System.out.println("狗吃骨头");  
                    }
                }
 
        );
    }
}

public static void method(Animal a){   //Animal a=子类对象,利用了多态          
    a.eat();
}




public abstract class Swim{
    public abstract void swim();
}

public abstract class Animal{
    public abstract void eat();
}
public class Test{
    public static void main(String[] args){
        
        //实现了接口的多态,因为s相当于通过Swim父类创建的对象,而右边相当于用匿名内部类创建的Swim 
        //的子类对象,也就相当于        父类类型 对象名称=new 子类对象;
        Swim s=new Swim(){                  
                   @Override
                   public void swim(){
                       System.out.println("重写之后的方法");
                   }
               };

        s.swim();                       //利用多态调用成员方法,遵守编译看左边,运行看右边
        
   
        new Swim(){
            @Override
            public void swim(){
                System.out.println("重写之后的方法");
            }.swim();                                //匿名内部类的整体是一个对象
        }
    }
}










public abstract class Swim(){
    public abstract void swim("重写之前的游泳方法");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值