其他分享
首页 > 其他分享> > 内部类

内部类

作者:互联网

内部类

什么是内部类?

类的五大成员之一:

属性、方法、构造方法、代码块、内部类

在一个类的里面,在定义一个类

举例:在A类的内部定义B类,B类就被称为内部类

为什么要学员内部类?

内部类表示的事物是外部类的一部分

内部类单独出现没有任何意义

内部类的访问特点:

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

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

public class Car {
   String carName;
   private int carAge;
   String carColor;
   public void show(Car this){
       System.out.println(this.carName);
//       System.out.println(this.engineName);//必须创建对象
       Engine e = new Engine();
       System.out.println(e.engineName);
  }
   class Engine{
       String engineName;
       int engineAge;
       public void show(){
           System.out.println(engineName);
           System.out.println(carName);
           System.out.println(carAge);
      }
  }
}

内部类的分类

成员内部类

写在成员位置的,属于外部类的成员

成员内部类可以被一些修饰符所修饰,如:private,默认,protected,public,static等

在成员内部类里面,JDK16之前不难定义静态变量,JDk16开始才可以定义静态变量

获取及创建成员内部类对象

方式一:在外部类中编写方法,对外提供内部类的对象

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

package com.he.innerclassdemo2;

public class Outer {
   String name;
   //可以被私有, 无法被外界调用
   //内部类只能在同包或其他包的子类使用
   private class Inner{
       static int a=10;
  }
   public Inner getInstance(){
       return new Inner();
  }
}
public class Test {
   public static void main(String[] args) {
       //因为name是一个成员变量,想要调用只能通过对象去调用
//       System.out.println(new Outer().name);
//       Outer.Inner oi = new Outer().new Inner();
       Outer o = new Outer();
//       Object inner = o.getInstance();
       System.out.println(o.getInstance());
  }
}

内部类的内存图

 

静态内部类

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

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

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

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

public class Outer {
//   int a = 10;
//   static int b = 20;
   static class Inner{
       public void show1(){
           System.out.println("非静态方法");
           //如果想要访问a,需要先创建对象
//           System.out.println(a);
//           Outer o = new Outer();
//           System.out.println(o.a);
//           System.out.println(b);
      }
       public static void show2(){
           System.out.println("静态方法");
//           System.out.println(a);
//           System.out.println(b);
      }
  }
}
public class Test {
   public static void main(String[] args) {
       Outer.Inner oi = new Outer.Inner();
       oi.show1();
       //静态方法
//       oi.show2();
       Outer.Inner.show2();
  }
}

局部内部类

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

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

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

public class Outer {
   int b = 20;
   public void show(){
       int a = 10;
       //局部内部类,和局部变量相似,可修饰局部变量的皆可以修饰局部内部类
       class Inner{
           String naem;
           public void method(){
               System.out.println("局部内部类中的method方法1");
               System.out.println(a);
               System.out.println(b);
          }
           public static void method2(){
               System.out.println("局部内部类中的method静态方法2");
          }
      }
       Inner i = new Inner();
       System.out.println(i.naem);
       i.method();
       Inner.method2();
  }
}
public class Test {
   public static void main(String[] args) {
       //无法直接使用show方法里面的局部变量a
       Outer o = new Outer();
       o.show();
  }
}

匿名内部类(重点掌握)

匿名内部类本质上就是隐藏了名字的内部类

格式:
new 类名或者接口名(){
重写方法;
};
public abstract class Animal {
   public abstract void eat();
}
public interface Swim {
   public abstract void swim();
}
public class Test {
   public static void main(String[] args) {
       //1.把前面的class删掉,剩余的内容就变成了一个没有名字的类
       //2.这个没有名字的类想要实现Swim接口
       //吧Swim写在大括号前面,表示这个没有名字的类实现了
       //Swim接口,所以需要在类中重写接口里面的所有的抽象方法
       //3.创建这个没有名字的对象
       new Swim(){//类的开始
           //匿名类为括号里面的内容
           //书写了一个没有名字的类去实现Swim,之后重写抽象的方法
           @Override
           public void swim() {
               System.out.println("重写游泳方法");
          }
      };//类的结束

       //和上面接口相似,不过关系为继承
//       new Animal(){
//           @Override
//           public void eat() {
//               System.out.println("重写eat的方法");
//           }
//       };
       //在测试类中调用下面的method方法
       method(
               new Animal() {
                   @Override
                   public void eat() {
                       System.out.println("狗吃骨头");
                  }
              }
      );
  }
   public static void method(Animal a){
       a.eat();
  }
}

额外的创建方法

public class Test2 {
  public static void main(String[] args) {
      //整体可以理解为Swim接口的实现类对象
      //接口的多态
      Swim s = new Swim() {
          @Override
          public void swim() {
              System.out.println("重写之后的游泳方法");
          }
      };
      s.swim();

      new Swim(){
          @Override
          public void swim() {
              System.out.println("重写之后的游泳方法");
          }
      }.swim();
  }
}

总结

1.什么是匿名内部类

隐藏了名字的内部类,可以写在成员位置,有可以写在局部位置

2.匿名内部类的格式

new 类名或者接口名(){
重写方法;
};

3.格式的细节

包含了继承或实现,方法重写,创建对象

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

4.使用场景

当方法的参数是接口或者类是,

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

如果实现类值要使用异常,就可以用匿名内部类简化代码

标签:内部,void,System,println,public,out
来源: https://www.cnblogs.com/kuangshihe/p/16512199.html